https://wiki.archlinux.org/api.php?action=feedcontributions&user=HelloCode&feedformat=atomArchWiki - User contributions [en]2024-03-29T01:55:20ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Emacs_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=355576Emacs (简体中文)2015-01-06T10:02:30Z<p>HelloCode: /* Loading extensions */</p>
<hr />
<div>[[Category:Text editors (简体中文)]]<br />
[[de:Emacs]]<br />
[[en:Emacs]]<br />
[[fr:Emacs]]<br />
[[ja:Emacs]]<br />
[[sr:Emacs]]<br />
{{TranslationStatus (简体中文)|Emacs|2014-12-08|229169}}<br />
{{Translateme (简体中文)}}<br />
[[Wikipedia:Emacs|Emacs]]是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在[[Wikipedia:Emacs Lisp|Emacs Lisp]]解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和[[vim]]比较。<br />
<br />
{{Note|入门建议直接使用starterkit扩展。本文档实际帮助不大}}<br />
<br />
== 安装 ==<br />
Emacs有众多变体发行版本(有时候称作''emacsen''). 最常见的莫过于 [http://www.gnu.org/software/emacs/ GNU Emacs],在[[Official repositories]]可以找到<br />
<br />
$ pacman -S emacs<br />
<br />
如果你总是在终端下工作的话,你可能会选择{{Pkg|emacs-nox}}。这是一个没有GTK+依赖的版本(也没有声音支持)。<br />
<br />
终端版Emacs存在以下问题:它支持更少的颜色和更少的字体控制功能(缺少在线控制字体大小、在一篇文档中使用多种字体等功能)。而且对于一些需要高级特性的功能比如Speedbar或者GUD(调试环境),它也不支持。另外在控制复杂的外观(face)时,emacs-nox比Emacs要慢。<br />
<br />
如果你想体验Emacs的所有扩展功能而不用装一堆依赖的话,你可以使用PKGBUILD来按你的需求定制Emacs。不使用{{ic|gtk3}}可以让Emacs避免使用gconf。图像和声音的支持也可以去除。在Emacs的源代码目录下运行{{ic|./configure --help}}可以看看有哪些配置选项。<br />
{{hc|PKGBUILD|<nowiki><br />
# ...<br />
./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \<br />
--localstatedir=/var --with-x-toolkit=gtk2 --with-xft \<br />
--without-gconf --without-sound<br />
# ...<br />
</nowiki>}}<br />
<br />
另外一个常见的变体就是{{Pkg|xemacs}}.<br />
<br />
== 快速入门 ==<br />
一般印象是Emacs十分复杂,学习曲线陡峭,但很多资深学习者并不这样认为,反而认为其非常易懂和可定制。因为其源码和配置文件语义化程度较高。简单了解下自定义和高扩展带来的好处花不了多少时间。何况还有很多成熟的功能拓展模块,很方便添加,可以让Emacs为任何文本编辑的需求配置强大的环境。<br />
<br />
Emacs自带一个入门教程,你可以点击欢迎界面上的第一个链接来打开它; 或者从菜单栏中选择''Help->Emacs Tutorial'',或者按'F1'键然后按't'. 我们设计这篇文章来为你在Emacs入门学习中提供额外的资源。<br />
<br />
Emacs也包括一系列引用链接,既有适合初学者的内容,也有骨灰级玩家所喜爱的.参见{{ic|/usr/share/emacs/<version>/etc/refcards/}} (将<version>换成你的emacs版本).<br />
<br />
===运行Emacs===<br />
<br />
在启动Emacs之前,你要先学会怎么关闭它(尤其是你要在终端里运行它的话):用{{ic|Ctrl+x}}{{ic|Ctrl+c}}来关闭它。<br />
<br />
====图形界面下打开方式====<br />
图形界面下可以直接点击图标打开。<br />
<br />
====虚拟终端下的常见方式====<br />
打开Emacs:<br />
<br />
$ emacs<br />
<br />
不打开图形界面,直接在终端中运行:<br />
<br />
$ emacs -nw<br />
<br />
也可以直接用下面的命令来打开一个文件:<br />
<br />
$ emacs filename.txt<br />
<br />
=====去掉颜色=====<br />
默认的emacs会带有颜色主题,如果不需要,可以关闭之:<br />
<br />
$ emacs -nw --color=no<br />
<br />
<br />
====作为守护进程====<br />
Emacs由于每次启动都需要加载大量自定义的配置文件,所以打开时候会有点慢。从Emacs23开始, Emacs可以以守护进程的形式运行,这样每个用户都可以链接到Emacs。以守护进程运行Emacs:<br />
<br />
$ emacs --daemon<br />
<br />
你可能在启动时打开一个守护进程,然后再将守护进程链接到窗口。另外,也可以将图形和终端客户端同时链接到守护进程上,这样启动图形界面速度就很快了。<br />
<br />
如果你仅仅想链接到守护进程,用下面的命令(注意,在桌面环境下这个命令会打开一个图形客户端,而在像tty这种命令行下,它会打开一个命令行版的emacs):<br />
<br />
$ emacsclient<br />
<br />
如果你想在桌面环境下打开一个命令行版的emacs,使用下面的命令:<br />
<br />
$ emacsclient -t<br />
<br />
另外,你可以在后面加上 {{ic|-a ""}} 参数.<br />
现在,你第一次使用这个命令时,它会把emacs作为守护进程来启动,它会留在后台以加快以后的启动速度(也会记住缓冲区).<br />
<br />
更聪明点,你可以在.bashrc中加上下面的别名:<br />
{{bc|1=<br />
alias em='emacsclient -t -a ""' #在终端中开启emacs<br />
alias emc='emacsclient -nc -a ""' #启动emacs图形界面<br />
EDITOR='emacsclient -a ""'<br />
}}<br />
<br />
在[[xfce]]桌面环境中,如果你想使用 emacsclient -c 来代替 emacs %f 打开一个新文件, 你可以修改你的 /usr/share/applications/emacs.desktop 文件,把下面这一行<br />
<br />
$ Exec=emacs %f<br />
<br />
修改为<br />
<br />
$ Exec=emacsclient -c<br />
<br />
使用这种方法,每次你打开一个文件时就只会启动客户端,因此速度非常快!<br />
<br />
===基本术语和约定===<br />
Emacs使用一些刚开始看起来很奇怪的术语和约定,我们会在合适的时候介绍。但是,对于部分术语,我们必须要在前面介绍,因为它们对于使用Emacs来说是非常基础的。<br />
<br />
第一个要介绍的术语是''缓冲区''的概念。一个缓冲区就是Emacs中的数据的一种表示方式,比如,当使用Emacs打开一个文件时,这个文件从磁盘中被读出来,它的内容被存储在了缓冲区里面,它的内容可以在这个缓冲区里面被编辑并且可以重新写进磁盘中。缓冲区中的内容不仅仅可以是文本,也可以是图片和widget。现在,让缓冲区可以显示应用程序的工作正在进行!换个角度思考,在磁盘中数据是以文件形式保存的,而在Emacs中,数据是以缓冲区的形式存在的。<br />
<br />
在Emacs中,对于按键组合的约定你可能很陌生。比如:<br />
<br />
'''C-x''' 代表 Ctrl-x<br />
<br />
'''M-x''' 代表 Meta-x<br />
<br />
{{注意|'Meta'一般代表Alt键,也可以用Esc键替代。}}<br />
<br />
举个例子,退出Emacs使用下面的按键组合'''C-x C-c'''。这个可以读做,"按住Ctrl键再按'x',释放,再按住Ctrl键再按'c'。虽然Emacs提供了一个菜单栏,但是强烈建议学习使用按键组合。这个指南将参考Emacs的按键绑定的约定。<br />
<br />
===移动===<br />
光标移动和其它图形编辑器非常类似,鼠标和方向键可以用来改变光标(在Emacs中称为''点'')的位置。在Emacs中,方向键代表的标准移动命令也有其它辅助的绑定。向前(forward)移动一个字符,使用 '''C-f''',向后(back)移动一个字符,使用'''C-b'''。 '''C-n''' 和 '''C-p''' 分别用于移动到下(next)一行和移动到上(previous)一行。再声明一下,强烈推荐使用组合键而不是使用方向键和鼠标。<br />
<br />
可以想像,Emacs提供了更多的光标高级移动命令,包括移动一个单词和一个句子。 '''M-f''' 表示光标向前移动一个单词, '''M-b''' 表示向后移动一个单词。类似地,'''M-e''' 把光标移动到一个句子的末尾(end), '''M-a''' 移动到句子的开头。<br />
<br />
直到现在,所有的移动命令都是和光标有关的。'''M-<''' 表示把光标移动到缓冲区的开头,和它相反的是 '''M->''', 把光标移动到缓冲区的末尾。要把光标移动到某一特定行,使用'''M-g g'''. '''M-g g''' 会提示输入行号。同样,要移动到一行的开头或者结尾,分别使用'''C-a''' 和 '''C-e'''。<br />
<br />
{{Note|这些命令(实际上是全部命令)的绑定,在不同的模式(mode)中,''稍微''会有不同。然而,覆盖的命令提供不同的功能这种情况很少见。更多信息请看[[Emacs#Modes|Modes]]。}}<br />
<br />
===文件和缓冲区===<br />
Emacs 提供了一系列命令来对文件操作,其中最常用的会在这里详细说明。'''C-x C-f''' 用来打开一个文件(在Emacs中叫做'查找文件')。如果指定的文件不存在,Emacs会打开一个空的缓冲区。保存一个缓冲区会创建一个包含缓冲区内容的文件。'''C-x C-s''' 就是用来保存缓冲区的。要保存一个文件名不一样的缓冲区,使用'''C-x C-w''' (这其实是'write-file'这条命令的助记符), 它会在写入磁盘之前提示输入新文件名。也可以使用'''C-x s'''来保存所有的缓冲区, 如果某个缓冲区在上次保存之后被修改了,则会提示进行哪项操作。<br />
<br />
{{Note|如果指向某个文件的缓冲区还在打开的话,'''C-x C-f''' 是不会重新从磁盘中读取文件的。要从磁盘中重新读取文件,先使用'''C-x k'''关掉缓冲区,再使用'''C-x C-f'''打开文件,或者使用'''M-x revert-buffer'''.}}<br />
<br />
很多互动的命令,比如"find-file" 或者 "write-file" 会在Emacs窗口的底部栏提示输入。这栏称为''minibuffer''。和很多*nix shell一样,minibuffer支持很多基本的操作和TAB补全。按两下'''<TAB>'''可以显示一个补全的选项列表,并且,如果你喜欢,可以用鼠标从列表中选择。minibuffer的补全在很多输入(包括命令和文件名)中都可以用。<br />
<br />
minibuffer也提供一个记住历史的特性。通过'''Up Arrow''' 或者 '''C-p'''可以取得这条命令的上一个条目.<br />
<br />
要在任意时刻退出minibuffer,使用'''C-g'''.<br />
<br />
打开几个文件后,切换缓冲区是非常必要的。打开一个指向那个缓冲区的文件可以切换到那个缓冲区。但是这不是最高效的方法。Emacs提供'''C-x b'''来提示要显示的新缓冲区(这里可以使用TAB补全)。输入一个不存在的缓冲区,则会新建一个空的缓冲区。<br />
<br />
{{Note|要切换到上一个缓冲区,使用'''C-x b <RET>''', 因为上一个缓冲区是默认的缓冲区。}}<br />
<br />
使用'''C-x C-b'''可以显示所有打开缓冲区的列表。如果某个缓冲区不需要使用了,使用'''C-x k'''来关掉它。<br />
<br />
===编辑===<br />
Emacs 内建有很多编辑命令。可能最重要的还没有介绍的是'undo',它的快捷键为 ''C-_'' 或者 ''C-/'' .移动光标的命令通常都有对应的删除字符的命令。例如, '''M-<backspace>''' 可以用来删除一个光标后的词,'''M-d'''可以用来删除光标前面的一个词。删除光标至行尾或者句尾的字符可以分别用'''C-k''' 或者 '''M-k'''。<br />
<br />
通常我们都约定一行不能超过80个字符。这是为了代码的可读性,尤其是一行中的字符可能会接触到窗口边缘。在Emacs,自动地插入或者删除换行符称为''filling''。我们可以用 '''M-q''' 重整当前的段落(重新分配换行符,删除段落中多余的空格和tab键)<br />
<br />
字符和单词可以分别通过 '''C-t''' 和 '''M-t''' 进行交换。比如: <code>Hello World!</code> → <code>World! Hello</code><br />
<br />
单词的大小写也可以调整。'''M-l''' 把光标处的单词变成小写 (<code>HELLO</code> → <code>hello</code>); '''M-u''' 把光标处的单词变成大写(<code>hello</code> → <code>HELLO</code>), '''M-c''' 把光标处的单词的第一个字母变成大写,并把后面的变成小写(<code>hElLo</code> → <code>Hello</code>).<br />
<br />
===移除,召回和区域===<br />
一个''区域''(region)是指在两个位置之间的一段字。其中一个位置被称为''标记''(mark),另一个是光标。'''C-<SPC>'''用来设置标记的位置,紧接着就可以通过移动光标来创造一个区域。在GNU Emacs 23.1及以后的版本中,这个区域默认是可见的。有许多命令是针对区域的,其中最常用的就是''kill''命令。<br />
<br />
在Emacs中,剪切和粘贴分别对应的命令叫做''kill''和''yank''。许多删除多个字符的命令(包括上面提到的'''C-k'''和'''M-d'''命令)实际上是把文字剪切下来,附加到一个叫''kill-ring''的地方。kill-ring 就是一个被删掉的文字的列表。在默认情况下,kill-ring会保存最多60次删除记录。连续的删除会连在一起。<br />
<br />
'''C-w''' 和 '''M-w''' 可以用来删除或复制一个区域。<br />
<br />
要想把删掉的文字插入进来(也就是'yanking'),可以用'''C-y'''命令。'''C-y''' 可以连续用好多次来重复插入。按刚刚所讲,之前删除的文字会排成一个列表,但是'''C-y'''只能获取列表中的第一个,也就是最后删掉的一个。再之前删掉的可以通过'''M-y'''来获取。它会把'''C-y'''刚刚插入的文字用再早删除的文字替换掉。'''M-y''' 必须紧跟着'''C-y'''命令执行,可以执行很多次以遍历kill-ring。<br />
<br />
===查找和替换===<br />
在文本编辑中进行字符串查找是很常见的任务。按'''C-s'''可以正向搜索,按'''C-r‘’‘则可以反向搜索。这些命令提示要搜索的字符串。搜索是增量的,你再次按键时会显示下一个匹配的位置,并且可以使用'''C-s’‘’向前或者使用'''C-r‘’‘向后。找到匹配结果之后,可以按下'''<RET>'''结束搜索。另外,如果你想回到发起搜索的位置,可以使用'''C-g'''。<br />
<br />
一旦搜索完成(不是由'''C-g'''之类的指令引起),当前搜索的字符串将会作为下一次搜索的默认参数。使用’‘’C-s C-s'''或者'''C-r C-r'''可以达到这样的效果。<br />
<br />
I-search 有一些有用的命令,使用'''M-e'''来编辑当且搜索区域,使用'''M-c'''来触发大小写敏感匹配。<br />
<br />
正则表达式搜索除了指令不同之外,其他方面和以上都相同。使用'''C-M-s'''或者'''C-M-r'''来使用正则表达式搜索。相应地,用'''C-s'''和'''C-r'''可以前后移动,和普通的搜索没什么两样。<br />
<br />
除了搜索之外,进行字符串替换也是有必要的。原始文本和替换文本都会有提示,替换的时候也会有提示。尽管有很多选项提供(按'''?'''可以了解完整的选项),最常用的还是'''y'''(进行替换),'''n'''(跳过),以及'''!'''(替换当前及之后所有匹配)。<br />
<br />
===缩进和前缀参数===<br />
Indentation is usually performed with either '''<TAB>''', to indent a single line, or with '''C-M-\''', to indent a region.<br />
<br />
Exactly how text is indented usually depends on the ''major-mode'' which is active. Major-modes often define indentation styles specialising in indenting a certain type of text. (See [[Emacs#Modes|Modes]] for more information.)<br />
<br />
In some cases, a suitable major-mode may not exist for a file type, in which case, manual indentation may be necessary. Create a region (see [[Emacs#Killing, yanking and regions|Killing, yanking and regions]]) then perform indentation with '''C-u <n> C-x <TAB>''' (where '<n>' is the number of columns which the text within the region should be indented). For example:<br />
<br />
Increase the region's indentation by four columns:<br />
<br />
C-u 4 C-x <TAB><br />
<br />
Decrease the region's indentation by two columns.<br />
<br />
C-u -2 C-x <TAB><br />
<br />
{{Note|The trick behind this is '''C-u''', which corresponds to the 'universal-argument' command. Providing a 'universal-argument' is a way to provide more information to a command (this information is referred to as a 'prefix argument'). In this case, we provided the amount of indentation desired to the command invoked by '''C-x <TAB>'''. Without providing an argument, '''C-x <TAB>''' will only increase indentation by 1 column.}}<br />
<br />
===窗口和外框架===<br />
Emacs的设计是可以同时方便地编辑多个文件。这是通过把Emacs的接口分成三个层次来实现的,即buffer(之前介绍过了),''window''和''frame''。<br />
<br />
''window'' 是显示buffer的一个viewport(社区)。一个window一次只能显示一个buffer。但是一个buffer可以在多个window中显示。在窗口下面有一个''mode-line'',它用于显示当前buffer的信息。<br />
<br />
''frame'' 是Emacs的一个"窗口"(这是标准的术语。比如,'窗口'是现代桌面的称谓),它包含了标题栏,菜单栏,还有一个或多个'window'(这是Emacs的术语,比如上面提到的'window')。<br />
<br />
从现在起,这些Emacs中存在的名词的定义就可以使用了。<br />
<br />
要把window水平分隔和垂直分隔,分别使用'''C-x 2'''和'''C-x 3'''。这种效果其实就是在当前frame中开户另外一个window。要在多个window中循环切换,使用'''C-x o'''。<br />
<br />
与分隔一个window相反的是删除window。要删掉当前window,使用'''C-x 0''',要删掉除了当前window之外的其它window,使用'''C-x 1'''。<br />
<br />
和window一样,创建和删除frame也是可以的。'''C-x 5 2'''会创建一个frame,'''C-x 5 0'''会删除当前的frame,'''C-x 5 1'''会删除除了当前frame之外的其它frame。<br />
<br />
{{注意|这些命令不影响buffer。比如删除一个window并不会删除在window中显示的buffer。}}<br />
<br />
===获得帮助===<br />
Emacs在设计的时候就自文档化了。比如,要查看一个命令的名字或者它的键的绑定,Emacs提供了很多帮助信息。下面是列出来的最有用的一些帮助命令:<br />
<br />
'''C-h t''' 启动Emacs官方教程<br />
<br />
'''C-h b''' 列出来所有的有效键绑定<br />
<br />
'''C-h k''' 查找一个键被绑定在了哪个命令上<br />
<br />
'''C-h w''' 查找一个命令被绑定在了哪些键上<br />
<br />
'''C-h a''' 查找一个匹配一段描述的命令<br />
<br />
'''C-h m''' 显示当前激活的所有模式的信息<br />
<br />
'''C-h f''' 显示给定函数的描述信息<br />
<br />
===模式===<br />
一个Emacs模式是用Emacs Lisp语言写的一个控制相关缓冲区行为的扩展。一般来说,它给编辑文本提供缩进,语法高亮和键绑定的功能。复杂的模式可以把Emacs变成一个完美的IDE (Integrated Development Environment). Emacs 一般会使用一个文件的扩展来确定应该加载那个模式。<br />
<br />
一些编写shell脚本比较有用的模式有sh-mode, line-number-mode 和 column-number-mode。它们可以并行地通过下面的方式激活:<br />
<br />
'''M-x sh-mode <RET>'''<br />
<br />
'''M-x column-number-mode <RET>'''<br />
<br />
line-number-mode 默认是激活的,它可以通过下面的命令来打开/关闭:<br />
<br />
'''M-x line-number-mode <RET>'''<br />
<br />
sh-mode 是一个 ''major-mode''. Major-modes 调整Emacs,并且经常提供了一些特定的命令来编辑某种类型的文本。一个缓冲区只能激活一种major-mode。除了支持语法高亮和缩进,sh-mode还定义了几条命令来帮助快速开发shell脚本。下面是其中的几条:<br />
<br />
'''C-c (''' 插入一个函数定义<br />
<br />
'''C-c C-f''' 插入一个for循环<br />
<br />
'''C-c TAB''' 插入一条if语句<br />
<br />
'''C-c C-w''' 插入一个while循环<br />
<br />
'''C-c C-l''' 插入一个从1到n的有下标的循环<br />
<br />
'line-number-mode' 和 'column-number-mode' 是 ''minor-modes''. Minor-modes 可以用来扩充major-mode的功能,多个minor-mode可以同时激活。<br />
<br />
==提示和技巧==<br />
前面的部分给出了基本编辑命令的概述,没有给出Emacs的一个指示。这个部分讲述一些高级的技巧和功能。<br />
<br />
===TRAMP===<br />
TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入一个文件名,输入特定的格式就可以使用TRAMPP。比如:<br />
<br />
在打开{{ic|/etc/hosts}}文件之前提示输入root的密码以获取root权限:<br />
<br />
C-x C-f /su::/etc/hosts<br />
<br />
要通过SSH使用'myuser'用户名登录'myhost'主机并打开文件{{ic|~/example.txt}}:<br />
<br />
C-x C-f /ssh:myuser@myhost:~/example.txt<br />
<br />
TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。<br />
<br />
===键盘宏和寄存器===<br />
这一部分会提供一个实用的指南来使用一些更强大的编辑特性。也就是“键盘宏”和“寄存器”。<br />
<br />
我们的目标是产生一个字符列表和它们在这个列表中对应的位置。虽然这可以通过手工格式化来完成,但是这样会很慢而且容易出错。如果我们采用一些Emacs更高级的编辑功能却可以起到四两拨千斤的功效。在介绍这个方法之前,需要先了解一些技术背后的细节。<br />
<br />
要介绍的第一个特性就是''寄存器''。寄存器的功能是用来保存和获取各种各样的数据。每个寄存器用一个字母来命名,这个字母就是用来调用这个寄存器的。<br />
<br />
另一个要介绍的就是''键盘宏''。一个键盘宏存储了一个命令序列以便以后可以重复使用。下面就一步一步地讲解这个方法。<br />
<br />
首先我们从一个包含如下字符的缓冲区开始:<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
通过`number-to-register' 命令 ('''C-x r n''')我们来准备一个寄存器,把数字'0'存储在寄存器'k'中:<br />
<br />
C-x r n k<br />
<br />
当光标在缓冲区开头的时候,开始录制键盘宏 ('''C-x (''') 然后开始对字符串进行格式化:<br />
<br />
C-x ( C-f M-4 .<br />
<br />
插入 ('''C-x r i''') 然后将寄存器'k'加1 ('''C-x r +''') 。开头的 ('''C-u''') 命令是用来在插入文字之后让光标移到插入的文字后面:<br />
<br />
C-u C-x r i k C-x r + k<br />
<br />
最后我们来插入一个回车来结束格式化。Emacs可以重复以上过程,从我们定义键盘宏的位置开始,直到最后一个字符。'''C-x e'''命令停止宏的录制并开始执行这段宏。开头的 '''M-0''' 命令是用来让宏在出错的时候停下来,这样在它走到这行的结尾就会停下来。<br />
<br />
<RET> M-0 C-x e<br />
<br />
下面是结果:<br />
<br />
A....0<br />
B....1<br />
C....2<br />
[...]<br />
x....49<br />
y....50<br />
z....51<br />
<br />
===正则表达式===<br />
From the Emacs Manual: "A regular expression, or ''regexp'' for short, is a pattern that denotes a (possibly infinite) set of strings." This section will not go into any detail regarding regular expressions themselves (as there is simply too much to cover). It will however provide a quick demonstration of their power. See [http://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html#Regular-Expressions Regular Expressions] section in the Emacs Manual for further reading.<br />
<br />
Given the same scenario presented above: A list of characters which are to be formatted to represent their respective position in the list. (see [[Emacs#Keyboard macros and registers|Keyboard macros and registers]]). Again, starting with a buffer containing.<br />
<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
At the beginning of the buffer, use '''C-M-%''' (if the key-sequence is difficult to perform, it may be more comfortable to use '''M-x query-replace-regexp'''). At the prompt:<br />
\(.\)<br />
which simply matches one character. Then, when prompted for the replacement:<br />
\1....\#^J<br />
{{Note|'^J' represents where a newline should be placed, it should not be entered into the prompt. The newline must instead be inserted literally using '''C-q C-j'''.}}<br />
The replacement expression reads: "Insert the matched text between the first set of parentheses (in this case, a single character), followed by 4 periods then insert an automatically incremented number followed by a newline.<br />
<br />
Finally, press '''!''' to apply this across the entire buffer. All of the formatting that was performed in the previous section was performed with a single regexp replacement.<br />
<br />
==定制==<br />
Emacs能通过~/.emacs或者'''M-x customize'''来定制。本段落将着眼于手动定制 ~/.emacs,并且提供了一些常用配置的样例。配置命令提供了一个适应的途径,通过它你能够渐渐熟悉Emacs。<br />
<br />
这里的所有例子都能在Emacs中奏效。比如,在Emacs中计算表达式:<br />
'''C-M-x''' 同时指到任何需要求值的地方。<br />
<br />
或者<br />
<br />
'''C-x C-e''' 指到最后的“)”。<br />
<br />
用'y'和'n'来代替频繁地输入'yes’和'no‘是一个好的方法:<br />
<br />
(defalias 'yes-or-no-p 'y-or-n-p)<br />
<br />
取消光标闪烁:<br />
<br />
(blink-cursor-mode -1)<br />
<br />
类似地,开启上一节提到的列号模式:<br />
<br />
(column-number-mode 1)<br />
<br />
它们两者之间的相似不是偶然:光标闪烁模式和列号模式都是'副参模式',按照规则,'副参模式’能通过正负值来设置。如果参数省略,'副参模式'将被开/关。<br />
<br />
这里有其他一些'副参模式'的例子,下面的参数将会关闭滚动栏、菜单栏、工具栏。<br />
(scroll-bar-mode -1)<br />
(menu-bar-mode -1)<br />
(tool-bar-mode -1)<br />
<br />
变量'auto-mode-alist'修改之后能够改变默认的“主参模式”。下面的例子把'.tut'和'.req'修改成了'.text-mode'。<br />
<br />
(setq auto-mode-alist<br />
(append<br />
'(("\\.tut$" . text-mode)<br />
("\\.req$" . text-mode))<br />
auto-mode-alist))<br />
<br />
Settings can also be applied on a per-mode basis. A common method for this is to add a function to a ''hook''. For example, to force indentation to use spaces instead of tabs, but only in text-mode:<br />
<br />
(add-hook 'text-mode-hook (lambda () (setq indent-tabs-mode nil)))<br />
<br />
Similarly, to only use spaces for indentation everywhere:<br />
<br />
(setq-default indent-tabs-mode nil)<br />
<br />
Keybindings can be adjusted in two ways. The first of which is 'define-key'. 'define-key' creates a keybinding for a command but only in one mode. The example below will make '''F8''' delete any whitespace from the end of each line of a 'text-mode' buffer:<br />
<br />
(define-key text-mode-map (kbd "<f8>") 'delete-trailing-whitespace)<br />
<br />
The other method is 'global-set-key'. This is used to bind a key to a command everywhere. To bind 'query-replace-regexp' ('''C-M-%''') to '<f7>'.<br />
<br />
(global-set-key (kbd "<f7>") 'query-replace-regexp)<br />
<br />
Binding a command to an alternate key does not replace any existing bindings. Which is to say, 'query-replace-regexp' would be bound to both '''F7''' and '''C-M-%''' after the above example.<br />
<br />
Almost anything within Emacs can be configured. Browsing through the [http://emacswiki.org/ Emacs Wiki] should give a solid place to start.<br />
<br />
<br />
=== 多种配置 ===<br />
<br />
你可以使用少量配置然后告诉Emacs来加载其他配置。<br />
<br />
例如,我们来定义两个配置文件。<br />
<br />
{{hc|.emacs|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/plugins" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
这是我们在后台载入的完整配置。但是plugins文件太大导致载入太慢,如果我们要打开一个新的Emacs窗口,可能就不会使用plugins配置,每次加载它实在是太笨重了。<br />
<br />
{{hc|.emacs-light|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
现在我们这样来加载Emacs:<br />
<br />
emacs -q -l ~/.emacs-light<br />
<br />
你可以为这个命令创建一个别名。<br />
<br />
=== 加载扩展程序 ===<br />
<br />
你能用require来加载扩展程序,例如这样:<br />
<br />
(require 'mediawiki)<br />
<br />
如果你试着在一个买有安装mediawiki的机器上使用相同的配置,Emacs会提示错误。并且,所有制定的扩展代码都会失效。<br />
<br />
一个小的技巧是测试require的返回值。<br />
<br />
(if (require 'mediawiki nil t)<br />
(progn<br />
(setq mediawiki-site-alist '(<br />
("ArchLinux" "https://wiki.archlinux.org/" "UserName" "" "Main Page")<br />
)<br />
)<br />
(setq mediawiki-mode-hook<br />
(lambda ()<br />
(visual-line-mode 1)<br />
(turn-off-auto-fill)<br />
))<br />
))<br />
<br />
=== Local and custom variables ===<br />
<br />
You can define variables in your configuration file that can be later one modified locally for a file.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation")<br />
<br />
Now in any file you can define local variables in two ways:<br />
* On the very first line, write<br />
// -*- my-compiler:g++; mode:c++ -*-<br />
* If you cannot (or do not want to) write this on the first line, you can put it at the end:<br />
// Local Variables:<br />
// my-compiler: g++<br />
// mode: c++<br />
// End:<br />
<br />
Note that the beginning characters need to be comments for the current language, that's why here we used two backslashes for C++. For Elisp you would use<br />
;; -*- mode:emacs-lisp -*-<br />
<br />
There is two functions that may help you in defining the variables: ''add-file-local-variable'' and ''add-file-local-variable-prop-line''.<br />
<br />
Finally, custom variable are considered insecure by default. If you try to open a file that contains local variable redefining insecure custom variables, Emacs will ask you for confirmation.<br />
<br />
If you know what you are doing, you can declare the variable as secure, thus removing the Emacs prompt for confirmation. You need to specify a predicate that any new value has to verify so that it can be considered safe.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)<br />
<br />
In the previous example, if you attempt to set anything else than a string, Emacs will consider it insecure.<br />
<br />
=== Custom colors and theme ===<br />
<br />
Colors can be easily customized using the ''face'' facility.<br />
(set-face-background 'region "color-17")<br />
(set-face-foreground 'region "white")<br />
(set-face-bold-p 'font-lock-builtin-face t ) <br />
<br />
You can have let Emacs tell you the name of the face where the point is. Use the ''customize-face'' function for that. The facility will show you how to set colors, bold, underline, etc.<br />
<br />
Emacs in console can handle 256 colors, but you will have to use an appropriate terminal for that. For instance URxvt has support for 256 colors. You can use the ''list-colors-display'' for a comprehensive list of supported colors. This is highly terminal-dependent.<br />
<br />
=== SyncTeX support ===<br />
<br />
Emacs is definitely one of the most powerful LaTeX editor. This is mostly due to the fact you can adapt or create a LaTeX mode to fit your needs best.<br />
<br />
Still, there might be some challenges, like SyncTeX support. First you need to make sure your TeX distribution has it. If you installed TeX Live manually, you may need to install the ''synctex'' package.<br />
# umask 022 && tlmgr install synctex<br />
<br />
SyncTeX support is viewer-dependent. Here we will use Zathura as an example, so the code needs to be adapted if you want to use another PDF viewer.<br />
<br />
(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" <br />
"PDF Viewer for TeX documents. You may want to fork the viewer<br />
so that it detects when the same document is launched twice, and<br />
persists when Emacs gets closed.<br />
<br />
Simple command:<br />
<br />
zathura --fork<br />
<br />
We can use<br />
<br />
emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'<br />
<br />
to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."<br />
:safe 'stringp)<br />
<br />
Here we define our custom variable. If you are using AucTeX or Emacs default LaTeX-mode, you will have to set the viewer accordingly.<br />
<br />
Now open a LaTeX source file with Emacs, compile the document, and launch the viewer. Zathura will spawn. If you press {{ic|Ctrl+Left click}} Emacs should place the point at the corresponding position.<br />
<br />
== Documentation ==<br />
<br />
You may find yourself overwhelmed by the amount of Emacs features. You may find it difficult to know how to use Emacs Lisp to customize your favorite modes, or even to create your own modes / packages. Thankfully Emacs takes a strong point to auto-documenting everything: its internals, current configuration, bindings, etc. Almost everything is documented.<br />
<br />
=== Contextual help ===<br />
<br />
Emacs is self-documenting by design. As such, a great deal of information is available to determine the name of a specific command or its keybinding, for example. The following is a listing of some of the most helpful of these:<br />
<br />
'''C-h a''' Find a command matching a description.<br />
<br />
'''C-h b''' List all active keybindings.<br />
<br />
'''C-h f''' Describe the given function.<br />
<br />
'''C-h k''' Find which command a key is bound to.<br />
<br />
'''C-h m''' Display information regarding the currently active modes.<br />
<br />
'''C-h t''' Start the Emacs tutorial.<br />
<br />
'''C-h v''' Describe the given variable.<br />
<br />
'''C-h w''' Find which key(s) a command is bound to.<br />
<br />
=== The manuals ===<br />
<br />
If you really want to master Emacs, the most recommanded source of documentation remains the official manuals:<br />
* Emacs: the complete Emacs user manual.<br />
* Emacs FAQ.<br />
* Emacs Lisp Intro: if you never used any programming language before.<br />
* Elisp: if you are already familiar with a programming language.<br />
<br />
You can access it as PDFs from [http://www.gnu.org/software/emacs/manual/ GNU.org] or directly from Emacs itself thanks to the embedded 'info' reader: '''C-h i'''. Press '''m''' to choose a book.<br />
<br />
Some users prefer to read books using 'info' because of its convenient shortcuts, its paragraphs adapting to window width and the font adapted to current screen resolution. Some find it less irritating to the eyes. Finally you can easily copy content from the book to any Emacs buffer, and you can even execute Lisp code snippets directly from the examples.<br />
<br />
You may want to read the '''Info''' book to know more about it: '''C-h i m info <RET>'''.<br />
Press '''?''' while in info mode for a quick list of shortcuts.<br />
<br />
== 拓展模块 ==<br />
<br />
虽然Emacs包含了成百上千种模式(mode),库和其它扩展,还有更多的扩展来增强Emacs。大多数扩展会详细说明安装它的时候要对~/.emacs作什么改动。这些说明一般会在一个elisp源文件开头的注释中,或者在一个README中(如果这个扩展包含了多个源文件)。<br />
<br />
在'community'仓库中有很多流行的扩展,更多的扩展还放在了[[AUR]]。这些软件包的名字有一个'emacs-'前缀(比如emacs-lua-mode)。在很多情况下,在安装的过程会显示怎样修改~/.emacs以安装该扩展到Emacs中。<br />
<br />
想知道怎样激活一个不在上面提到的地方的扩展,查看[http://emacswiki.org/ Emacs Wiki]中的相应页面,一般会提供一个配置的例子。Emacs Wiki也是一个寻找扩展的优秀资源。<br />
<br />
你也可以使用[http://tromey.com/elpa/ Emacs Lisp Package Archive (ELPA)] 来自动安装软件包。打开那个网站看说明。ELPA已经包括在了Emacs24中;它已经作为Emacs生态系统中的一部分了。<br />
<br />
== 疑难杂症 ==<br />
<br />
===彩色输出的问题===<br />
Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。<br />
<br />
在{{ic|~/.emacs}}中加入下面的代码解决这个问题:<br />
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)<br />
<br />
===菜单显示为空===<br />
一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550541 Debian bug report] 有一个应对措施。<br />
<br />
=== X 窗口下的字符显示问题 ===<br />
当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 {{pkg|xorg-fonts-75dpi}} 或者 {{pkg|xorg-fonts-100dpi}} 并且重启X窗口。<br />
<br />
=== 启动速度慢 ===<br />
启动速度慢经常是由下面两种情况引起的。<br />
<br />
要确定是哪种情况,这样打开Emacs:<br />
<br />
$ emacs -q<br />
<br />
如果Emacs还是启动很慢,则是[[Emacs#Incorrect network configuration|错误的网络配置]]。如果不是,则可以确定是[[Emacs#Init file loads slowly|.emacs的问题]]。<br />
<br />
====错误的网络配置====<br />
<br />
当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'[[Configuring_network#Set_the_hostname|set the hostname]]' 了解更多内容。<br />
<br />
====初始化文件加载慢====<br />
<br />
一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:<br />
<br />
(require 'anything)<br />
<br />
你应该这样:<br />
<br />
(autoload 'anything "anything" "Select anything" t)<br />
<br />
=== 不能打开配置文件: ... ===<br />
<br />
这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:<br />
<br />
(add-to-list 'load-path "/path/to/directory/")<br />
<br />
当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:<br />
<br />
(add-to-list 'load-path "/usr/share/emacs/site-lisp")<br />
<br />
如果手动编译Emacs,记住默认的前缀是'/usr/local'。<br />
<br />
=== Dead-accent keys problem: '<dead-acute> is undefined' ===<br />
<br />
Searching about this bug on Google, we find this link:<br />
http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html<br />
<br />
Explaining the problem: in recent versions of<br />
b72<br />
Emacs, the normal way to use accent keys doesn't work as expected. Trying to accent a word like 'fiancé' will produce the message above.<br />
<br />
A way to solve it is just put the line above on your startup file, {{ic|~/.emacs}}:<br />
<br />
(require 'iso-transl)<br />
<br />
And no, it isn't a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):<br />
<br />
:''It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be<br />
a3b<br />
classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. ''<br />
<br />
=== C-M-% and some other bindings do not work in emacs nox ===<br />
<br />
This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:<br />
* either use the graphical version,<br />
* or change the binding to a supported one.<br />
<br />
Example:<br />
{{hc|.emacs|<br />
(global-set-key (kbd "C-M-y") 'query-replace-regexp)<br />
}}<br />
<br />
=== Emacs client gets stuck when switching back to it ===<br />
<br />
If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an '''M-x''' for instance), then all other instance will wait for it to finish. Press '''C-g''' to cancel any input to make sure this Emacs session is not blocking.<br />
<br />
=== Emacs-nox output gets messy ===<br />
<br />
When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal.<br />
There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.<br />
<br />
Graphical Emacs does not suffer from this issue.<br />
<br />
=== Shift + Arrow keys not working in emacs within tmux ===<br />
<br />
First you must enable xterm-keys in your [[tmux]] config.<br />
{{hc|.tmux.conf|<br />
setw -g xterm-keys on<br />
}}<br />
<br />
But, this will break other key combinations. To fix them, put the following in your emacs config.<br />
{{hc|.emacs|<br />
;; handle tmux's xterm-keys<br />
;; put the following line in your ~/.tmux.conf:<br />
;; setw -g xterm-keys on<br />
(if (getenv "TMUX")<br />
(progn<br />
(let ((x 2) (tkey ""))<br />
(while (<&#61; x 8)<br />
;; shift<br />
(if (&#61; x 2)<br />
(setq tkey "S-"))<br />
;; alt<br />
(if (&#61; x 3)<br />
(setq tkey "M-"))<br />
;; alt + shift<br />
(if (&#61; x 4)<br />
(setq tkey "M-S-"))<br />
;; ctrl<br />
(if (&#61; x 5)<br />
(setq tkey "C-"))<br />
;; ctrl + shift<br />
(if (&#61; x 6)<br />
(setq tkey "C-S-"))<br />
;; ctrl + alt<br />
(if (&#61; x 7)<br />
(setq tkey "C-M-"))<br />
;; ctrl + alt + shift<br />
(if (&#61; x 8)<br />
(setq tkey "C-M-S-"))<br />
<br />
;; arrows<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))<br />
;; home<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))<br />
;; end<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))<br />
;; page up<br />
(define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))<br />
;; page down<br />
(define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))<br />
;; insert<br />
(define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; delete<br />
(define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; f1<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))<br />
;; f2<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))<br />
;; f3<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))<br />
;; f4<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))<br />
;; f5<br />
(define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))<br />
;; f6<br />
(define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))<br />
;; f7<br />
(define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))<br />
;; f8<br />
(define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))<br />
;; f9<br />
(define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))<br />
;; f10<br />
(define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))<br />
;; f11<br />
(define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))<br />
;; f12<br />
(define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))<br />
;; f13<br />
(define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))<br />
;; f14<br />
(define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))<br />
;; f15<br />
(define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))<br />
;; f16<br />
(define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))<br />
;; f17<br />
(define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))<br />
;; f18<br />
(define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))<br />
;; f19<br />
(define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))<br />
;; f20<br />
(define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))<br />
<br />
(setq x (+ x 1))<br />
))<br />
)<br />
)<br />
}}<br />
<br />
== 替代方案 ==<br />
<br />
有很多Emacs的实现。GNU/Emacs 可能是最受欢迎的了。<br><br />
更轻量的兼容性较好的Emacs可以在Arch仓库或在[https://aur.archlinux.org/ AUR]中找到。<br />
<br />
=== mg ===<br />
<br />
mg(原来叫MicroGnuEmacs),是用C语言实现的轻量级Emacs。<br />
<br />
可以从{{ic|community}中安装mg<br />
# pacman -S mg<br />
或者从官方网站[http://homepage.boetes.org/software/mg/ page]中下载源代码。<br />
<br />
=== zile ===<br />
<br />
引用官方网站[https://www.gnu.org/software/zile/ page]的描述,"GNU Zile is a lightweight Emacs clone. Zile is short for Zile Is Lossy Emacs. Zile has been written to be as similar as possible to Emacs; every Emacs user should feel at home.",意思是'GNU Zile'是一个轻量级的Emacs的克隆。Zile是'Zile Is Lossy Emacs'的缩写。<br />
Zile的实现与Emacs如此相似以至于每个Emacs用户使用Zile一定会有一种宾至如归的感觉。<br />
<br />
zile 可以在{{ic|extra}}中找到<br />
<br />
# pacman -S zile<br />
<br />
最新的tarball可以在GNU的官方源[http://ftp.sh.cvut.cz/MIRRORS/gnu/pub/gnu/zile/ mirrors]中找到。<br />
<br />
=== uemacs ===<br />
<br />
uemacs 是由Linus Torvalds定制的微型Emacs版本。<br />
它可以在 [https://aur.archlinux.org/ AUR] 的 [https://aur.archlinux.org/packages.php?ID=31502 uemacs]中找到。<br />
<br />
== 资源 ==<br />
* [http://www.gnu.org/software/emacs/ GNU Emacs home page]<br />
* [http://www.gnu.org/software/emacs/manual/emacs.html GNU Emacs Manual]<br />
* [http://www.emacswiki.org/cgi-bin/wiki/ Emacs Wiki]<br />
* [http://wikemacs.org WikEmacs - a more readable, but less complete Emacs Wiki]<br />
* [http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Useful introduction to Emacs and its shortcuts]<br />
* [http://www.dina.kvl.dk/~abraham/religion/ The Church of Emacs]<br />
* [http://repo.or.cz/w/emacs.git/blob/HEAD:/etc/refcards/refcard.pdf Official reference card]</div>HelloCodehttps://wiki.archlinux.org/index.php?title=Emacs_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=355575Emacs (简体中文)2015-01-06T09:59:57Z<p>HelloCode: /* Multiple configurations */</p>
<hr />
<div>[[Category:Text editors (简体中文)]]<br />
[[de:Emacs]]<br />
[[en:Emacs]]<br />
[[fr:Emacs]]<br />
[[ja:Emacs]]<br />
[[sr:Emacs]]<br />
{{TranslationStatus (简体中文)|Emacs|2014-12-08|229169}}<br />
{{Translateme (简体中文)}}<br />
[[Wikipedia:Emacs|Emacs]]是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在[[Wikipedia:Emacs Lisp|Emacs Lisp]]解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和[[vim]]比较。<br />
<br />
{{Note|入门建议直接使用starterkit扩展。本文档实际帮助不大}}<br />
<br />
== 安装 ==<br />
Emacs有众多变体发行版本(有时候称作''emacsen''). 最常见的莫过于 [http://www.gnu.org/software/emacs/ GNU Emacs],在[[Official repositories]]可以找到<br />
<br />
$ pacman -S emacs<br />
<br />
如果你总是在终端下工作的话,你可能会选择{{Pkg|emacs-nox}}。这是一个没有GTK+依赖的版本(也没有声音支持)。<br />
<br />
终端版Emacs存在以下问题:它支持更少的颜色和更少的字体控制功能(缺少在线控制字体大小、在一篇文档中使用多种字体等功能)。而且对于一些需要高级特性的功能比如Speedbar或者GUD(调试环境),它也不支持。另外在控制复杂的外观(face)时,emacs-nox比Emacs要慢。<br />
<br />
如果你想体验Emacs的所有扩展功能而不用装一堆依赖的话,你可以使用PKGBUILD来按你的需求定制Emacs。不使用{{ic|gtk3}}可以让Emacs避免使用gconf。图像和声音的支持也可以去除。在Emacs的源代码目录下运行{{ic|./configure --help}}可以看看有哪些配置选项。<br />
{{hc|PKGBUILD|<nowiki><br />
# ...<br />
./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \<br />
--localstatedir=/var --with-x-toolkit=gtk2 --with-xft \<br />
--without-gconf --without-sound<br />
# ...<br />
</nowiki>}}<br />
<br />
另外一个常见的变体就是{{Pkg|xemacs}}.<br />
<br />
== 快速入门 ==<br />
一般印象是Emacs十分复杂,学习曲线陡峭,但很多资深学习者并不这样认为,反而认为其非常易懂和可定制。因为其源码和配置文件语义化程度较高。简单了解下自定义和高扩展带来的好处花不了多少时间。何况还有很多成熟的功能拓展模块,很方便添加,可以让Emacs为任何文本编辑的需求配置强大的环境。<br />
<br />
Emacs自带一个入门教程,你可以点击欢迎界面上的第一个链接来打开它; 或者从菜单栏中选择''Help->Emacs Tutorial'',或者按'F1'键然后按't'. 我们设计这篇文章来为你在Emacs入门学习中提供额外的资源。<br />
<br />
Emacs也包括一系列引用链接,既有适合初学者的内容,也有骨灰级玩家所喜爱的.参见{{ic|/usr/share/emacs/<version>/etc/refcards/}} (将<version>换成你的emacs版本).<br />
<br />
===运行Emacs===<br />
<br />
在启动Emacs之前,你要先学会怎么关闭它(尤其是你要在终端里运行它的话):用{{ic|Ctrl+x}}{{ic|Ctrl+c}}来关闭它。<br />
<br />
====图形界面下打开方式====<br />
图形界面下可以直接点击图标打开。<br />
<br />
====虚拟终端下的常见方式====<br />
打开Emacs:<br />
<br />
$ emacs<br />
<br />
不打开图形界面,直接在终端中运行:<br />
<br />
$ emacs -nw<br />
<br />
也可以直接用下面的命令来打开一个文件:<br />
<br />
$ emacs filename.txt<br />
<br />
=====去掉颜色=====<br />
默认的emacs会带有颜色主题,如果不需要,可以关闭之:<br />
<br />
$ emacs -nw --color=no<br />
<br />
<br />
====作为守护进程====<br />
Emacs由于每次启动都需要加载大量自定义的配置文件,所以打开时候会有点慢。从Emacs23开始, Emacs可以以守护进程的形式运行,这样每个用户都可以链接到Emacs。以守护进程运行Emacs:<br />
<br />
$ emacs --daemon<br />
<br />
你可能在启动时打开一个守护进程,然后再将守护进程链接到窗口。另外,也可以将图形和终端客户端同时链接到守护进程上,这样启动图形界面速度就很快了。<br />
<br />
如果你仅仅想链接到守护进程,用下面的命令(注意,在桌面环境下这个命令会打开一个图形客户端,而在像tty这种命令行下,它会打开一个命令行版的emacs):<br />
<br />
$ emacsclient<br />
<br />
如果你想在桌面环境下打开一个命令行版的emacs,使用下面的命令:<br />
<br />
$ emacsclient -t<br />
<br />
另外,你可以在后面加上 {{ic|-a ""}} 参数.<br />
现在,你第一次使用这个命令时,它会把emacs作为守护进程来启动,它会留在后台以加快以后的启动速度(也会记住缓冲区).<br />
<br />
更聪明点,你可以在.bashrc中加上下面的别名:<br />
{{bc|1=<br />
alias em='emacsclient -t -a ""' #在终端中开启emacs<br />
alias emc='emacsclient -nc -a ""' #启动emacs图形界面<br />
EDITOR='emacsclient -a ""'<br />
}}<br />
<br />
在[[xfce]]桌面环境中,如果你想使用 emacsclient -c 来代替 emacs %f 打开一个新文件, 你可以修改你的 /usr/share/applications/emacs.desktop 文件,把下面这一行<br />
<br />
$ Exec=emacs %f<br />
<br />
修改为<br />
<br />
$ Exec=emacsclient -c<br />
<br />
使用这种方法,每次你打开一个文件时就只会启动客户端,因此速度非常快!<br />
<br />
===基本术语和约定===<br />
Emacs使用一些刚开始看起来很奇怪的术语和约定,我们会在合适的时候介绍。但是,对于部分术语,我们必须要在前面介绍,因为它们对于使用Emacs来说是非常基础的。<br />
<br />
第一个要介绍的术语是''缓冲区''的概念。一个缓冲区就是Emacs中的数据的一种表示方式,比如,当使用Emacs打开一个文件时,这个文件从磁盘中被读出来,它的内容被存储在了缓冲区里面,它的内容可以在这个缓冲区里面被编辑并且可以重新写进磁盘中。缓冲区中的内容不仅仅可以是文本,也可以是图片和widget。现在,让缓冲区可以显示应用程序的工作正在进行!换个角度思考,在磁盘中数据是以文件形式保存的,而在Emacs中,数据是以缓冲区的形式存在的。<br />
<br />
在Emacs中,对于按键组合的约定你可能很陌生。比如:<br />
<br />
'''C-x''' 代表 Ctrl-x<br />
<br />
'''M-x''' 代表 Meta-x<br />
<br />
{{注意|'Meta'一般代表Alt键,也可以用Esc键替代。}}<br />
<br />
举个例子,退出Emacs使用下面的按键组合'''C-x C-c'''。这个可以读做,"按住Ctrl键再按'x',释放,再按住Ctrl键再按'c'。虽然Emacs提供了一个菜单栏,但是强烈建议学习使用按键组合。这个指南将参考Emacs的按键绑定的约定。<br />
<br />
===移动===<br />
光标移动和其它图形编辑器非常类似,鼠标和方向键可以用来改变光标(在Emacs中称为''点'')的位置。在Emacs中,方向键代表的标准移动命令也有其它辅助的绑定。向前(forward)移动一个字符,使用 '''C-f''',向后(back)移动一个字符,使用'''C-b'''。 '''C-n''' 和 '''C-p''' 分别用于移动到下(next)一行和移动到上(previous)一行。再声明一下,强烈推荐使用组合键而不是使用方向键和鼠标。<br />
<br />
可以想像,Emacs提供了更多的光标高级移动命令,包括移动一个单词和一个句子。 '''M-f''' 表示光标向前移动一个单词, '''M-b''' 表示向后移动一个单词。类似地,'''M-e''' 把光标移动到一个句子的末尾(end), '''M-a''' 移动到句子的开头。<br />
<br />
直到现在,所有的移动命令都是和光标有关的。'''M-<''' 表示把光标移动到缓冲区的开头,和它相反的是 '''M->''', 把光标移动到缓冲区的末尾。要把光标移动到某一特定行,使用'''M-g g'''. '''M-g g''' 会提示输入行号。同样,要移动到一行的开头或者结尾,分别使用'''C-a''' 和 '''C-e'''。<br />
<br />
{{Note|这些命令(实际上是全部命令)的绑定,在不同的模式(mode)中,''稍微''会有不同。然而,覆盖的命令提供不同的功能这种情况很少见。更多信息请看[[Emacs#Modes|Modes]]。}}<br />
<br />
===文件和缓冲区===<br />
Emacs 提供了一系列命令来对文件操作,其中最常用的会在这里详细说明。'''C-x C-f''' 用来打开一个文件(在Emacs中叫做'查找文件')。如果指定的文件不存在,Emacs会打开一个空的缓冲区。保存一个缓冲区会创建一个包含缓冲区内容的文件。'''C-x C-s''' 就是用来保存缓冲区的。要保存一个文件名不一样的缓冲区,使用'''C-x C-w''' (这其实是'write-file'这条命令的助记符), 它会在写入磁盘之前提示输入新文件名。也可以使用'''C-x s'''来保存所有的缓冲区, 如果某个缓冲区在上次保存之后被修改了,则会提示进行哪项操作。<br />
<br />
{{Note|如果指向某个文件的缓冲区还在打开的话,'''C-x C-f''' 是不会重新从磁盘中读取文件的。要从磁盘中重新读取文件,先使用'''C-x k'''关掉缓冲区,再使用'''C-x C-f'''打开文件,或者使用'''M-x revert-buffer'''.}}<br />
<br />
很多互动的命令,比如"find-file" 或者 "write-file" 会在Emacs窗口的底部栏提示输入。这栏称为''minibuffer''。和很多*nix shell一样,minibuffer支持很多基本的操作和TAB补全。按两下'''<TAB>'''可以显示一个补全的选项列表,并且,如果你喜欢,可以用鼠标从列表中选择。minibuffer的补全在很多输入(包括命令和文件名)中都可以用。<br />
<br />
minibuffer也提供一个记住历史的特性。通过'''Up Arrow''' 或者 '''C-p'''可以取得这条命令的上一个条目.<br />
<br />
要在任意时刻退出minibuffer,使用'''C-g'''.<br />
<br />
打开几个文件后,切换缓冲区是非常必要的。打开一个指向那个缓冲区的文件可以切换到那个缓冲区。但是这不是最高效的方法。Emacs提供'''C-x b'''来提示要显示的新缓冲区(这里可以使用TAB补全)。输入一个不存在的缓冲区,则会新建一个空的缓冲区。<br />
<br />
{{Note|要切换到上一个缓冲区,使用'''C-x b <RET>''', 因为上一个缓冲区是默认的缓冲区。}}<br />
<br />
使用'''C-x C-b'''可以显示所有打开缓冲区的列表。如果某个缓冲区不需要使用了,使用'''C-x k'''来关掉它。<br />
<br />
===编辑===<br />
Emacs 内建有很多编辑命令。可能最重要的还没有介绍的是'undo',它的快捷键为 ''C-_'' 或者 ''C-/'' .移动光标的命令通常都有对应的删除字符的命令。例如, '''M-<backspace>''' 可以用来删除一个光标后的词,'''M-d'''可以用来删除光标前面的一个词。删除光标至行尾或者句尾的字符可以分别用'''C-k''' 或者 '''M-k'''。<br />
<br />
通常我们都约定一行不能超过80个字符。这是为了代码的可读性,尤其是一行中的字符可能会接触到窗口边缘。在Emacs,自动地插入或者删除换行符称为''filling''。我们可以用 '''M-q''' 重整当前的段落(重新分配换行符,删除段落中多余的空格和tab键)<br />
<br />
字符和单词可以分别通过 '''C-t''' 和 '''M-t''' 进行交换。比如: <code>Hello World!</code> → <code>World! Hello</code><br />
<br />
单词的大小写也可以调整。'''M-l''' 把光标处的单词变成小写 (<code>HELLO</code> → <code>hello</code>); '''M-u''' 把光标处的单词变成大写(<code>hello</code> → <code>HELLO</code>), '''M-c''' 把光标处的单词的第一个字母变成大写,并把后面的变成小写(<code>hElLo</code> → <code>Hello</code>).<br />
<br />
===移除,召回和区域===<br />
一个''区域''(region)是指在两个位置之间的一段字。其中一个位置被称为''标记''(mark),另一个是光标。'''C-<SPC>'''用来设置标记的位置,紧接着就可以通过移动光标来创造一个区域。在GNU Emacs 23.1及以后的版本中,这个区域默认是可见的。有许多命令是针对区域的,其中最常用的就是''kill''命令。<br />
<br />
在Emacs中,剪切和粘贴分别对应的命令叫做''kill''和''yank''。许多删除多个字符的命令(包括上面提到的'''C-k'''和'''M-d'''命令)实际上是把文字剪切下来,附加到一个叫''kill-ring''的地方。kill-ring 就是一个被删掉的文字的列表。在默认情况下,kill-ring会保存最多60次删除记录。连续的删除会连在一起。<br />
<br />
'''C-w''' 和 '''M-w''' 可以用来删除或复制一个区域。<br />
<br />
要想把删掉的文字插入进来(也就是'yanking'),可以用'''C-y'''命令。'''C-y''' 可以连续用好多次来重复插入。按刚刚所讲,之前删除的文字会排成一个列表,但是'''C-y'''只能获取列表中的第一个,也就是最后删掉的一个。再之前删掉的可以通过'''M-y'''来获取。它会把'''C-y'''刚刚插入的文字用再早删除的文字替换掉。'''M-y''' 必须紧跟着'''C-y'''命令执行,可以执行很多次以遍历kill-ring。<br />
<br />
===查找和替换===<br />
在文本编辑中进行字符串查找是很常见的任务。按'''C-s'''可以正向搜索,按'''C-r‘’‘则可以反向搜索。这些命令提示要搜索的字符串。搜索是增量的,你再次按键时会显示下一个匹配的位置,并且可以使用'''C-s’‘’向前或者使用'''C-r‘’‘向后。找到匹配结果之后,可以按下'''<RET>'''结束搜索。另外,如果你想回到发起搜索的位置,可以使用'''C-g'''。<br />
<br />
一旦搜索完成(不是由'''C-g'''之类的指令引起),当前搜索的字符串将会作为下一次搜索的默认参数。使用’‘’C-s C-s'''或者'''C-r C-r'''可以达到这样的效果。<br />
<br />
I-search 有一些有用的命令,使用'''M-e'''来编辑当且搜索区域,使用'''M-c'''来触发大小写敏感匹配。<br />
<br />
正则表达式搜索除了指令不同之外,其他方面和以上都相同。使用'''C-M-s'''或者'''C-M-r'''来使用正则表达式搜索。相应地,用'''C-s'''和'''C-r'''可以前后移动,和普通的搜索没什么两样。<br />
<br />
除了搜索之外,进行字符串替换也是有必要的。原始文本和替换文本都会有提示,替换的时候也会有提示。尽管有很多选项提供(按'''?'''可以了解完整的选项),最常用的还是'''y'''(进行替换),'''n'''(跳过),以及'''!'''(替换当前及之后所有匹配)。<br />
<br />
===缩进和前缀参数===<br />
Indentation is usually performed with either '''<TAB>''', to indent a single line, or with '''C-M-\''', to indent a region.<br />
<br />
Exactly how text is indented usually depends on the ''major-mode'' which is active. Major-modes often define indentation styles specialising in indenting a certain type of text. (See [[Emacs#Modes|Modes]] for more information.)<br />
<br />
In some cases, a suitable major-mode may not exist for a file type, in which case, manual indentation may be necessary. Create a region (see [[Emacs#Killing, yanking and regions|Killing, yanking and regions]]) then perform indentation with '''C-u <n> C-x <TAB>''' (where '<n>' is the number of columns which the text within the region should be indented). For example:<br />
<br />
Increase the region's indentation by four columns:<br />
<br />
C-u 4 C-x <TAB><br />
<br />
Decrease the region's indentation by two columns.<br />
<br />
C-u -2 C-x <TAB><br />
<br />
{{Note|The trick behind this is '''C-u''', which corresponds to the 'universal-argument' command. Providing a 'universal-argument' is a way to provide more information to a command (this information is referred to as a 'prefix argument'). In this case, we provided the amount of indentation desired to the command invoked by '''C-x <TAB>'''. Without providing an argument, '''C-x <TAB>''' will only increase indentation by 1 column.}}<br />
<br />
===窗口和外框架===<br />
Emacs的设计是可以同时方便地编辑多个文件。这是通过把Emacs的接口分成三个层次来实现的,即buffer(之前介绍过了),''window''和''frame''。<br />
<br />
''window'' 是显示buffer的一个viewport(社区)。一个window一次只能显示一个buffer。但是一个buffer可以在多个window中显示。在窗口下面有一个''mode-line'',它用于显示当前buffer的信息。<br />
<br />
''frame'' 是Emacs的一个"窗口"(这是标准的术语。比如,'窗口'是现代桌面的称谓),它包含了标题栏,菜单栏,还有一个或多个'window'(这是Emacs的术语,比如上面提到的'window')。<br />
<br />
从现在起,这些Emacs中存在的名词的定义就可以使用了。<br />
<br />
要把window水平分隔和垂直分隔,分别使用'''C-x 2'''和'''C-x 3'''。这种效果其实就是在当前frame中开户另外一个window。要在多个window中循环切换,使用'''C-x o'''。<br />
<br />
与分隔一个window相反的是删除window。要删掉当前window,使用'''C-x 0''',要删掉除了当前window之外的其它window,使用'''C-x 1'''。<br />
<br />
和window一样,创建和删除frame也是可以的。'''C-x 5 2'''会创建一个frame,'''C-x 5 0'''会删除当前的frame,'''C-x 5 1'''会删除除了当前frame之外的其它frame。<br />
<br />
{{注意|这些命令不影响buffer。比如删除一个window并不会删除在window中显示的buffer。}}<br />
<br />
===获得帮助===<br />
Emacs在设计的时候就自文档化了。比如,要查看一个命令的名字或者它的键的绑定,Emacs提供了很多帮助信息。下面是列出来的最有用的一些帮助命令:<br />
<br />
'''C-h t''' 启动Emacs官方教程<br />
<br />
'''C-h b''' 列出来所有的有效键绑定<br />
<br />
'''C-h k''' 查找一个键被绑定在了哪个命令上<br />
<br />
'''C-h w''' 查找一个命令被绑定在了哪些键上<br />
<br />
'''C-h a''' 查找一个匹配一段描述的命令<br />
<br />
'''C-h m''' 显示当前激活的所有模式的信息<br />
<br />
'''C-h f''' 显示给定函数的描述信息<br />
<br />
===模式===<br />
一个Emacs模式是用Emacs Lisp语言写的一个控制相关缓冲区行为的扩展。一般来说,它给编辑文本提供缩进,语法高亮和键绑定的功能。复杂的模式可以把Emacs变成一个完美的IDE (Integrated Development Environment). Emacs 一般会使用一个文件的扩展来确定应该加载那个模式。<br />
<br />
一些编写shell脚本比较有用的模式有sh-mode, line-number-mode 和 column-number-mode。它们可以并行地通过下面的方式激活:<br />
<br />
'''M-x sh-mode <RET>'''<br />
<br />
'''M-x column-number-mode <RET>'''<br />
<br />
line-number-mode 默认是激活的,它可以通过下面的命令来打开/关闭:<br />
<br />
'''M-x line-number-mode <RET>'''<br />
<br />
sh-mode 是一个 ''major-mode''. Major-modes 调整Emacs,并且经常提供了一些特定的命令来编辑某种类型的文本。一个缓冲区只能激活一种major-mode。除了支持语法高亮和缩进,sh-mode还定义了几条命令来帮助快速开发shell脚本。下面是其中的几条:<br />
<br />
'''C-c (''' 插入一个函数定义<br />
<br />
'''C-c C-f''' 插入一个for循环<br />
<br />
'''C-c TAB''' 插入一条if语句<br />
<br />
'''C-c C-w''' 插入一个while循环<br />
<br />
'''C-c C-l''' 插入一个从1到n的有下标的循环<br />
<br />
'line-number-mode' 和 'column-number-mode' 是 ''minor-modes''. Minor-modes 可以用来扩充major-mode的功能,多个minor-mode可以同时激活。<br />
<br />
==提示和技巧==<br />
前面的部分给出了基本编辑命令的概述,没有给出Emacs的一个指示。这个部分讲述一些高级的技巧和功能。<br />
<br />
===TRAMP===<br />
TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入一个文件名,输入特定的格式就可以使用TRAMPP。比如:<br />
<br />
在打开{{ic|/etc/hosts}}文件之前提示输入root的密码以获取root权限:<br />
<br />
C-x C-f /su::/etc/hosts<br />
<br />
要通过SSH使用'myuser'用户名登录'myhost'主机并打开文件{{ic|~/example.txt}}:<br />
<br />
C-x C-f /ssh:myuser@myhost:~/example.txt<br />
<br />
TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。<br />
<br />
===键盘宏和寄存器===<br />
这一部分会提供一个实用的指南来使用一些更强大的编辑特性。也就是“键盘宏”和“寄存器”。<br />
<br />
我们的目标是产生一个字符列表和它们在这个列表中对应的位置。虽然这可以通过手工格式化来完成,但是这样会很慢而且容易出错。如果我们采用一些Emacs更高级的编辑功能却可以起到四两拨千斤的功效。在介绍这个方法之前,需要先了解一些技术背后的细节。<br />
<br />
要介绍的第一个特性就是''寄存器''。寄存器的功能是用来保存和获取各种各样的数据。每个寄存器用一个字母来命名,这个字母就是用来调用这个寄存器的。<br />
<br />
另一个要介绍的就是''键盘宏''。一个键盘宏存储了一个命令序列以便以后可以重复使用。下面就一步一步地讲解这个方法。<br />
<br />
首先我们从一个包含如下字符的缓冲区开始:<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
通过`number-to-register' 命令 ('''C-x r n''')我们来准备一个寄存器,把数字'0'存储在寄存器'k'中:<br />
<br />
C-x r n k<br />
<br />
当光标在缓冲区开头的时候,开始录制键盘宏 ('''C-x (''') 然后开始对字符串进行格式化:<br />
<br />
C-x ( C-f M-4 .<br />
<br />
插入 ('''C-x r i''') 然后将寄存器'k'加1 ('''C-x r +''') 。开头的 ('''C-u''') 命令是用来在插入文字之后让光标移到插入的文字后面:<br />
<br />
C-u C-x r i k C-x r + k<br />
<br />
最后我们来插入一个回车来结束格式化。Emacs可以重复以上过程,从我们定义键盘宏的位置开始,直到最后一个字符。'''C-x e'''命令停止宏的录制并开始执行这段宏。开头的 '''M-0''' 命令是用来让宏在出错的时候停下来,这样在它走到这行的结尾就会停下来。<br />
<br />
<RET> M-0 C-x e<br />
<br />
下面是结果:<br />
<br />
A....0<br />
B....1<br />
C....2<br />
[...]<br />
x....49<br />
y....50<br />
z....51<br />
<br />
===正则表达式===<br />
From the Emacs Manual: "A regular expression, or ''regexp'' for short, is a pattern that denotes a (possibly infinite) set of strings." This section will not go into any detail regarding regular expressions themselves (as there is simply too much to cover). It will however provide a quick demonstration of their power. See [http://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html#Regular-Expressions Regular Expressions] section in the Emacs Manual for further reading.<br />
<br />
Given the same scenario presented above: A list of characters which are to be formatted to represent their respective position in the list. (see [[Emacs#Keyboard macros and registers|Keyboard macros and registers]]). Again, starting with a buffer containing.<br />
<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
At the beginning of the buffer, use '''C-M-%''' (if the key-sequence is difficult to perform, it may be more comfortable to use '''M-x query-replace-regexp'''). At the prompt:<br />
\(.\)<br />
which simply matches one character. Then, when prompted for the replacement:<br />
\1....\#^J<br />
{{Note|'^J' represents where a newline should be placed, it should not be entered into the prompt. The newline must instead be inserted literally using '''C-q C-j'''.}}<br />
The replacement expression reads: "Insert the matched text between the first set of parentheses (in this case, a single character), followed by 4 periods then insert an automatically incremented number followed by a newline.<br />
<br />
Finally, press '''!''' to apply this across the entire buffer. All of the formatting that was performed in the previous section was performed with a single regexp replacement.<br />
<br />
==定制==<br />
Emacs能通过~/.emacs或者'''M-x customize'''来定制。本段落将着眼于手动定制 ~/.emacs,并且提供了一些常用配置的样例。配置命令提供了一个适应的途径,通过它你能够渐渐熟悉Emacs。<br />
<br />
这里的所有例子都能在Emacs中奏效。比如,在Emacs中计算表达式:<br />
'''C-M-x''' 同时指到任何需要求值的地方。<br />
<br />
或者<br />
<br />
'''C-x C-e''' 指到最后的“)”。<br />
<br />
用'y'和'n'来代替频繁地输入'yes’和'no‘是一个好的方法:<br />
<br />
(defalias 'yes-or-no-p 'y-or-n-p)<br />
<br />
取消光标闪烁:<br />
<br />
(blink-cursor-mode -1)<br />
<br />
类似地,开启上一节提到的列号模式:<br />
<br />
(column-number-mode 1)<br />
<br />
它们两者之间的相似不是偶然:光标闪烁模式和列号模式都是'副参模式',按照规则,'副参模式’能通过正负值来设置。如果参数省略,'副参模式'将被开/关。<br />
<br />
这里有其他一些'副参模式'的例子,下面的参数将会关闭滚动栏、菜单栏、工具栏。<br />
(scroll-bar-mode -1)<br />
(menu-bar-mode -1)<br />
(tool-bar-mode -1)<br />
<br />
变量'auto-mode-alist'修改之后能够改变默认的“主参模式”。下面的例子把'.tut'和'.req'修改成了'.text-mode'。<br />
<br />
(setq auto-mode-alist<br />
(append<br />
'(("\\.tut$" . text-mode)<br />
("\\.req$" . text-mode))<br />
auto-mode-alist))<br />
<br />
Settings can also be applied on a per-mode basis. A common method for this is to add a function to a ''hook''. For example, to force indentation to use spaces instead of tabs, but only in text-mode:<br />
<br />
(add-hook 'text-mode-hook (lambda () (setq indent-tabs-mode nil)))<br />
<br />
Similarly, to only use spaces for indentation everywhere:<br />
<br />
(setq-default indent-tabs-mode nil)<br />
<br />
Keybindings can be adjusted in two ways. The first of which is 'define-key'. 'define-key' creates a keybinding for a command but only in one mode. The example below will make '''F8''' delete any whitespace from the end of each line of a 'text-mode' buffer:<br />
<br />
(define-key text-mode-map (kbd "<f8>") 'delete-trailing-whitespace)<br />
<br />
The other method is 'global-set-key'. This is used to bind a key to a command everywhere. To bind 'query-replace-regexp' ('''C-M-%''') to '<f7>'.<br />
<br />
(global-set-key (kbd "<f7>") 'query-replace-regexp)<br />
<br />
Binding a command to an alternate key does not replace any existing bindings. Which is to say, 'query-replace-regexp' would be bound to both '''F7''' and '''C-M-%''' after the above example.<br />
<br />
Almost anything within Emacs can be configured. Browsing through the [http://emacswiki.org/ Emacs Wiki] should give a solid place to start.<br />
<br />
<br />
=== 多种配置 ===<br />
<br />
你可以使用少量配置然后告诉Emacs来加载其他配置。<br />
<br />
例如,我们来定义两个配置文件。<br />
<br />
{{hc|.emacs|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/plugins" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
这是我们在后台载入的完整配置。但是plugins文件太大导致载入太慢,如果我们要打开一个新的Emacs窗口,可能就不会使用plugins配置,每次加载它实在是太笨重了。<br />
<br />
{{hc|.emacs-light|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
现在我们这样来加载Emacs:<br />
<br />
emacs -q -l ~/.emacs-light<br />
<br />
你可以为这个命令创建一个别名。<br />
<br />
=== Loading extensions ===<br />
<br />
You can load extensions using the ''require'' function. For instance<br />
(require 'mediawiki)<br />
<br />
If you try using the same configuration file on a machine where mediawiki is not installed, Emacs will primpt for an error. Besides, all extension-specific code would be parsed for nothing.<br />
<br />
The trick is to test the return value of ''require'':<br />
<br />
(if (require 'mediawiki nil t)<br />
(progn<br />
(setq mediawiki-site-alist '(<br />
("ArchLinux" "https://wiki.archlinux.org/" "UserName" "" "Main Page")<br />
)<br />
)<br />
(setq mediawiki-mode-hook<br />
(lambda ()<br />
(visual-line-mode 1)<br />
(turn-off-auto-fill)<br />
))<br />
)) <br />
<br />
=== Local and custom variables ===<br />
<br />
You can define variables in your configuration file that can be later one modified locally for a file.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation")<br />
<br />
Now in any file you can define local variables in two ways:<br />
* On the very first line, write<br />
// -*- my-compiler:g++; mode:c++ -*-<br />
* If you cannot (or do not want to) write this on the first line, you can put it at the end:<br />
// Local Variables:<br />
// my-compiler: g++<br />
// mode: c++<br />
// End:<br />
<br />
Note that the beginning characters need to be comments for the current language, that's why here we used two backslashes for C++. For Elisp you would use<br />
;; -*- mode:emacs-lisp -*-<br />
<br />
There is two functions that may help you in defining the variables: ''add-file-local-variable'' and ''add-file-local-variable-prop-line''.<br />
<br />
Finally, custom variable are considered insecure by default. If you try to open a file that contains local variable redefining insecure custom variables, Emacs will ask you for confirmation.<br />
<br />
If you know what you are doing, you can declare the variable as secure, thus removing the Emacs prompt for confirmation. You need to specify a predicate that any new value has to verify so that it can be considered safe.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)<br />
<br />
In the previous example, if you attempt to set anything else than a string, Emacs will consider it insecure.<br />
<br />
=== Custom colors and theme ===<br />
<br />
Colors can be easily customized using the ''face'' facility.<br />
(set-face-background 'region "color-17")<br />
(set-face-foreground 'region "white")<br />
(set-face-bold-p 'font-lock-builtin-face t ) <br />
<br />
You can have let Emacs tell you the name of the face where the point is. Use the ''customize-face'' function for that. The facility will show you how to set colors, bold, underline, etc.<br />
<br />
Emacs in console can handle 256 colors, but you will have to use an appropriate terminal for that. For instance URxvt has support for 256 colors. You can use the ''list-colors-display'' for a comprehensive list of supported colors. This is highly terminal-dependent.<br />
<br />
=== SyncTeX support ===<br />
<br />
Emacs is definitely one of the most powerful LaTeX editor. This is mostly due to the fact you can adapt or create a LaTeX mode to fit your needs best.<br />
<br />
Still, there might be some challenges, like SyncTeX support. First you need to make sure your TeX distribution has it. If you installed TeX Live manually, you may need to install the ''synctex'' package.<br />
# umask 022 && tlmgr install synctex<br />
<br />
SyncTeX support is viewer-dependent. Here we will use Zathura as an example, so the code needs to be adapted if you want to use another PDF viewer.<br />
<br />
(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" <br />
"PDF Viewer for TeX documents. You may want to fork the viewer<br />
so that it detects when the same document is launched twice, and<br />
persists when Emacs gets closed.<br />
<br />
Simple command:<br />
<br />
zathura --fork<br />
<br />
We can use<br />
<br />
emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'<br />
<br />
to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."<br />
:safe 'stringp)<br />
<br />
Here we define our custom variable. If you are using AucTeX or Emacs default LaTeX-mode, you will have to set the viewer accordingly.<br />
<br />
Now open a LaTeX source file with Emacs, compile the document, and launch the viewer. Zathura will spawn. If you press {{ic|Ctrl+Left click}} Emacs should place the point at the corresponding position.<br />
<br />
== Documentation ==<br />
<br />
You may find yourself overwhelmed by the amount of Emacs features. You may find it difficult to know how to use Emacs Lisp to customize your favorite modes, or even to create your own modes / packages. Thankfully Emacs takes a strong point to auto-documenting everything: its internals, current configuration, bindings, etc. Almost everything is documented.<br />
<br />
=== Contextual help ===<br />
<br />
Emacs is self-documenting by design. As such, a great deal of information is available to determine the name of a specific command or its keybinding, for example. The following is a listing of some of the most helpful of these:<br />
<br />
'''C-h a''' Find a command matching a description.<br />
<br />
'''C-h b''' List all active keybindings.<br />
<br />
'''C-h f''' Describe the given function.<br />
<br />
'''C-h k''' Find which command a key is bound to.<br />
<br />
'''C-h m''' Display information regarding the currently active modes.<br />
<br />
'''C-h t''' Start the Emacs tutorial.<br />
<br />
'''C-h v''' Describe the given variable.<br />
<br />
'''C-h w''' Find which key(s) a command is bound to.<br />
<br />
=== The manuals ===<br />
<br />
If you really want to master Emacs, the most recommanded source of documentation remains the official manuals:<br />
* Emacs: the complete Emacs user manual.<br />
* Emacs FAQ.<br />
* Emacs Lisp Intro: if you never used any programming language before.<br />
* Elisp: if you are already familiar with a programming language.<br />
<br />
You can access it as PDFs from [http://www.gnu.org/software/emacs/manual/ GNU.org] or directly from Emacs itself thanks to the embedded 'info' reader: '''C-h i'''. Press '''m''' to choose a book.<br />
<br />
Some users prefer to read books using 'info' because of its convenient shortcuts, its paragraphs adapting to window width and the font adapted to current screen resolution. Some find it less irritating to the eyes. Finally you can easily copy content from the book to any Emacs buffer, and you can even execute Lisp code snippets directly from the examples.<br />
<br />
You may want to read the '''Info''' book to know more about it: '''C-h i m info <RET>'''.<br />
Press '''?''' while in info mode for a quick list of shortcuts.<br />
<br />
== 拓展模块 ==<br />
<br />
虽然Emacs包含了成百上千种模式(mode),库和其它扩展,还有更多的扩展来增强Emacs。大多数扩展会详细说明安装它的时候要对~/.emacs作什么改动。这些说明一般会在一个elisp源文件开头的注释中,或者在一个README中(如果这个扩展包含了多个源文件)。<br />
<br />
在'community'仓库中有很多流行的扩展,更多的扩展还放在了[[AUR]]。这些软件包的名字有一个'emacs-'前缀(比如emacs-lua-mode)。在很多情况下,在安装的过程会显示怎样修改~/.emacs以安装该扩展到Emacs中。<br />
<br />
想知道怎样激活一个不在上面提到的地方的扩展,查看[http://emacswiki.org/ Emacs Wiki]中的相应页面,一般会提供一个配置的例子。Emacs Wiki也是一个寻找扩展的优秀资源。<br />
<br />
你也可以使用[http://tromey.com/elpa/ Emacs Lisp Package Archive (ELPA)] 来自动安装软件包。打开那个网站看说明。ELPA已经包括在了Emacs24中;它已经作为Emacs生态系统中的一部分了。<br />
<br />
== 疑难杂症 ==<br />
<br />
===彩色输出的问题===<br />
Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。<br />
<br />
在{{ic|~/.emacs}}中加入下面的代码解决这个问题:<br />
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)<br />
<br />
===菜单显示为空===<br />
一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550541 Debian bug report] 有一个应对措施。<br />
<br />
=== X 窗口下的字符显示问题 ===<br />
当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 {{pkg|xorg-fonts-75dpi}} 或者 {{pkg|xorg-fonts-100dpi}} 并且重启X窗口。<br />
<br />
=== 启动速度慢 ===<br />
启动速度慢经常是由下面两种情况引起的。<br />
<br />
要确定是哪种情况,这样打开Emacs:<br />
<br />
$ emacs -q<br />
<br />
如果Emacs还是启动很慢,则是[[Emacs#Incorrect network configuration|错误的网络配置]]。如果不是,则可以确定是[[Emacs#Init file loads slowly|.emacs的问题]]。<br />
<br />
====错误的网络配置====<br />
<br />
当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'[[Configuring_network#Set_the_hostname|set the hostname]]' 了解更多内容。<br />
<br />
====初始化文件加载慢====<br />
<br />
一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:<br />
<br />
(require 'anything)<br />
<br />
你应该这样:<br />
<br />
(autoload 'anything "anything" "Select anything" t)<br />
<br />
=== 不能打开配置文件: ... ===<br />
<br />
这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:<br />
<br />
(add-to-list 'load-path "/path/to/directory/")<br />
<br />
当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:<br />
<br />
(add-to-list 'load-path "/usr/share/emacs/site-lisp")<br />
<br />
如果手动编译Emacs,记住默认的前缀是'/usr/local'。<br />
<br />
=== Dead-accent keys problem: '<dead-acute> is undefined' ===<br />
<br />
Searching about this bug on Google, we find this link:<br />
http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html<br />
<br />
Explaining the problem: in recent versions of<br />
b72<br />
Emacs, the normal way to use accent keys doesn't work as expected. Trying to accent a word like 'fiancé' will produce the message above.<br />
<br />
A way to solve it is just put the line above on your startup file, {{ic|~/.emacs}}:<br />
<br />
(require 'iso-transl)<br />
<br />
And no, it isn't a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):<br />
<br />
:''It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be<br />
a3b<br />
classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. ''<br />
<br />
=== C-M-% and some other bindings do not work in emacs nox ===<br />
<br />
This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:<br />
* either use the graphical version,<br />
* or change the binding to a supported one.<br />
<br />
Example:<br />
{{hc|.emacs|<br />
(global-set-key (kbd "C-M-y") 'query-replace-regexp)<br />
}}<br />
<br />
=== Emacs client gets stuck when switching back to it ===<br />
<br />
If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an '''M-x''' for instance), then all other instance will wait for it to finish. Press '''C-g''' to cancel any input to make sure this Emacs session is not blocking.<br />
<br />
=== Emacs-nox output gets messy ===<br />
<br />
When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal.<br />
There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.<br />
<br />
Graphical Emacs does not suffer from this issue.<br />
<br />
=== Shift + Arrow keys not working in emacs within tmux ===<br />
<br />
First you must enable xterm-keys in your [[tmux]] config.<br />
{{hc|.tmux.conf|<br />
setw -g xterm-keys on<br />
}}<br />
<br />
But, this will break other key combinations. To fix them, put the following in your emacs config.<br />
{{hc|.emacs|<br />
;; handle tmux's xterm-keys<br />
;; put the following line in your ~/.tmux.conf:<br />
;; setw -g xterm-keys on<br />
(if (getenv "TMUX")<br />
(progn<br />
(let ((x 2) (tkey ""))<br />
(while (<&#61; x 8)<br />
;; shift<br />
(if (&#61; x 2)<br />
(setq tkey "S-"))<br />
;; alt<br />
(if (&#61; x 3)<br />
(setq tkey "M-"))<br />
;; alt + shift<br />
(if (&#61; x 4)<br />
(setq tkey "M-S-"))<br />
;; ctrl<br />
(if (&#61; x 5)<br />
(setq tkey "C-"))<br />
;; ctrl + shift<br />
(if (&#61; x 6)<br />
(setq tkey "C-S-"))<br />
;; ctrl + alt<br />
(if (&#61; x 7)<br />
(setq tkey "C-M-"))<br />
;; ctrl + alt + shift<br />
(if (&#61; x 8)<br />
(setq tkey "C-M-S-"))<br />
<br />
;; arrows<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))<br />
;; home<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))<br />
;; end<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))<br />
;; page up<br />
(define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))<br />
;; page down<br />
(define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))<br />
;; insert<br />
(define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; delete<br />
(define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; f1<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))<br />
;; f2<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))<br />
;; f3<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))<br />
;; f4<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))<br />
;; f5<br />
(define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))<br />
;; f6<br />
(define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))<br />
;; f7<br />
(define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))<br />
;; f8<br />
(define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))<br />
;; f9<br />
(define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))<br />
;; f10<br />
(define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))<br />
;; f11<br />
(define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))<br />
;; f12<br />
(define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))<br />
;; f13<br />
(define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))<br />
;; f14<br />
(define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))<br />
;; f15<br />
(define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))<br />
;; f16<br />
(define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))<br />
;; f17<br />
(define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))<br />
;; f18<br />
(define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))<br />
;; f19<br />
(define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))<br />
;; f20<br />
(define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))<br />
<br />
(setq x (+ x 1))<br />
))<br />
)<br />
)<br />
}}<br />
<br />
== 替代方案 ==<br />
<br />
有很多Emacs的实现。GNU/Emacs 可能是最受欢迎的了。<br><br />
更轻量的兼容性较好的Emacs可以在Arch仓库或在[https://aur.archlinux.org/ AUR]中找到。<br />
<br />
=== mg ===<br />
<br />
mg(原来叫MicroGnuEmacs),是用C语言实现的轻量级Emacs。<br />
<br />
可以从{{ic|community}中安装mg<br />
# pacman -S mg<br />
或者从官方网站[http://homepage.boetes.org/software/mg/ page]中下载源代码。<br />
<br />
=== zile ===<br />
<br />
引用官方网站[https://www.gnu.org/software/zile/ page]的描述,"GNU Zile is a lightweight Emacs clone. Zile is short for Zile Is Lossy Emacs. Zile has been written to be as similar as possible to Emacs; every Emacs user should feel at home.",意思是'GNU Zile'是一个轻量级的Emacs的克隆。Zile是'Zile Is Lossy Emacs'的缩写。<br />
Zile的实现与Emacs如此相似以至于每个Emacs用户使用Zile一定会有一种宾至如归的感觉。<br />
<br />
zile 可以在{{ic|extra}}中找到<br />
<br />
# pacman -S zile<br />
<br />
最新的tarball可以在GNU的官方源[http://ftp.sh.cvut.cz/MIRRORS/gnu/pub/gnu/zile/ mirrors]中找到。<br />
<br />
=== uemacs ===<br />
<br />
uemacs 是由Linus Torvalds定制的微型Emacs版本。<br />
它可以在 [https://aur.archlinux.org/ AUR] 的 [https://aur.archlinux.org/packages.php?ID=31502 uemacs]中找到。<br />
<br />
== 资源 ==<br />
* [http://www.gnu.org/software/emacs/ GNU Emacs home page]<br />
* [http://www.gnu.org/software/emacs/manual/emacs.html GNU Emacs Manual]<br />
* [http://www.emacswiki.org/cgi-bin/wiki/ Emacs Wiki]<br />
* [http://wikemacs.org WikEmacs - a more readable, but less complete Emacs Wiki]<br />
* [http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Useful introduction to Emacs and its shortcuts]<br />
* [http://www.dina.kvl.dk/~abraham/religion/ The Church of Emacs]<br />
* [http://repo.or.cz/w/emacs.git/blob/HEAD:/etc/refcards/refcard.pdf Official reference card]</div>HelloCodehttps://wiki.archlinux.org/index.php?title=Emacs_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=349394Emacs (简体中文)2014-12-10T14:07:55Z<p>HelloCode: /* 定制 */</p>
<hr />
<div>[[Category:Text editors (简体中文)]]<br />
[[de:Emacs]]<br />
[[en:Emacs]]<br />
[[fr:Emacs]]<br />
[[ja:Emacs]]<br />
[[sr:Emacs]]<br />
{{TranslationStatus (简体中文)|Emacs|2014-12-08|229169}}<br />
{{Translateme (简体中文)}}<br />
[[Wikipedia:Emacs|Emacs]]是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在[[Wikipedia:Emacs Lisp|Emacs Lisp]]解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和[[vim]]比较。<br />
<br />
{{Note|入门建议直接使用starterkit扩展。本文档实际帮助不大}}<br />
<br />
== 安装 ==<br />
Emacs有众多变体发行版本(有时候称作''emacsen''). 最常见的莫过于 [http://www.gnu.org/software/emacs/ GNU Emacs],在[[Official repositories]]可以找到<br />
<br />
$ pacman -S emacs<br />
<br />
如果你总是在终端下工作的话,你可能会选择{{Pkg|emacs-nox}}。这是一个没有GTK+依赖的版本(也没有声音支持)。<br />
<br />
终端版Emacs存在以下问题:它支持更少的颜色和更少的字体控制功能(缺少在线控制字体大小、在一篇文档中使用多种字体等功能)。而且对于一些需要高级特性的功能比如Speedbar或者GUD(调试环境),它也不支持。另外在控制复杂的外观(face)时,emacs-nox比Emacs要慢。<br />
<br />
如果你想体验Emacs的所有扩展功能而不用装一堆依赖的话,你可以使用PKGBUILD来按你的需求定制Emacs。不使用{{ic|gtk3}}可以让Emacs避免使用gconf。图像和声音的支持也可以去除。在Emacs的源代码目录下运行{{ic|./configure --help}}可以看看有哪些配置选项。<br />
{{hc|PKGBUILD|<nowiki><br />
# ...<br />
./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \<br />
--localstatedir=/var --with-x-toolkit=gtk2 --with-xft \<br />
--without-gconf --without-sound<br />
# ...<br />
</nowiki>}}<br />
<br />
另外一个常见的变体就是{{Pkg|xemacs}}.<br />
<br />
== 快速入门 ==<br />
一般印象是Emacs十分复杂,学习曲线陡峭,但很多资深学习者并不这样认为,反而认为其非常易懂和可定制。因为其源码和配置文件语义化程度较高。简单了解下自定义和高扩展带来的好处花不了多少时间。何况还有很多成熟的功能拓展模块,很方便添加,可以让Emacs为任何文本编辑的需求配置强大的环境。<br />
<br />
Emacs自带一个入门教程,你可以点击欢迎界面上的第一个链接来打开它; 或者从菜单栏中选择''Help->Emacs Tutorial'',或者按'F1'键然后按't'. 我们设计这篇文章来为你在Emacs入门学习中提供额外的资源。<br />
<br />
Emacs也包括一系列引用链接,既有适合初学者的内容,也有骨灰级玩家所喜爱的.参见{{ic|/usr/share/emacs/<version>/etc/refcards/}} (将<version>换成你的emacs版本).<br />
<br />
===运行Emacs===<br />
<br />
在启动Emacs之前,你要先学会怎么关闭它(尤其是你要在终端里运行它的话):用{{ic|Ctrl+x}}{{ic|Ctrl+c}}来关闭它。<br />
<br />
====图形界面下打开方式====<br />
图形界面下可以直接点击图标打开。<br />
<br />
====虚拟终端下的常见方式====<br />
打开Emacs:<br />
<br />
$ emacs<br />
<br />
不打开图形界面,直接在终端中运行:<br />
<br />
$ emacs -nw<br />
<br />
也可以直接用下面的命令来打开一个文件:<br />
<br />
$ emacs filename.txt<br />
<br />
=====去掉颜色=====<br />
默认的emacs会带有颜色主题,如果不需要,可以关闭之:<br />
<br />
$ emacs -nw --color=no<br />
<br />
<br />
====作为守护进程====<br />
Emacs由于每次启动都需要加载大量自定义的配置文件,所以打开时候会有点慢。从Emacs23开始, Emacs可以以守护进程的形式运行,这样每个用户都可以链接到Emacs。以守护进程运行Emacs:<br />
<br />
$ emacs --daemon<br />
<br />
你可能在启动时打开一个守护进程,然后再将守护进程链接到窗口。另外,也可以将图形和终端客户端同时链接到守护进程上,这样启动图形界面速度就很快了。<br />
<br />
如果你仅仅想链接到守护进程,用下面的命令(注意,在桌面环境下这个命令会打开一个图形客户端,而在像tty这种命令行下,它会打开一个命令行版的emacs):<br />
<br />
$ emacsclient<br />
<br />
如果你想在桌面环境下打开一个命令行版的emacs,使用下面的命令:<br />
<br />
$ emacsclient -t<br />
<br />
另外,你可以在后面加上 {{ic|-a ""}} 参数.<br />
现在,你第一次使用这个命令时,它会把emacs作为守护进程来启动,它会留在后台以加快以后的启动速度(也会记住缓冲区).<br />
<br />
更聪明点,你可以在.bashrc中加上下面的别名:<br />
{{bc|1=<br />
alias em='emacsclient -t -a ""' #在终端中开启emacs<br />
alias emc='emacsclient -nc -a ""' #启动emacs图形界面<br />
EDITOR='emacsclient -a ""'<br />
}}<br />
<br />
在[[xfce]]桌面环境中,如果你想使用 emacsclient -c 来代替 emacs %f 打开一个新文件, 你可以修改你的 /usr/share/applications/emacs.desktop 文件,把下面这一行<br />
<br />
$ Exec=emacs %f<br />
<br />
修改为<br />
<br />
$ Exec=emacsclient -c<br />
<br />
使用这种方法,每次你打开一个文件时就只会启动客户端,因此速度非常快!<br />
<br />
===基本术语和约定===<br />
Emacs使用一些刚开始看起来很奇怪的术语和约定,我们会在合适的时候介绍。但是,对于部分术语,我们必须要在前面介绍,因为它们对于使用Emacs来说是非常基础的。<br />
<br />
第一个要介绍的术语是''缓冲区''的概念。一个缓冲区就是Emacs中的数据的一种表示方式,比如,当使用Emacs打开一个文件时,这个文件从磁盘中被读出来,它的内容被存储在了缓冲区里面,它的内容可以在这个缓冲区里面被编辑并且可以重新写进磁盘中。缓冲区中的内容不仅仅可以是文本,也可以是图片和widget。现在,让缓冲区可以显示应用程序的工作正在进行!换个角度思考,在磁盘中数据是以文件形式保存的,而在Emacs中,数据是以缓冲区的形式存在的。<br />
<br />
在Emacs中,对于按键组合的约定你可能很陌生。比如:<br />
<br />
'''C-x''' 代表 Ctrl-x<br />
<br />
'''M-x''' 代表 Meta-x<br />
<br />
{{注意|'Meta'一般代表Alt键,也可以用Esc键替代。}}<br />
<br />
举个例子,退出Emacs使用下面的按键组合'''C-x C-c'''。这个可以读做,"按住Ctrl键再按'x',释放,再按住Ctrl键再按'c'。虽然Emacs提供了一个菜单栏,但是强烈建议学习使用按键组合。这个指南将参考Emacs的按键绑定的约定。<br />
<br />
===移动===<br />
光标移动和其它图形编辑器非常类似,鼠标和方向键可以用来改变光标(在Emacs中称为''点'')的位置。在Emacs中,方向键代表的标准移动命令也有其它辅助的绑定。向前(forward)移动一个字符,使用 '''C-f''',向后(back)移动一个字符,使用'''C-b'''。 '''C-n''' 和 '''C-p''' 分别用于移动到下(next)一行和移动到上(previous)一行。再声明一下,强烈推荐使用组合键而不是使用方向键和鼠标。<br />
<br />
可以想像,Emacs提供了更多的光标高级移动命令,包括移动一个单词和一个句子。 '''M-f''' 表示光标向前移动一个单词, '''M-b''' 表示向后移动一个单词。类似地,'''M-e''' 把光标移动到一个句子的末尾(end), '''M-a''' 移动到句子的开头。<br />
<br />
直到现在,所有的移动命令都是和光标有关的。'''M-<''' 表示把光标移动到缓冲区的开头,和它相反的是 '''M->''', 把光标移动到缓冲区的末尾。要把光标移动到某一特定行,使用'''M-g g'''. '''M-g g''' 会提示输入行号。同样,要移动到一行的开头或者结尾,分别使用'''C-a''' 和 '''C-e'''。<br />
<br />
{{Note|这些命令(实际上是全部命令)的绑定,在不同的模式(mode)中,''稍微''会有不同。然而,覆盖的命令提供不同的功能这种情况很少见。更多信息请看[[Emacs#Modes|Modes]]。}}<br />
<br />
===文件和缓冲区===<br />
Emacs 提供了一系列命令来对文件操作,其中最常用的会在这里详细说明。'''C-x C-f''' 用来打开一个文件(在Emacs中叫做'查找文件')。如果指定的文件不存在,Emacs会打开一个空的缓冲区。保存一个缓冲区会创建一个包含缓冲区内容的文件。'''C-x C-s''' 就是用来保存缓冲区的。要保存一个文件名不一样的缓冲区,使用'''C-x C-w''' (这其实是'write-file'这条命令的助记符), 它会在写入磁盘之前提示输入新文件名。也可以使用'''C-x s'''来保存所有的缓冲区, 如果某个缓冲区在上次保存之后被修改了,则会提示进行哪项操作。<br />
<br />
{{Note|如果指向某个文件的缓冲区还在打开的话,'''C-x C-f''' 是不会重新从磁盘中读取文件的。要从磁盘中重新读取文件,先使用'''C-x k'''关掉缓冲区,再使用'''C-x C-f'''打开文件,或者使用'''M-x revert-buffer'''.}}<br />
<br />
很多互动的命令,比如"find-file" 或者 "write-file" 会在Emacs窗口的底部栏提示输入。这栏称为''minibuffer''。和很多*nix shell一样,minibuffer支持很多基本的操作和TAB补全。按两下'''<TAB>'''可以显示一个补全的选项列表,并且,如果你喜欢,可以用鼠标从列表中选择。minibuffer的补全在很多输入(包括命令和文件名)中都可以用。<br />
<br />
minibuffer也提供一个记住历史的特性。通过'''Up Arrow''' 或者 '''C-p'''可以取得这条命令的上一个条目.<br />
<br />
要在任意时刻退出minibuffer,使用'''C-g'''.<br />
<br />
打开几个文件后,切换缓冲区是非常必要的。打开一个指向那个缓冲区的文件可以切换到那个缓冲区。但是这不是最高效的方法。Emacs提供'''C-x b'''来提示要显示的新缓冲区(这里可以使用TAB补全)。输入一个不存在的缓冲区,则会新建一个空的缓冲区。<br />
<br />
{{Note|要切换到上一个缓冲区,使用'''C-x b <RET>''', 因为上一个缓冲区是默认的缓冲区。}}<br />
<br />
使用'''C-x C-b'''可以显示所有打开缓冲区的列表。如果某个缓冲区不需要使用了,使用'''C-x k'''来关掉它。<br />
<br />
===编辑===<br />
Emacs 内建有很多编辑命令。可能最重要的还没有介绍的是'undo',它的快捷键为 ''C-_'' 或者 ''C-/'' .移动光标的命令通常都有对应的删除字符的命令。例如, '''M-<backspace>''' 可以用来删除一个光标后的词,'''M-d'''可以用来删除光标前面的一个词。删除光标至行尾或者句尾的字符可以分别用'''C-k''' 或者 '''M-k'''。<br />
<br />
通常我们都约定一行不能超过80个字符。这是为了代码的可读性,尤其是一行中的字符可能会接触到窗口边缘。在Emacs,自动地插入或者删除换行符称为''filling''。我们可以用 '''M-q''' 重整当前的段落(重新分配换行符,删除段落中多余的空格和tab键)<br />
<br />
字符和单词可以分别通过 '''C-t''' 和 '''M-t''' 进行交换。比如: <code>Hello World!</code> → <code>World! Hello</code><br />
<br />
单词的大小写也可以调整。'''M-l''' 把光标处的单词变成小写 (<code>HELLO</code> → <code>hello</code>); '''M-u''' 把光标处的单词变成大写(<code>hello</code> → <code>HELLO</code>), '''M-c''' 把光标处的单词的第一个字母变成大写,并把后面的变成小写(<code>hElLo</code> → <code>Hello</code>).<br />
<br />
===移除,召回和区域===<br />
一个''区域''(region)是指在两个位置之间的一段字。其中一个位置被称为''标记''(mark),另一个是光标。'''C-<SPC>'''用来设置标记的位置,紧接着就可以通过移动光标来创造一个区域。在GNU Emacs 23.1及以后的版本中,这个区域默认是可见的。有许多命令是针对区域的,其中最常用的就是''kill''命令。<br />
<br />
在Emacs中,剪切和粘贴分别对应的命令叫做''kill''和''yank''。许多删除多个字符的命令(包括上面提到的'''C-k'''和'''M-d'''命令)实际上是把文字剪切下来,附加到一个叫''kill-ring''的地方。kill-ring 就是一个被删掉的文字的列表。在默认情况下,kill-ring会保存最多60次删除记录。连续的删除会连在一起。<br />
<br />
'''C-w''' 和 '''M-w''' 可以用来删除或复制一个区域。<br />
<br />
要想把删掉的文字插入进来(也就是'yanking'),可以用'''C-y'''命令。'''C-y''' 可以连续用好多次来重复插入。按刚刚所讲,之前删除的文字会排成一个列表,但是'''C-y'''只能获取列表中的第一个,也就是最后删掉的一个。再之前删掉的可以通过'''M-y'''来获取。它会把'''C-y'''刚刚插入的文字用再早删除的文字替换掉。'''M-y''' 必须紧跟着'''C-y'''命令执行,可以执行很多次以遍历kill-ring。<br />
<br />
===查找和替换===<br />
在文本编辑中进行字符串查找是很常见的任务。按'''C-s'''可以正向搜索,按'''C-r‘’‘则可以反向搜索。这些命令提示要搜索的字符串。搜索是增量的,你再次按键时会显示下一个匹配的位置,并且可以使用'''C-s’‘’向前或者使用'''C-r‘’‘向后。找到匹配结果之后,可以按下'''<RET>'''结束搜索。另外,如果你想回到发起搜索的位置,可以使用'''C-g'''。<br />
<br />
一旦搜索完成(不是由'''C-g'''之类的指令引起),当前搜索的字符串将会作为下一次搜索的默认参数。使用’‘’C-s C-s'''或者'''C-r C-r'''可以达到这样的效果。<br />
<br />
I-search 有一些有用的命令,使用'''M-e'''来编辑当且搜索区域,使用'''M-c'''来触发大小写敏感匹配。<br />
<br />
正则表达式搜索除了指令不同之外,其他方面和以上都相同。使用'''C-M-s'''或者'''C-M-r'''来使用正则表达式搜索。相应地,用'''C-s'''和'''C-r'''可以前后移动,和普通的搜索没什么两样。<br />
<br />
除了搜索之外,进行字符串替换也是有必要的。原始文本和替换文本都会有提示,替换的时候也会有提示。尽管有很多选项提供(按'''?'''可以了解完整的选项),最常用的还是'''y'''(进行替换),'''n'''(跳过),以及'''!'''(替换当前及之后所有匹配)。<br />
<br />
===缩进和前缀参数===<br />
Indentation is usually performed with either '''<TAB>''', to indent a single line, or with '''C-M-\''', to indent a region.<br />
<br />
Exactly how text is indented usually depends on the ''major-mode'' which is active. Major-modes often define indentation styles specialising in indenting a certain type of text. (See [[Emacs#Modes|Modes]] for more information.)<br />
<br />
In some cases, a suitable major-mode may not exist for a file type, in which case, manual indentation may be necessary. Create a region (see [[Emacs#Killing, yanking and regions|Killing, yanking and regions]]) then perform indentation with '''C-u <n> C-x <TAB>''' (where '<n>' is the number of columns which the text within the region should be indented). For example:<br />
<br />
Increase the region's indentation by four columns:<br />
<br />
C-u 4 C-x <TAB><br />
<br />
Decrease the region's indentation by two columns.<br />
<br />
C-u -2 C-x <TAB><br />
<br />
{{Note|The trick behind this is '''C-u''', which corresponds to the 'universal-argument' command. Providing a 'universal-argument' is a way to provide more information to a command (this information is referred to as a 'prefix argument'). In this case, we provided the amount of indentation desired to the command invoked by '''C-x <TAB>'''. Without providing an argument, '''C-x <TAB>''' will only increase indentation by 1 column.}}<br />
<br />
===窗口和外框架===<br />
Emacs的设计是可以同时方便地编辑多个文件。这是通过把Emacs的接口分成三个层次来实现的,即buffer(之前介绍过了),''window''和''frame''。<br />
<br />
''window'' 是显示buffer的一个viewport(社区)。一个window一次只能显示一个buffer。但是一个buffer可以在多个window中显示。在窗口下面有一个''mode-line'',它用于显示当前buffer的信息。<br />
<br />
''frame'' 是Emacs的一个"窗口"(这是标准的术语。比如,'窗口'是现代桌面的称谓),它包含了标题栏,菜单栏,还有一个或多个'window'(这是Emacs的术语,比如上面提到的'window')。<br />
<br />
从现在起,这些Emacs中存在的名词的定义就可以使用了。<br />
<br />
要把window水平分隔和垂直分隔,分别使用'''C-x 2'''和'''C-x 3'''。这种效果其实就是在当前frame中开户另外一个window。要在多个window中循环切换,使用'''C-x o'''。<br />
<br />
与分隔一个window相反的是删除window。要删掉当前window,使用'''C-x 0''',要删掉除了当前window之外的其它window,使用'''C-x 1'''。<br />
<br />
和window一样,创建和删除frame也是可以的。'''C-x 5 2'''会创建一个frame,'''C-x 5 0'''会删除当前的frame,'''C-x 5 1'''会删除除了当前frame之外的其它frame。<br />
<br />
{{注意|这些命令不影响buffer。比如删除一个window并不会删除在window中显示的buffer。}}<br />
<br />
===获得帮助===<br />
Emacs在设计的时候就自文档化了。比如,要查看一个命令的名字或者它的键的绑定,Emacs提供了很多帮助信息。下面是列出来的最有用的一些帮助命令:<br />
<br />
'''C-h t''' 启动Emacs官方教程<br />
<br />
'''C-h b''' 列出来所有的有效键绑定<br />
<br />
'''C-h k''' 查找一个键被绑定在了哪个命令上<br />
<br />
'''C-h w''' 查找一个命令被绑定在了哪些键上<br />
<br />
'''C-h a''' 查找一个匹配一段描述的命令<br />
<br />
'''C-h m''' 显示当前激活的所有模式的信息<br />
<br />
'''C-h f''' 显示给定函数的描述信息<br />
<br />
===模式===<br />
一个Emacs模式是用Emacs Lisp语言写的一个控制相关缓冲区行为的扩展。一般来说,它给编辑文本提供缩进,语法高亮和键绑定的功能。复杂的模式可以把Emacs变成一个完美的IDE (Integrated Development Environment). Emacs 一般会使用一个文件的扩展来确定应该加载那个模式。<br />
<br />
一些编写shell脚本比较有用的模式有sh-mode, line-number-mode 和 column-number-mode。它们可以并行地通过下面的方式激活:<br />
<br />
'''M-x sh-mode <RET>'''<br />
<br />
'''M-x column-number-mode <RET>'''<br />
<br />
line-number-mode 默认是激活的,它可以通过下面的命令来打开/关闭:<br />
<br />
'''M-x line-number-mode <RET>'''<br />
<br />
sh-mode 是一个 ''major-mode''. Major-modes 调整Emacs,并且经常提供了一些特定的命令来编辑某种类型的文本。一个缓冲区只能激活一种major-mode。除了支持语法高亮和缩进,sh-mode还定义了几条命令来帮助快速开发shell脚本。下面是其中的几条:<br />
<br />
'''C-c (''' 插入一个函数定义<br />
<br />
'''C-c C-f''' 插入一个for循环<br />
<br />
'''C-c TAB''' 插入一条if语句<br />
<br />
'''C-c C-w''' 插入一个while循环<br />
<br />
'''C-c C-l''' 插入一个从1到n的有下标的循环<br />
<br />
'line-number-mode' 和 'column-number-mode' 是 ''minor-modes''. Minor-modes 可以用来扩充major-mode的功能,多个minor-mode可以同时激活。<br />
<br />
==提示和技巧==<br />
前面的部分给出了基本编辑命令的概述,没有给出Emacs的一个指示。这个部分讲述一些高级的技巧和功能。<br />
<br />
===TRAMP===<br />
TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入一个文件名,输入特定的格式就可以使用TRAMPP。比如:<br />
<br />
在打开{{ic|/etc/hosts}}文件之前提示输入root的密码以获取root权限:<br />
<br />
C-x C-f /su::/etc/hosts<br />
<br />
要通过SSH使用'myuser'用户名登录'myhost'主机并打开文件{{ic|~/example.txt}}:<br />
<br />
C-x C-f /ssh:myuser@myhost:~/example.txt<br />
<br />
TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。<br />
<br />
===键盘宏和寄存器===<br />
这一部分会提供一个实用的指南来使用一些更强大的编辑特性。也就是“键盘宏”和“寄存器”。<br />
<br />
我们的目标是产生一个字符列表和它们在这个列表中对应的位置。虽然这可以通过手工格式化来完成,但是这样会很慢而且容易出错。如果我们采用一些Emacs更高级的编辑功能却可以起到四两拨千斤的功效。在介绍这个方法之前,需要先了解一些技术背后的细节。<br />
<br />
要介绍的第一个特性就是''寄存器''。寄存器的功能是用来保存和获取各种各样的数据。每个寄存器用一个字母来命名,这个字母就是用来调用这个寄存器的。<br />
<br />
另一个要介绍的就是''键盘宏''。一个键盘宏存储了一个命令序列以便以后可以重复使用。下面就一步一步地讲解这个方法。<br />
<br />
首先我们从一个包含如下字符的缓冲区开始:<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
通过`number-to-register' 命令 ('''C-x r n''')我们来准备一个寄存器,把数字'0'存储在寄存器'k'中:<br />
<br />
C-x r n k<br />
<br />
当光标在缓冲区开头的时候,开始录制键盘宏 ('''C-x (''') 然后开始对字符串进行格式化:<br />
<br />
C-x ( C-f M-4 .<br />
<br />
插入 ('''C-x r i''') 然后将寄存器'k'加1 ('''C-x r +''') 。开头的 ('''C-u''') 命令是用来在插入文字之后让光标移到插入的文字后面:<br />
<br />
C-u C-x r i k C-x r + k<br />
<br />
最后我们来插入一个回车来结束格式化。Emacs可以重复以上过程,从我们定义键盘宏的位置开始,直到最后一个字符。'''C-x e'''命令停止宏的录制并开始执行这段宏。开头的 '''M-0''' 命令是用来让宏在出错的时候停下来,这样在它走到这行的结尾就会停下来。<br />
<br />
<RET> M-0 C-x e<br />
<br />
下面是结果:<br />
<br />
A....0<br />
B....1<br />
C....2<br />
[...]<br />
x....49<br />
y....50<br />
z....51<br />
<br />
===正则表达式===<br />
From the Emacs Manual: "A regular expression, or ''regexp'' for short, is a pattern that denotes a (possibly infinite) set of strings." This section will not go into any detail regarding regular expressions themselves (as there is simply too much to cover). It will however provide a quick demonstration of their power. See [http://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html#Regular-Expressions Regular Expressions] section in the Emacs Manual for further reading.<br />
<br />
Given the same scenario presented above: A list of characters which are to be formatted to represent their respective position in the list. (see [[Emacs#Keyboard macros and registers|Keyboard macros and registers]]). Again, starting with a buffer containing.<br />
<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
At the beginning of the buffer, use '''C-M-%''' (if the key-sequence is difficult to perform, it may be more comfortable to use '''M-x query-replace-regexp'''). At the prompt:<br />
\(.\)<br />
which simply matches one character. Then, when prompted for the replacement:<br />
\1....\#^J<br />
{{Note|'^J' represents where a newline should be placed, it should not be entered into the prompt. The newline must instead be inserted literally using '''C-q C-j'''.}}<br />
The replacement expression reads: "Insert the matched text between the first set of parentheses (in this case, a single character), followed by 4 periods then insert an automatically incremented number followed by a newline.<br />
<br />
Finally, press '''!''' to apply this across the entire buffer. All of the formatting that was performed in the previous section was performed with a single regexp replacement.<br />
<br />
==定制==<br />
Emacs能通过~/.emacs或者'''M-x customize'''来定制。本段落将着眼于手动定制 ~/.emacs,并且提供了一些常用配置的样例。配置命令提供了一个适应的途径,通过它你能够渐渐熟悉Emacs。<br />
<br />
这里的所有例子都能在Emacs中奏效。比如,在Emacs中计算表达式:<br />
'''C-M-x''' 同时指到任何需要求值的地方。<br />
<br />
或者<br />
<br />
'''C-x C-e''' 指到最后的“)”。<br />
<br />
用'y'和'n'来代替频繁地输入'yes’和'no‘是一个好的方法:<br />
<br />
(defalias 'yes-or-no-p 'y-or-n-p)<br />
<br />
取消光标闪烁:<br />
<br />
(blink-cursor-mode -1)<br />
<br />
类似地,开启上一节提到的列号模式:<br />
<br />
(column-number-mode 1)<br />
<br />
它们两者之间的相似不是偶然:光标闪烁模式和列号模式都是'副参模式',按照规则,'副参模式’能通过正负值来设置。如果参数省略,'副参模式'将被开/关。<br />
<br />
这里有其他一些'副参模式'的例子,下面的参数将会关闭滚动栏、菜单栏、工具栏。<br />
(scroll-bar-mode -1)<br />
(menu-bar-mode -1)<br />
(tool-bar-mode -1)<br />
<br />
变量'auto-mode-alist'修改之后能够改变默认的“主参模式”。下面的例子把'.tut'和'.req'修改成了'.text-mode'。<br />
<br />
(setq auto-mode-alist<br />
(append<br />
'(("\\.tut$" . text-mode)<br />
("\\.req$" . text-mode))<br />
auto-mode-alist))<br />
<br />
Settings can also be applied on a per-mode basis. A common method for this is to add a function to a ''hook''. For example, to force indentation to use spaces instead of tabs, but only in text-mode:<br />
<br />
(add-hook 'text-mode-hook (lambda () (setq indent-tabs-mode nil)))<br />
<br />
Similarly, to only use spaces for indentation everywhere:<br />
<br />
(setq-default indent-tabs-mode nil)<br />
<br />
Keybindings can be adjusted in two ways. The first of which is 'define-key'. 'define-key' creates a keybinding for a command but only in one mode. The example below will make '''F8''' delete any whitespace from the end of each line of a 'text-mode' buffer:<br />
<br />
(define-key text-mode-map (kbd "<f8>") 'delete-trailing-whitespace)<br />
<br />
The other method is 'global-set-key'. This is used to bind a key to a command everywhere. To bind 'query-replace-regexp' ('''C-M-%''') to '<f7>'.<br />
<br />
(global-set-key (kbd "<f7>") 'query-replace-regexp)<br />
<br />
Binding a command to an alternate key does not replace any existing bindings. Which is to say, 'query-replace-regexp' would be bound to both '''F7''' and '''C-M-%''' after the above example.<br />
<br />
Almost anything within Emacs can be configured. Browsing through the [http://emacswiki.org/ Emacs Wiki] should give a solid place to start.<br />
<br />
<br />
=== Multiple configurations ===<br />
<br />
You can use several configurations and tell Emacs to load one or the other.<br />
<br />
For example, let's define two configuration files.<br />
<br />
{{hc|.emacs|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/plugins" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
This is the full configuration we load for the daemon. But the ''plugins'' file is huge and slow to load. If we want to spaqn a new Emacs instance that does not need the ''plutings'' features, it can be cumbersome to load it everytime in the long time.<br />
<br />
{{hc|.emacs-light|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
And now we launch Emacs with<br />
emacs -q -l ~/.emacs-light<br />
You can create an alias to ease the call.<br />
<br />
=== Loading extensions ===<br />
<br />
You can load extensions using the ''require'' function. For instance<br />
(require 'mediawiki)<br />
<br />
If you try using the same configuration file on a machine where mediawiki is not installed, Emacs will primpt for an error. Besides, all extension-specific code would be parsed for nothing.<br />
<br />
The trick is to test the return value of ''require'':<br />
<br />
(if (require 'mediawiki nil t)<br />
(progn<br />
(setq mediawiki-site-alist '(<br />
("ArchLinux" "https://wiki.archlinux.org/" "UserName" "" "Main Page")<br />
)<br />
)<br />
(setq mediawiki-mode-hook<br />
(lambda ()<br />
(visual-line-mode 1)<br />
(turn-off-auto-fill)<br />
))<br />
)) <br />
<br />
=== Local and custom variables ===<br />
<br />
You can define variables in your configuration file that can be later one modified locally for a file.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation")<br />
<br />
Now in any file you can define local variables in two ways:<br />
* On the very first line, write<br />
// -*- my-compiler:g++; mode:c++ -*-<br />
* If you cannot (or do not want to) write this on the first line, you can put it at the end:<br />
// Local Variables:<br />
// my-compiler: g++<br />
// mode: c++<br />
// End:<br />
<br />
Note that the beginning characters need to be comments for the current language, that's why here we used two backslashes for C++. For Elisp you would use<br />
;; -*- mode:emacs-lisp -*-<br />
<br />
There is two functions that may help you in defining the variables: ''add-file-local-variable'' and ''add-file-local-variable-prop-line''.<br />
<br />
Finally, custom variable are considered insecure by default. If you try to open a file that contains local variable redefining insecure custom variables, Emacs will ask you for confirmation.<br />
<br />
If you know what you are doing, you can declare the variable as secure, thus removing the Emacs prompt for confirmation. You need to specify a predicate that any new value has to verify so that it can be considered safe.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)<br />
<br />
In the previous example, if you attempt to set anything else than a string, Emacs will consider it insecure.<br />
<br />
=== Custom colors and theme ===<br />
<br />
Colors can be easily customized using the ''face'' facility.<br />
(set-face-background 'region "color-17")<br />
(set-face-foreground 'region "white")<br />
(set-face-bold-p 'font-lock-builtin-face t ) <br />
<br />
You can have let Emacs tell you the name of the face where the point is. Use the ''customize-face'' function for that. The facility will show you how to set colors, bold, underline, etc.<br />
<br />
Emacs in console can handle 256 colors, but you will have to use an appropriate terminal for that. For instance URxvt has support for 256 colors. You can use the ''list-colors-display'' for a comprehensive list of supported colors. This is highly terminal-dependent.<br />
<br />
=== SyncTeX support ===<br />
<br />
Emacs is definitely one of the most powerful LaTeX editor. This is mostly due to the fact you can adapt or create a LaTeX mode to fit your needs best.<br />
<br />
Still, there might be some challenges, like SyncTeX support. First you need to make sure your TeX distribution has it. If you installed TeX Live manually, you may need to install the ''synctex'' package.<br />
# umask 022 && tlmgr install synctex<br />
<br />
SyncTeX support is viewer-dependent. Here we will use Zathura as an example, so the code needs to be adapted if you want to use another PDF viewer.<br />
<br />
(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" <br />
"PDF Viewer for TeX documents. You may want to fork the viewer<br />
so that it detects when the same document is launched twice, and<br />
persists when Emacs gets closed.<br />
<br />
Simple command:<br />
<br />
zathura --fork<br />
<br />
We can use<br />
<br />
emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'<br />
<br />
to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."<br />
:safe 'stringp)<br />
<br />
Here we define our custom variable. If you are using AucTeX or Emacs default LaTeX-mode, you will have to set the viewer accordingly.<br />
<br />
Now open a LaTeX source file with Emacs, compile the document, and launch the viewer. Zathura will spawn. If you press {{ic|Ctrl+Left click}} Emacs should place the point at the corresponding position.<br />
<br />
== Documentation ==<br />
<br />
You may find yourself overwhelmed by the amount of Emacs features. You may find it difficult to know how to use Emacs Lisp to customize your favorite modes, or even to create your own modes / packages. Thankfully Emacs takes a strong point to auto-documenting everything: its internals, current configuration, bindings, etc. Almost everything is documented.<br />
<br />
=== Contextual help ===<br />
<br />
Emacs is self-documenting by design. As such, a great deal of information is available to determine the name of a specific command or its keybinding, for example. The following is a listing of some of the most helpful of these:<br />
<br />
'''C-h a''' Find a command matching a description.<br />
<br />
'''C-h b''' List all active keybindings.<br />
<br />
'''C-h f''' Describe the given function.<br />
<br />
'''C-h k''' Find which command a key is bound to.<br />
<br />
'''C-h m''' Display information regarding the currently active modes.<br />
<br />
'''C-h t''' Start the Emacs tutorial.<br />
<br />
'''C-h v''' Describe the given variable.<br />
<br />
'''C-h w''' Find which key(s) a command is bound to.<br />
<br />
=== The manuals ===<br />
<br />
If you really want to master Emacs, the most recommanded source of documentation remains the official manuals:<br />
* Emacs: the complete Emacs user manual.<br />
* Emacs FAQ.<br />
* Emacs Lisp Intro: if you never used any programming language before.<br />
* Elisp: if you are already familiar with a programming language.<br />
<br />
You can access it as PDFs from [http://www.gnu.org/software/emacs/manual/ GNU.org] or directly from Emacs itself thanks to the embedded 'info' reader: '''C-h i'''. Press '''m''' to choose a book.<br />
<br />
Some users prefer to read books using 'info' because of its convenient shortcuts, its paragraphs adapting to window width and the font adapted to current screen resolution. Some find it less irritating to the eyes. Finally you can easily copy content from the book to any Emacs buffer, and you can even execute Lisp code snippets directly from the examples.<br />
<br />
You may want to read the '''Info''' book to know more about it: '''C-h i m info <RET>'''.<br />
Press '''?''' while in info mode for a quick list of shortcuts.<br />
<br />
== 拓展模块 ==<br />
<br />
虽然Emacs包含了成百上千种模式(mode),库和其它扩展,还有更多的扩展来增强Emacs。大多数扩展会详细说明安装它的时候要对~/.emacs作什么改动。这些说明一般会在一个elisp源文件开头的注释中,或者在一个README中(如果这个扩展包含了多个源文件)。<br />
<br />
在'community'仓库中有很多流行的扩展,更多的扩展还放在了[[AUR]]。这些软件包的名字有一个'emacs-'前缀(比如emacs-lua-mode)。在很多情况下,在安装的过程会显示怎样修改~/.emacs以安装该扩展到Emacs中。<br />
<br />
想知道怎样激活一个不在上面提到的地方的扩展,查看[http://emacswiki.org/ Emacs Wiki]中的相应页面,一般会提供一个配置的例子。Emacs Wiki也是一个寻找扩展的优秀资源。<br />
<br />
你也可以使用[http://tromey.com/elpa/ Emacs Lisp Package Archive (ELPA)] 来自动安装软件包。打开那个网站看说明。ELPA已经包括在了Emacs24中;它已经作为Emacs生态系统中的一部分了。<br />
<br />
== 疑难杂症 ==<br />
<br />
===彩色输出的问题===<br />
Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。<br />
<br />
在{{ic|~/.emacs}}中加入下面的代码解决这个问题:<br />
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)<br />
<br />
===菜单显示为空===<br />
一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550541 Debian bug report] 有一个应对措施。<br />
<br />
=== X 窗口下的字符显示问题 ===<br />
当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 {{pkg|xorg-fonts-75dpi}} 或者 {{pkg|xorg-fonts-100dpi}} 并且重启X窗口。<br />
<br />
=== 启动速度慢 ===<br />
启动速度慢经常是由下面两种情况引起的。<br />
<br />
要确定是哪种情况,这样打开Emacs:<br />
<br />
$ emacs -q<br />
<br />
如果Emacs还是启动很慢,则是[[Emacs#Incorrect network configuration|错误的网络配置]]。如果不是,则可以确定是[[Emacs#Init file loads slowly|.emacs的问题]]。<br />
<br />
====错误的网络配置====<br />
<br />
当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'[[Configuring_network#Set_the_hostname|set the hostname]]' 了解更多内容。<br />
<br />
====初始化文件加载慢====<br />
<br />
一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:<br />
<br />
(require 'anything)<br />
<br />
你应该这样:<br />
<br />
(autoload 'anything "anything" "Select anything" t)<br />
<br />
=== 不能打开配置文件: ... ===<br />
<br />
这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:<br />
<br />
(add-to-list 'load-path "/path/to/directory/")<br />
<br />
当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:<br />
<br />
(add-to-list 'load-path "/usr/share/emacs/site-lisp")<br />
<br />
如果手动编译Emacs,记住默认的前缀是'/usr/local'。<br />
<br />
=== Dead-accent keys problem: '<dead-acute> is undefined' ===<br />
<br />
Searching about this bug on Google, we find this link:<br />
http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html<br />
<br />
Explaining the problem: in recent versions of<br />
b72<br />
Emacs, the normal way to use accent keys doesn't work as expected. Trying to accent a word like 'fiancé' will produce the message above.<br />
<br />
A way to solve it is just put the line above on your startup file, {{ic|~/.emacs}}:<br />
<br />
(require 'iso-transl)<br />
<br />
And no, it isn't a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):<br />
<br />
:''It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be<br />
a3b<br />
classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. ''<br />
<br />
=== C-M-% and some other bindings do not work in emacs nox ===<br />
<br />
This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:<br />
* either use the graphical version,<br />
* or change the binding to a supported one.<br />
<br />
Example:<br />
{{hc|.emacs|<br />
(global-set-key (kbd "C-M-y") 'query-replace-regexp)<br />
}}<br />
<br />
=== Emacs client gets stuck when switching back to it ===<br />
<br />
If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an '''M-x''' for instance), then all other instance will wait for it to finish. Press '''C-g''' to cancel any input to make sure this Emacs session is not blocking.<br />
<br />
=== Emacs-nox output gets messy ===<br />
<br />
When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal.<br />
There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.<br />
<br />
Graphical Emacs does not suffer from this issue.<br />
<br />
=== Shift + Arrow keys not working in emacs within tmux ===<br />
<br />
First you must enable xterm-keys in your [[tmux]] config.<br />
{{hc|.tmux.conf|<br />
setw -g xterm-keys on<br />
}}<br />
<br />
But, this will break other key combinations. To fix them, put the following in your emacs config.<br />
{{hc|.emacs|<br />
;; handle tmux's xterm-keys<br />
;; put the following line in your ~/.tmux.conf:<br />
;; setw -g xterm-keys on<br />
(if (getenv "TMUX")<br />
(progn<br />
(let ((x 2) (tkey ""))<br />
(while (<&#61; x 8)<br />
;; shift<br />
(if (&#61; x 2)<br />
(setq tkey "S-"))<br />
;; alt<br />
(if (&#61; x 3)<br />
(setq tkey "M-"))<br />
;; alt + shift<br />
(if (&#61; x 4)<br />
(setq tkey "M-S-"))<br />
;; ctrl<br />
(if (&#61; x 5)<br />
(setq tkey "C-"))<br />
;; ctrl + shift<br />
(if (&#61; x 6)<br />
(setq tkey "C-S-"))<br />
;; ctrl + alt<br />
(if (&#61; x 7)<br />
(setq tkey "C-M-"))<br />
;; ctrl + alt + shift<br />
(if (&#61; x 8)<br />
(setq tkey "C-M-S-"))<br />
<br />
;; arrows<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))<br />
;; home<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))<br />
;; end<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))<br />
;; page up<br />
(define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))<br />
;; page down<br />
(define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))<br />
;; insert<br />
(define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; delete<br />
(define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; f1<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))<br />
;; f2<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))<br />
;; f3<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))<br />
;; f4<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))<br />
;; f5<br />
(define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))<br />
;; f6<br />
(define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))<br />
;; f7<br />
(define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))<br />
;; f8<br />
(define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))<br />
;; f9<br />
(define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))<br />
;; f10<br />
(define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))<br />
;; f11<br />
(define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))<br />
;; f12<br />
(define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))<br />
;; f13<br />
(define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))<br />
;; f14<br />
(define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))<br />
;; f15<br />
(define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))<br />
;; f16<br />
(define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))<br />
;; f17<br />
(define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))<br />
;; f18<br />
(define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))<br />
;; f19<br />
(define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))<br />
;; f20<br />
(define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))<br />
<br />
(setq x (+ x 1))<br />
))<br />
)<br />
)<br />
}}<br />
<br />
== 替代方案 ==<br />
<br />
有很多Emacs的实现。GNU/Emacs 可能是最受欢迎的了。<br><br />
更轻量的兼容性较好的Emacs可以在Arch仓库或在[https://aur.archlinux.org/ AUR]中找到。<br />
<br />
=== mg ===<br />
<br />
mg(原来叫MicroGnuEmacs),是用C语言实现的轻量级Emacs。<br />
<br />
可以从{{ic|community}中安装mg<br />
# pacman -S mg<br />
或者从官方网站[http://homepage.boetes.org/software/mg/ page]中下载源代码。<br />
<br />
=== zile ===<br />
<br />
引用官方网站[https://www.gnu.org/software/zile/ page]的描述,"GNU Zile is a lightweight Emacs clone. Zile is short for Zile Is Lossy Emacs. Zile has been written to be as similar as possible to Emacs; every Emacs user should feel at home.",意思是'GNU Zile'是一个轻量级的Emacs的克隆。Zile是'Zile Is Lossy Emacs'的缩写。<br />
Zile的实现与Emacs如此相似以至于每个Emacs用户使用Zile一定会有一种宾至如归的感觉。<br />
<br />
zile 可以在{{ic|extra}}中找到<br />
<br />
# pacman -S zile<br />
<br />
最新的tarball可以在GNU的官方源[http://ftp.sh.cvut.cz/MIRRORS/gnu/pub/gnu/zile/ mirrors]中找到。<br />
<br />
=== uemacs ===<br />
<br />
uemacs 是由Linus Torvalds定制的微型Emacs版本。<br />
它可以在 [https://aur.archlinux.org/ AUR] 的 [https://aur.archlinux.org/packages.php?ID=31502 uemacs]中找到。<br />
<br />
== 资源 ==<br />
* [http://www.gnu.org/software/emacs/ GNU Emacs home page]<br />
* [http://www.gnu.org/software/emacs/manual/emacs.html GNU Emacs Manual]<br />
* [http://www.emacswiki.org/cgi-bin/wiki/ Emacs Wiki]<br />
* [http://wikemacs.org WikEmacs - a more readable, but less complete Emacs Wiki]<br />
* [http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Useful introduction to Emacs and its shortcuts]<br />
* [http://www.dina.kvl.dk/~abraham/religion/ The Church of Emacs]<br />
* [http://repo.or.cz/w/emacs.git/blob/HEAD:/etc/refcards/refcard.pdf Official reference card]</div>HelloCodehttps://wiki.archlinux.org/index.php?title=Emacs_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=349118Emacs (简体中文)2014-12-08T14:31:54Z<p>HelloCode: </p>
<hr />
<div>[[Category:Text editors (简体中文)]]<br />
[[de:Emacs]]<br />
[[en:Emacs]]<br />
[[fr:Emacs]]<br />
[[ja:Emacs]]<br />
[[sr:Emacs]]<br />
{{TranslationStatus (简体中文)|Emacs|2014-12-08|229169}}<br />
{{Translateme (简体中文)}}<br />
[[Wikipedia:Emacs|Emacs]]是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在[[Wikipedia:Emacs Lisp|Emacs Lisp]]解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和[[vim]]比较。<br />
<br />
{{Note|入门建议直接使用starterkit扩展。本文档实际帮助不大}}<br />
<br />
== 安装 ==<br />
Emacs有众多变体发行版本(有时候称作''emacsen''). 最常见的莫过于 [http://www.gnu.org/software/emacs/ GNU Emacs],在[[Official repositories]]可以找到<br />
<br />
$ pacman -S emacs<br />
<br />
如果你总是在终端下工作的话,你可能会选择{{Pkg|emacs-nox}}。这是一个没有GTK+依赖的版本(也没有声音支持)。<br />
<br />
终端版Emacs存在以下问题:它支持更少的颜色和更少的字体控制功能(缺少在线控制字体大小、在一篇文档中使用多种字体等功能)。而且对于一些需要高级特性的功能比如Speedbar或者GUD(调试环境),它也不支持。另外在控制复杂的外观(face)时,emacs-nox比Emacs要慢。<br />
<br />
如果你想体验Emacs的所有扩展功能而不用装一堆依赖的话,你可以使用PKGBUILD来按你的需求定制Emacs。不使用{{ic|gtk3}}可以让Emacs避免使用gconf。图像和声音的支持也可以去除。在Emacs的源代码目录下运行{{ic|./configure --help}}可以看看有哪些配置选项。<br />
{{hc|PKGBUILD|<nowiki><br />
# ...<br />
./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \<br />
--localstatedir=/var --with-x-toolkit=gtk2 --with-xft \<br />
--without-gconf --without-sound<br />
# ...<br />
</nowiki>}}<br />
<br />
另外一个常见的变体就是{{Pkg|xemacs}}.<br />
<br />
== 快速入门 ==<br />
一般印象是Emacs十分复杂,学习曲线陡峭,但很多资深学习者并不这样认为,反而认为其非常易懂和可定制。因为其源码和配置文件语义化程度较高。简单了解下自定义和高扩展带来的好处花不了多少时间。何况还有很多成熟的功能拓展模块,很方便添加,可以让Emacs为任何文本编辑的需求配置强大的环境。<br />
<br />
Emacs自带一个入门教程,你可以点击欢迎界面上的第一个链接来打开它; 或者从菜单栏中选择''Help->Emacs Tutorial'',或者按'F1'键然后按't'. 我们设计这篇文章来为你在Emacs入门学习中提供额外的资源。<br />
<br />
Emacs也包括一系列引用链接,既有适合初学者的内容,也有骨灰级玩家所喜爱的.参见{{ic|/usr/share/emacs/<version>/etc/refcards/}} (将<version>换成你的emacs版本).<br />
<br />
===运行Emacs===<br />
<br />
在启动Emacs之前,你要先学会怎么关闭它(尤其是你要在终端里运行它的话):用{{ic|Ctrl+x}}{{ic|Ctrl+c}}来关闭它。<br />
<br />
====图形界面下打开方式====<br />
图形界面下可以直接点击图标打开。<br />
<br />
====虚拟终端下的常见方式====<br />
打开Emacs:<br />
<br />
$ emacs<br />
<br />
不打开图形界面,直接在终端中运行:<br />
<br />
$ emacs -nw<br />
<br />
也可以直接用下面的命令来打开一个文件:<br />
<br />
$ emacs filename.txt<br />
<br />
=====去掉颜色=====<br />
默认的emacs会带有颜色主题,如果不需要,可以关闭之:<br />
<br />
$ emacs -nw --color=no<br />
<br />
<br />
====作为守护进程====<br />
Emacs由于每次启动都需要加载大量自定义的配置文件,所以打开时候会有点慢。从Emacs23开始, Emacs可以以守护进程的形式运行,这样每个用户都可以链接到Emacs。以守护进程运行Emacs:<br />
<br />
$ emacs --daemon<br />
<br />
你可能在启动时打开一个守护进程,然后再将守护进程链接到窗口。另外,也可以将图形和终端客户端同时链接到守护进程上,这样启动图形界面速度就很快了。<br />
<br />
如果你仅仅想链接到守护进程,用下面的命令(注意,在桌面环境下这个命令会打开一个图形客户端,而在像tty这种命令行下,它会打开一个命令行版的emacs):<br />
<br />
$ emacsclient<br />
<br />
如果你想在桌面环境下打开一个命令行版的emacs,使用下面的命令:<br />
<br />
$ emacsclient -t<br />
<br />
另外,你可以在后面加上 {{ic|-a ""}} 参数.<br />
现在,你第一次使用这个命令时,它会把emacs作为守护进程来启动,它会留在后台以加快以后的启动速度(也会记住缓冲区).<br />
<br />
更聪明点,你可以在.bashrc中加上下面的别名:<br />
{{bc|1=<br />
alias em='emacsclient -t -a ""' #在终端中开启emacs<br />
alias emc='emacsclient -nc -a ""' #启动emacs图形界面<br />
EDITOR='emacsclient -a ""'<br />
}}<br />
<br />
在[[xfce]]桌面环境中,如果你想使用 emacsclient -c 来代替 emacs %f 打开一个新文件, 你可以修改你的 /usr/share/applications/emacs.desktop 文件,把下面这一行<br />
<br />
$ Exec=emacs %f<br />
<br />
修改为<br />
<br />
$ Exec=emacsclient -c<br />
<br />
使用这种方法,每次你打开一个文件时就只会启动客户端,因此速度非常快!<br />
<br />
===基本术语和约定===<br />
Emacs使用一些刚开始看起来很奇怪的术语和约定,我们会在合适的时候介绍。但是,对于部分术语,我们必须要在前面介绍,因为它们对于使用Emacs来说是非常基础的。<br />
<br />
第一个要介绍的术语是''缓冲区''的概念。一个缓冲区就是Emacs中的数据的一种表示方式,比如,当使用Emacs打开一个文件时,这个文件从磁盘中被读出来,它的内容被存储在了缓冲区里面,它的内容可以在这个缓冲区里面被编辑并且可以重新写进磁盘中。缓冲区中的内容不仅仅可以是文本,也可以是图片和widget。现在,让缓冲区可以显示应用程序的工作正在进行!换个角度思考,在磁盘中数据是以文件形式保存的,而在Emacs中,数据是以缓冲区的形式存在的。<br />
<br />
在Emacs中,对于按键组合的约定你可能很陌生。比如:<br />
<br />
'''C-x''' 代表 Ctrl-x<br />
<br />
'''M-x''' 代表 Meta-x<br />
<br />
{{注意|'Meta'一般代表Alt键,也可以用Esc键替代。}}<br />
<br />
举个例子,退出Emacs使用下面的按键组合'''C-x C-c'''。这个可以读做,"按住Ctrl键再按'x',释放,再按住Ctrl键再按'c'。虽然Emacs提供了一个菜单栏,但是强烈建议学习使用按键组合。这个指南将参考Emacs的按键绑定的约定。<br />
<br />
===移动===<br />
光标移动和其它图形编辑器非常类似,鼠标和方向键可以用来改变光标(在Emacs中称为''点'')的位置。在Emacs中,方向键代表的标准移动命令也有其它辅助的绑定。向前(forward)移动一个字符,使用 '''C-f''',向后(back)移动一个字符,使用'''C-b'''。 '''C-n''' 和 '''C-p''' 分别用于移动到下(next)一行和移动到上(previous)一行。再声明一下,强烈推荐使用组合键而不是使用方向键和鼠标。<br />
<br />
可以想像,Emacs提供了更多的光标高级移动命令,包括移动一个单词和一个句子。 '''M-f''' 表示光标向前移动一个单词, '''M-b''' 表示向后移动一个单词。类似地,'''M-e''' 把光标移动到一个句子的末尾(end), '''M-a''' 移动到句子的开头。<br />
<br />
直到现在,所有的移动命令都是和光标有关的。'''M-<''' 表示把光标移动到缓冲区的开头,和它相反的是 '''M->''', 把光标移动到缓冲区的末尾。要把光标移动到某一特定行,使用'''M-g g'''. '''M-g g''' 会提示输入行号。同样,要移动到一行的开头或者结尾,分别使用'''C-a''' 和 '''C-e'''。<br />
<br />
{{Note|这些命令(实际上是全部命令)的绑定,在不同的模式(mode)中,''稍微''会有不同。然而,覆盖的命令提供不同的功能这种情况很少见。更多信息请看[[Emacs#Modes|Modes]]。}}<br />
<br />
===文件和缓冲区===<br />
Emacs 提供了一系列命令来对文件操作,其中最常用的会在这里详细说明。'''C-x C-f''' 用来打开一个文件(在Emacs中叫做'查找文件')。如果指定的文件不存在,Emacs会打开一个空的缓冲区。保存一个缓冲区会创建一个包含缓冲区内容的文件。'''C-x C-s''' 就是用来保存缓冲区的。要保存一个文件名不一样的缓冲区,使用'''C-x C-w''' (这其实是'write-file'这条命令的助记符), 它会在写入磁盘之前提示输入新文件名。也可以使用'''C-x s'''来保存所有的缓冲区, 如果某个缓冲区在上次保存之后被修改了,则会提示进行哪项操作。<br />
<br />
{{Note|如果指向某个文件的缓冲区还在打开的话,'''C-x C-f''' 是不会重新从磁盘中读取文件的。要从磁盘中重新读取文件,先使用'''C-x k'''关掉缓冲区,再使用'''C-x C-f'''打开文件,或者使用'''M-x revert-buffer'''.}}<br />
<br />
很多互动的命令,比如"find-file" 或者 "write-file" 会在Emacs窗口的底部栏提示输入。这栏称为''minibuffer''。和很多*nix shell一样,minibuffer支持很多基本的操作和TAB补全。按两下'''<TAB>'''可以显示一个补全的选项列表,并且,如果你喜欢,可以用鼠标从列表中选择。minibuffer的补全在很多输入(包括命令和文件名)中都可以用。<br />
<br />
minibuffer也提供一个记住历史的特性。通过'''Up Arrow''' 或者 '''C-p'''可以取得这条命令的上一个条目.<br />
<br />
要在任意时刻退出minibuffer,使用'''C-g'''.<br />
<br />
打开几个文件后,切换缓冲区是非常必要的。打开一个指向那个缓冲区的文件可以切换到那个缓冲区。但是这不是最高效的方法。Emacs提供'''C-x b'''来提示要显示的新缓冲区(这里可以使用TAB补全)。输入一个不存在的缓冲区,则会新建一个空的缓冲区。<br />
<br />
{{Note|要切换到上一个缓冲区,使用'''C-x b <RET>''', 因为上一个缓冲区是默认的缓冲区。}}<br />
<br />
使用'''C-x C-b'''可以显示所有打开缓冲区的列表。如果某个缓冲区不需要使用了,使用'''C-x k'''来关掉它。<br />
<br />
===编辑===<br />
Emacs 内建有很多编辑命令。可能最重要的还没有介绍的是'undo',它的快捷键为 ''C-_'' 或者 ''C-/'' .移动光标的命令通常都有对应的删除字符的命令。例如, '''M-<backspace>''' 可以用来删除一个光标后的词,'''M-d'''可以用来删除光标前面的一个词。删除光标至行尾或者句尾的字符可以分别用'''C-k''' 或者 '''M-k'''。<br />
<br />
通常我们都约定一行不能超过80个字符。这是为了代码的可读性,尤其是一行中的字符可能会接触到窗口边缘。在Emacs,自动地插入或者删除换行符称为''filling''。我们可以用 '''M-q''' 重整当前的段落(重新分配换行符,删除段落中多余的空格和tab键)<br />
<br />
字符和单词可以分别通过 '''C-t''' 和 '''M-t''' 进行交换。比如: <code>Hello World!</code> → <code>World! Hello</code><br />
<br />
单词的大小写也可以调整。'''M-l''' 把光标处的单词变成小写 (<code>HELLO</code> → <code>hello</code>); '''M-u''' 把光标处的单词变成大写(<code>hello</code> → <code>HELLO</code>), '''M-c''' 把光标处的单词的第一个字母变成大写,并把后面的变成小写(<code>hElLo</code> → <code>Hello</code>).<br />
<br />
===移除,召回和区域===<br />
一个''区域''(region)是指在两个位置之间的一段字。其中一个位置被称为''标记''(mark),另一个是光标。'''C-<SPC>'''用来设置标记的位置,紧接着就可以通过移动光标来创造一个区域。在GNU Emacs 23.1及以后的版本中,这个区域默认是可见的。有许多命令是针对区域的,其中最常用的就是''kill''命令。<br />
<br />
在Emacs中,剪切和粘贴分别对应的命令叫做''kill''和''yank''。许多删除多个字符的命令(包括上面提到的'''C-k'''和'''M-d'''命令)实际上是把文字剪切下来,附加到一个叫''kill-ring''的地方。kill-ring 就是一个被删掉的文字的列表。在默认情况下,kill-ring会保存最多60次删除记录。连续的删除会连在一起。<br />
<br />
'''C-w''' 和 '''M-w''' 可以用来删除或复制一个区域。<br />
<br />
要想把删掉的文字插入进来(也就是'yanking'),可以用'''C-y'''命令。'''C-y''' 可以连续用好多次来重复插入。按刚刚所讲,之前删除的文字会排成一个列表,但是'''C-y'''只能获取列表中的第一个,也就是最后删掉的一个。再之前删掉的可以通过'''M-y'''来获取。它会把'''C-y'''刚刚插入的文字用再早删除的文字替换掉。'''M-y''' 必须紧跟着'''C-y'''命令执行,可以执行很多次以遍历kill-ring。<br />
<br />
===查找和替换===<br />
在文本编辑中进行字符串查找是很常见的任务。按'''C-s'''可以正向搜索,按'''C-r‘’‘则可以反向搜索。这些命令提示要搜索的字符串。搜索是增量的,你再次按键时会显示下一个匹配的位置,并且可以使用'''C-s’‘’向前或者使用'''C-r‘’‘向后。找到匹配结果之后,可以按下'''<RET>'''结束搜索。另外,如果你想回到发起搜索的位置,可以使用'''C-g'''。<br />
<br />
一旦搜索完成(不是由'''C-g'''之类的指令引起),当前搜索的字符串将会作为下一次搜索的默认参数。使用’‘’C-s C-s'''或者'''C-r C-r'''可以达到这样的效果。<br />
<br />
I-search 有一些有用的命令,使用'''M-e'''来编辑当且搜索区域,使用'''M-c'''来触发大小写敏感匹配。<br />
<br />
正则表达式搜索除了指令不同之外,其他方面和以上都相同。使用'''C-M-s'''或者'''C-M-r'''来使用正则表达式搜索。相应地,用'''C-s'''和'''C-r'''可以前后移动,和普通的搜索没什么两样。<br />
<br />
除了搜索之外,进行字符串替换也是有必要的。原始文本和替换文本都会有提示,替换的时候也会有提示。尽管有很多选项提供(按'''?'''可以了解完整的选项),最常用的还是'''y'''(进行替换),'''n'''(跳过),以及'''!'''(替换当前及之后所有匹配)。<br />
<br />
===缩进和前缀参数===<br />
Indentation is usually performed with either '''<TAB>''', to indent a single line, or with '''C-M-\''', to indent a region.<br />
<br />
Exactly how text is indented usually depends on the ''major-mode'' which is active. Major-modes often define indentation styles specialising in indenting a certain type of text. (See [[Emacs#Modes|Modes]] for more information.)<br />
<br />
In some cases, a suitable major-mode may not exist for a file type, in which case, manual indentation may be necessary. Create a region (see [[Emacs#Killing, yanking and regions|Killing, yanking and regions]]) then perform indentation with '''C-u <n> C-x <TAB>''' (where '<n>' is the number of columns which the text within the region should be indented). For example:<br />
<br />
Increase the region's indentation by four columns:<br />
<br />
C-u 4 C-x <TAB><br />
<br />
Decrease the region's indentation by two columns.<br />
<br />
C-u -2 C-x <TAB><br />
<br />
{{Note|The trick behind this is '''C-u''', which corresponds to the 'universal-argument' command. Providing a 'universal-argument' is a way to provide more information to a command (this information is referred to as a 'prefix argument'). In this case, we provided the amount of indentation desired to the command invoked by '''C-x <TAB>'''. Without providing an argument, '''C-x <TAB>''' will only increase indentation by 1 column.}}<br />
<br />
===窗口和外框架===<br />
Emacs的设计是可以同时方便地编辑多个文件。这是通过把Emacs的接口分成三个层次来实现的,即buffer(之前介绍过了),''window''和''frame''。<br />
<br />
''window'' 是显示buffer的一个viewport(社区)。一个window一次只能显示一个buffer。但是一个buffer可以在多个window中显示。在窗口下面有一个''mode-line'',它用于显示当前buffer的信息。<br />
<br />
''frame'' 是Emacs的一个"窗口"(这是标准的术语。比如,'窗口'是现代桌面的称谓),它包含了标题栏,菜单栏,还有一个或多个'window'(这是Emacs的术语,比如上面提到的'window')。<br />
<br />
从现在起,这些Emacs中存在的名词的定义就可以使用了。<br />
<br />
要把window水平分隔和垂直分隔,分别使用'''C-x 2'''和'''C-x 3'''。这种效果其实就是在当前frame中开户另外一个window。要在多个window中循环切换,使用'''C-x o'''。<br />
<br />
与分隔一个window相反的是删除window。要删掉当前window,使用'''C-x 0''',要删掉除了当前window之外的其它window,使用'''C-x 1'''。<br />
<br />
和window一样,创建和删除frame也是可以的。'''C-x 5 2'''会创建一个frame,'''C-x 5 0'''会删除当前的frame,'''C-x 5 1'''会删除除了当前frame之外的其它frame。<br />
<br />
{{注意|这些命令不影响buffer。比如删除一个window并不会删除在window中显示的buffer。}}<br />
<br />
===获得帮助===<br />
Emacs在设计的时候就自文档化了。比如,要查看一个命令的名字或者它的键的绑定,Emacs提供了很多帮助信息。下面是列出来的最有用的一些帮助命令:<br />
<br />
'''C-h t''' 启动Emacs官方教程<br />
<br />
'''C-h b''' 列出来所有的有效键绑定<br />
<br />
'''C-h k''' 查找一个键被绑定在了哪个命令上<br />
<br />
'''C-h w''' 查找一个命令被绑定在了哪些键上<br />
<br />
'''C-h a''' 查找一个匹配一段描述的命令<br />
<br />
'''C-h m''' 显示当前激活的所有模式的信息<br />
<br />
'''C-h f''' 显示给定函数的描述信息<br />
<br />
===模式===<br />
一个Emacs模式是用Emacs Lisp语言写的一个控制相关缓冲区行为的扩展。一般来说,它给编辑文本提供缩进,语法高亮和键绑定的功能。复杂的模式可以把Emacs变成一个完美的IDE (Integrated Development Environment). Emacs 一般会使用一个文件的扩展来确定应该加载那个模式。<br />
<br />
一些编写shell脚本比较有用的模式有sh-mode, line-number-mode 和 column-number-mode。它们可以并行地通过下面的方式激活:<br />
<br />
'''M-x sh-mode <RET>'''<br />
<br />
'''M-x column-number-mode <RET>'''<br />
<br />
line-number-mode 默认是激活的,它可以通过下面的命令来打开/关闭:<br />
<br />
'''M-x line-number-mode <RET>'''<br />
<br />
sh-mode 是一个 ''major-mode''. Major-modes 调整Emacs,并且经常提供了一些特定的命令来编辑某种类型的文本。一个缓冲区只能激活一种major-mode。除了支持语法高亮和缩进,sh-mode还定义了几条命令来帮助快速开发shell脚本。下面是其中的几条:<br />
<br />
'''C-c (''' 插入一个函数定义<br />
<br />
'''C-c C-f''' 插入一个for循环<br />
<br />
'''C-c TAB''' 插入一条if语句<br />
<br />
'''C-c C-w''' 插入一个while循环<br />
<br />
'''C-c C-l''' 插入一个从1到n的有下标的循环<br />
<br />
'line-number-mode' 和 'column-number-mode' 是 ''minor-modes''. Minor-modes 可以用来扩充major-mode的功能,多个minor-mode可以同时激活。<br />
<br />
==提示和技巧==<br />
前面的部分给出了基本编辑命令的概述,没有给出Emacs的一个指示。这个部分讲述一些高级的技巧和功能。<br />
<br />
===TRAMP===<br />
TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入一个文件名,输入特定的格式就可以使用TRAMPP。比如:<br />
<br />
在打开{{ic|/etc/hosts}}文件之前提示输入root的密码以获取root权限:<br />
<br />
C-x C-f /su::/etc/hosts<br />
<br />
要通过SSH使用'myuser'用户名登录'myhost'主机并打开文件{{ic|~/example.txt}}:<br />
<br />
C-x C-f /ssh:myuser@myhost:~/example.txt<br />
<br />
TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。<br />
<br />
===键盘宏和寄存器===<br />
这一部分会提供一个实用的指南来使用一些更强大的编辑特性。也就是“键盘宏”和“寄存器”。<br />
<br />
我们的目标是产生一个字符列表和它们在这个列表中对应的位置。虽然这可以通过手工格式化来完成,但是这样会很慢而且容易出错。如果我们采用一些Emacs更高级的编辑功能却可以起到四两拨千斤的功效。在介绍这个方法之前,需要先了解一些技术背后的细节。<br />
<br />
要介绍的第一个特性就是''寄存器''。寄存器的功能是用来保存和获取各种各样的数据。每个寄存器用一个字母来命名,这个字母就是用来调用这个寄存器的。<br />
<br />
另一个要介绍的就是''键盘宏''。一个键盘宏存储了一个命令序列以便以后可以重复使用。下面就一步一步地讲解这个方法。<br />
<br />
首先我们从一个包含如下字符的缓冲区开始:<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
通过`number-to-register' 命令 ('''C-x r n''')我们来准备一个寄存器,把数字'0'存储在寄存器'k'中:<br />
<br />
C-x r n k<br />
<br />
当光标在缓冲区开头的时候,开始录制键盘宏 ('''C-x (''') 然后开始对字符串进行格式化:<br />
<br />
C-x ( C-f M-4 .<br />
<br />
插入 ('''C-x r i''') 然后将寄存器'k'加1 ('''C-x r +''') 。开头的 ('''C-u''') 命令是用来在插入文字之后让光标移到插入的文字后面:<br />
<br />
C-u C-x r i k C-x r + k<br />
<br />
最后我们来插入一个回车来结束格式化。Emacs可以重复以上过程,从我们定义键盘宏的位置开始,直到最后一个字符。'''C-x e'''命令停止宏的录制并开始执行这段宏。开头的 '''M-0''' 命令是用来让宏在出错的时候停下来,这样在它走到这行的结尾就会停下来。<br />
<br />
<RET> M-0 C-x e<br />
<br />
下面是结果:<br />
<br />
A....0<br />
B....1<br />
C....2<br />
[...]<br />
x....49<br />
y....50<br />
z....51<br />
<br />
===正则表达式===<br />
From the Emacs Manual: "A regular expression, or ''regexp'' for short, is a pattern that denotes a (possibly infinite) set of strings." This section will not go into any detail regarding regular expressions themselves (as there is simply too much to cover). It will however provide a quick demonstration of their power. See [http://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html#Regular-Expressions Regular Expressions] section in the Emacs Manual for further reading.<br />
<br />
Given the same scenario presented above: A list of characters which are to be formatted to represent their respective position in the list. (see [[Emacs#Keyboard macros and registers|Keyboard macros and registers]]). Again, starting with a buffer containing.<br />
<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
At the beginning of the buffer, use '''C-M-%''' (if the key-sequence is difficult to perform, it may be more comfortable to use '''M-x query-replace-regexp'''). At the prompt:<br />
\(.\)<br />
which simply matches one character. Then, when prompted for the replacement:<br />
\1....\#^J<br />
{{Note|'^J' represents where a newline should be placed, it should not be entered into the prompt. The newline must instead be inserted literally using '''C-q C-j'''.}}<br />
The replacement expression reads: "Insert the matched text between the first set of parentheses (in this case, a single character), followed by 4 periods then insert an automatically incremented number followed by a newline.<br />
<br />
Finally, press '''!''' to apply this across the entire buffer. All of the formatting that was performed in the previous section was performed with a single regexp replacement.<br />
<br />
==定制==<br />
Emacs can configured by editing '~/.emacs' or using '''M-x customize'''. This section will focus on editing ~/.emacs by hand, and provide some example customizations to demonstrate commonly-configured aspects of Emacs. The customize command provides a simple interface to make adjustments, though it may become restricting as you grow more familiar with Emacs.<br />
<br />
All of the examples here can be performed while Emacs is running. To evaluate the expression within Emacs, use:<br />
<br />
'''C-M-x''' with point anywhere within the expression.<br />
<br />
or<br />
<br />
'''C-x C-e''' with point following the last ')'<br />
<br />
For some users, typing 'yes' and 'no' in prompts can quickly become tiring. To instead use the 'y' and 'n' keys at these prompts:<br />
<br />
(defalias 'yes-or-no-p 'y-or-n-p)<br />
<br />
To stop the cursor blinking, use:<br />
<br />
(blink-cursor-mode -1)<br />
<br />
Similarly, to enable column-number-mode, as discussed in the previous section:<br />
<br />
(column-number-mode 1)<br />
<br />
The similarities between the previous two commands are not a coincidence: blink-cursor-mode and column-number-mode are both minor-modes. As a rule, minor-modes can be enabled given positive argument or disabled with a negative argument. Should the argument be omitted, the minor-mode will be toggled on/off.<br />
<br />
Here are some more examples of minor-modes. The following will disable the scroll bars, menu-bar and tool-bar, respectively.<br />
<br />
(scroll-bar-mode -1)<br />
(menu-bar-mode -1)<br />
(tool-bar-mode -1)<br />
<br />
The variable, 'auto-mode-alist', can be modified to change the major-mode used by default for certain file names. The following example will make the default major-mode for '.tut' and '.req' files 'text-mode'.<br />
<br />
(setq auto-mode-alist<br />
(append<br />
'(("\\.tut$" . text-mode)<br />
("\\.req$" . text-mode))<br />
auto-mode-alist))<br />
<br />
Settings can also be applied on a per-mode basis. A common method for this is to add a function to a ''hook''. For example, to force indentation to use spaces instead of tabs, but only in text-mode:<br />
<br />
(add-hook 'text-mode-hook (lambda () (setq indent-tabs-mode nil)))<br />
<br />
Similarly, to only use spaces for indentation everywhere:<br />
<br />
(setq-default indent-tabs-mode nil)<br />
<br />
Keybindings can be adjusted in two ways. The first of which is 'define-key'. 'define-key' creates a keybinding for a command but only in one mode. The example below will make '''F8''' delete any whitespace from the end of each line of a 'text-mode' buffer:<br />
<br />
(define-key text-mode-map (kbd "<f8>") 'delete-trailing-whitespace)<br />
<br />
The other method is 'global-set-key'. This is used to bind a key to a command everywhere. To bind 'query-replace-regexp' ('''C-M-%''') to '<f7>'.<br />
<br />
(global-set-key (kbd "<f7>") 'query-replace-regexp)<br />
<br />
Binding a command to an alternate key does not replace any existing bindings. Which is to say, 'query-replace-regexp' would be bound to both '''F7''' and '''C-M-%''' after the above example.<br />
<br />
Almost anything within Emacs can be configured. Browsing through the [http://emacswiki.org/ Emacs Wiki] should give a solid place to start.<br />
<br />
<br />
=== Multiple configurations ===<br />
<br />
You can use several configurations and tell Emacs to load one or the other.<br />
<br />
For example, let's define two configuration files.<br />
<br />
{{hc|.emacs|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/plugins" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
This is the full configuration we load for the daemon. But the ''plugins'' file is huge and slow to load. If we want to spaqn a new Emacs instance that does not need the ''plutings'' features, it can be cumbersome to load it everytime in the long time.<br />
<br />
{{hc|.emacs-light|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
And now we launch Emacs with<br />
emacs -q -l ~/.emacs-light<br />
You can create an alias to ease the call.<br />
<br />
=== Loading extensions ===<br />
<br />
You can load extensions using the ''require'' function. For instance<br />
(require 'mediawiki)<br />
<br />
If you try using the same configuration file on a machine where mediawiki is not installed, Emacs will primpt for an error. Besides, all extension-specific code would be parsed for nothing.<br />
<br />
The trick is to test the return value of ''require'':<br />
<br />
(if (require 'mediawiki nil t)<br />
(progn<br />
(setq mediawiki-site-alist '(<br />
("ArchLinux" "https://wiki.archlinux.org/" "UserName" "" "Main Page")<br />
)<br />
)<br />
(setq mediawiki-mode-hook<br />
(lambda ()<br />
(visual-line-mode 1)<br />
(turn-off-auto-fill)<br />
))<br />
)) <br />
<br />
=== Local and custom variables ===<br />
<br />
You can define variables in your configuration file that can be later one modified locally for a file.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation")<br />
<br />
Now in any file you can define local variables in two ways:<br />
* On the very first line, write<br />
// -*- my-compiler:g++; mode:c++ -*-<br />
* If you cannot (or do not want to) write this on the first line, you can put it at the end:<br />
// Local Variables:<br />
// my-compiler: g++<br />
// mode: c++<br />
// End:<br />
<br />
Note that the beginning characters need to be comments for the current language, that's why here we used two backslashes for C++. For Elisp you would use<br />
;; -*- mode:emacs-lisp -*-<br />
<br />
There is two functions that may help you in defining the variables: ''add-file-local-variable'' and ''add-file-local-variable-prop-line''.<br />
<br />
Finally, custom variable are considered insecure by default. If you try to open a file that contains local variable redefining insecure custom variables, Emacs will ask you for confirmation.<br />
<br />
If you know what you are doing, you can declare the variable as secure, thus removing the Emacs prompt for confirmation. You need to specify a predicate that any new value has to verify so that it can be considered safe.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)<br />
<br />
In the previous example, if you attempt to set anything else than a string, Emacs will consider it insecure.<br />
<br />
=== Custom colors and theme ===<br />
<br />
Colors can be easily customized using the ''face'' facility.<br />
(set-face-background 'region "color-17")<br />
(set-face-foreground 'region "white")<br />
(set-face-bold-p 'font-lock-builtin-face t ) <br />
<br />
You can have let Emacs tell you the name of the face where the point is. Use the ''customize-face'' function for that. The facility will show you how to set colors, bold, underline, etc.<br />
<br />
Emacs in console can handle 256 colors, but you will have to use an appropriate terminal for that. For instance URxvt has support for 256 colors. You can use the ''list-colors-display'' for a comprehensive list of supported colors. This is highly terminal-dependent.<br />
<br />
=== SyncTeX support ===<br />
<br />
Emacs is definitely one of the most powerful LaTeX editor. This is mostly due to the fact you can adapt or create a LaTeX mode to fit your needs best.<br />
<br />
Still, there might be some challenges, like SyncTeX support. First you need to make sure your TeX distribution has it. If you installed TeX Live manually, you may need to install the ''synctex'' package.<br />
# umask 022 && tlmgr install synctex<br />
<br />
SyncTeX support is viewer-dependent. Here we will use Zathura as an example, so the code needs to be adapted if you want to use another PDF viewer.<br />
<br />
(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" <br />
"PDF Viewer for TeX documents. You may want to fork the viewer<br />
so that it detects when the same document is launched twice, and<br />
persists when Emacs gets closed.<br />
<br />
Simple command:<br />
<br />
zathura --fork<br />
<br />
We can use<br />
<br />
emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'<br />
<br />
to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."<br />
:safe 'stringp)<br />
<br />
Here we define our custom variable. If you are using AucTeX or Emacs default LaTeX-mode, you will have to set the viewer accordingly.<br />
<br />
Now open a LaTeX source file with Emacs, compile the document, and launch the viewer. Zathura will spawn. If you press {{ic|Ctrl+Left click}} Emacs should place the point at the corresponding position.<br />
<br />
== Documentation ==<br />
<br />
You may find yourself overwhelmed by the amount of Emacs features. You may find it difficult to know how to use Emacs Lisp to customize your favorite modes, or even to create your own modes / packages. Thankfully Emacs takes a strong point to auto-documenting everything: its internals, current configuration, bindings, etc. Almost everything is documented.<br />
<br />
=== Contextual help ===<br />
<br />
Emacs is self-documenting by design. As such, a great deal of information is available to determine the name of a specific command or its keybinding, for example. The following is a listing of some of the most helpful of these:<br />
<br />
'''C-h a''' Find a command matching a description.<br />
<br />
'''C-h b''' List all active keybindings.<br />
<br />
'''C-h f''' Describe the given function.<br />
<br />
'''C-h k''' Find which command a key is bound to.<br />
<br />
'''C-h m''' Display information regarding the currently active modes.<br />
<br />
'''C-h t''' Start the Emacs tutorial.<br />
<br />
'''C-h v''' Describe the given variable.<br />
<br />
'''C-h w''' Find which key(s) a command is bound to.<br />
<br />
=== The manuals ===<br />
<br />
If you really want to master Emacs, the most recommanded source of documentation remains the official manuals:<br />
* Emacs: the complete Emacs user manual.<br />
* Emacs FAQ.<br />
* Emacs Lisp Intro: if you never used any programming language before.<br />
* Elisp: if you are already familiar with a programming language.<br />
<br />
You can access it as PDFs from [http://www.gnu.org/software/emacs/manual/ GNU.org] or directly from Emacs itself thanks to the embedded 'info' reader: '''C-h i'''. Press '''m''' to choose a book.<br />
<br />
Some users prefer to read books using 'info' because of its convenient shortcuts, its paragraphs adapting to window width and the font adapted to current screen resolution. Some find it less irritating to the eyes. Finally you can easily copy content from the book to any Emacs buffer, and you can even execute Lisp code snippets directly from the examples.<br />
<br />
You may want to read the '''Info''' book to know more about it: '''C-h i m info <RET>'''.<br />
Press '''?''' while in info mode for a quick list of shortcuts.<br />
<br />
== 拓展模块 ==<br />
<br />
虽然Emacs包含了成百上千种模式(mode),库和其它扩展,还有更多的扩展来增强Emacs。大多数扩展会详细说明安装它的时候要对~/.emacs作什么改动。这些说明一般会在一个elisp源文件开头的注释中,或者在一个README中(如果这个扩展包含了多个源文件)。<br />
<br />
在'community'仓库中有很多流行的扩展,更多的扩展还放在了[[AUR]]。这些软件包的名字有一个'emacs-'前缀(比如emacs-lua-mode)。在很多情况下,在安装的过程会显示怎样修改~/.emacs以安装该扩展到Emacs中。<br />
<br />
想知道怎样激活一个不在上面提到的地方的扩展,查看[http://emacswiki.org/ Emacs Wiki]中的相应页面,一般会提供一个配置的例子。Emacs Wiki也是一个寻找扩展的优秀资源。<br />
<br />
你也可以使用[http://tromey.com/elpa/ Emacs Lisp Package Archive (ELPA)] 来自动安装软件包。打开那个网站看说明。ELPA已经包括在了Emacs24中;它已经作为Emacs生态系统中的一部分了。<br />
<br />
== 疑难杂症 ==<br />
<br />
===彩色输出的问题===<br />
Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。<br />
<br />
在{{ic|~/.emacs}}中加入下面的代码解决这个问题:<br />
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)<br />
<br />
===菜单显示为空===<br />
一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550541 Debian bug report] 有一个应对措施。<br />
<br />
=== X 窗口下的字符显示问题 ===<br />
当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 {{pkg|xorg-fonts-75dpi}} 或者 {{pkg|xorg-fonts-100dpi}} 并且重启X窗口。<br />
<br />
=== 启动速度慢 ===<br />
启动速度慢经常是由下面两种情况引起的。<br />
<br />
要确定是哪种情况,这样打开Emacs:<br />
<br />
$ emacs -q<br />
<br />
如果Emacs还是启动很慢,则是[[Emacs#Incorrect network configuration|错误的网络配置]]。如果不是,则可以确定是[[Emacs#Init file loads slowly|.emacs的问题]]。<br />
<br />
====错误的网络配置====<br />
<br />
当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'[[Configuring_network#Set_the_hostname|set the hostname]]' 了解更多内容。<br />
<br />
====初始化文件加载慢====<br />
<br />
一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:<br />
<br />
(require 'anything)<br />
<br />
你应该这样:<br />
<br />
(autoload 'anything "anything" "Select anything" t)<br />
<br />
=== 不能打开配置文件: ... ===<br />
<br />
这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:<br />
<br />
(add-to-list 'load-path "/path/to/directory/")<br />
<br />
当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:<br />
<br />
(add-to-list 'load-path "/usr/share/emacs/site-lisp")<br />
<br />
如果手动编译Emacs,记住默认的前缀是'/usr/local'。<br />
<br />
=== Dead-accent keys problem: '<dead-acute> is undefined' ===<br />
<br />
Searching about this bug on Google, we find this link:<br />
http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html<br />
<br />
Explaining the problem: in recent versions of<br />
b72<br />
Emacs, the normal way to use accent keys doesn't work as expected. Trying to accent a word like 'fiancé' will produce the message above.<br />
<br />
A way to solve it is just put the line above on your startup file, {{ic|~/.emacs}}:<br />
<br />
(require 'iso-transl)<br />
<br />
And no, it isn't a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):<br />
<br />
:''It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be<br />
a3b<br />
classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. ''<br />
<br />
=== C-M-% and some other bindings do not work in emacs nox ===<br />
<br />
This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:<br />
* either use the graphical version,<br />
* or change the binding to a supported one.<br />
<br />
Example:<br />
{{hc|.emacs|<br />
(global-set-key (kbd "C-M-y") 'query-replace-regexp)<br />
}}<br />
<br />
=== Emacs client gets stuck when switching back to it ===<br />
<br />
If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an '''M-x''' for instance), then all other instance will wait for it to finish. Press '''C-g''' to cancel any input to make sure this Emacs session is not blocking.<br />
<br />
=== Emacs-nox output gets messy ===<br />
<br />
When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal.<br />
There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.<br />
<br />
Graphical Emacs does not suffer from this issue.<br />
<br />
=== Shift + Arrow keys not working in emacs within tmux ===<br />
<br />
First you must enable xterm-keys in your [[tmux]] config.<br />
{{hc|.tmux.conf|<br />
setw -g xterm-keys on<br />
}}<br />
<br />
But, this will break other key combinations. To fix them, put the following in your emacs config.<br />
{{hc|.emacs|<br />
;; handle tmux's xterm-keys<br />
;; put the following line in your ~/.tmux.conf:<br />
;; setw -g xterm-keys on<br />
(if (getenv "TMUX")<br />
(progn<br />
(let ((x 2) (tkey ""))<br />
(while (<&#61; x 8)<br />
;; shift<br />
(if (&#61; x 2)<br />
(setq tkey "S-"))<br />
;; alt<br />
(if (&#61; x 3)<br />
(setq tkey "M-"))<br />
;; alt + shift<br />
(if (&#61; x 4)<br />
(setq tkey "M-S-"))<br />
;; ctrl<br />
(if (&#61; x 5)<br />
(setq tkey "C-"))<br />
;; ctrl + shift<br />
(if (&#61; x 6)<br />
(setq tkey "C-S-"))<br />
;; ctrl + alt<br />
(if (&#61; x 7)<br />
(setq tkey "C-M-"))<br />
;; ctrl + alt + shift<br />
(if (&#61; x 8)<br />
(setq tkey "C-M-S-"))<br />
<br />
;; arrows<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))<br />
;; home<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))<br />
;; end<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))<br />
;; page up<br />
(define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))<br />
;; page down<br />
(define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))<br />
;; insert<br />
(define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; delete<br />
(define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; f1<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))<br />
;; f2<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))<br />
;; f3<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))<br />
;; f4<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))<br />
;; f5<br />
(define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))<br />
;; f6<br />
(define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))<br />
;; f7<br />
(define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))<br />
;; f8<br />
(define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))<br />
;; f9<br />
(define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))<br />
;; f10<br />
(define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))<br />
;; f11<br />
(define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))<br />
;; f12<br />
(define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))<br />
;; f13<br />
(define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))<br />
;; f14<br />
(define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))<br />
;; f15<br />
(define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))<br />
;; f16<br />
(define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))<br />
;; f17<br />
(define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))<br />
;; f18<br />
(define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))<br />
;; f19<br />
(define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))<br />
;; f20<br />
(define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))<br />
<br />
(setq x (+ x 1))<br />
))<br />
)<br />
)<br />
}}<br />
<br />
== 替代方案 ==<br />
<br />
有很多Emacs的实现。GNU/Emacs 可能是最受欢迎的了。<br><br />
更轻量的兼容性较好的Emacs可以在Arch仓库或在[https://aur.archlinux.org/ AUR]中找到。<br />
<br />
=== mg ===<br />
<br />
mg(原来叫MicroGnuEmacs),是用C语言实现的轻量级Emacs。<br />
<br />
可以从{{ic|community}中安装mg<br />
# pacman -S mg<br />
或者从官方网站[http://homepage.boetes.org/software/mg/ page]中下载源代码。<br />
<br />
=== zile ===<br />
<br />
引用官方网站[https://www.gnu.org/software/zile/ page]的描述,"GNU Zile is a lightweight Emacs clone. Zile is short for Zile Is Lossy Emacs. Zile has been written to be as similar as possible to Emacs; every Emacs user should feel at home.",意思是'GNU Zile'是一个轻量级的Emacs的克隆。Zile是'Zile Is Lossy Emacs'的缩写。<br />
Zile的实现与Emacs如此相似以至于每个Emacs用户使用Zile一定会有一种宾至如归的感觉。<br />
<br />
zile 可以在{{ic|extra}}中找到<br />
<br />
# pacman -S zile<br />
<br />
最新的tarball可以在GNU的官方源[http://ftp.sh.cvut.cz/MIRRORS/gnu/pub/gnu/zile/ mirrors]中找到。<br />
<br />
=== uemacs ===<br />
<br />
uemacs 是由Linus Torvalds定制的微型Emacs版本。<br />
它可以在 [https://aur.archlinux.org/ AUR] 的 [https://aur.archlinux.org/packages.php?ID=31502 uemacs]中找到。<br />
<br />
== 资源 ==<br />
* [http://www.gnu.org/software/emacs/ GNU Emacs home page]<br />
* [http://www.gnu.org/software/emacs/manual/emacs.html GNU Emacs Manual]<br />
* [http://www.emacswiki.org/cgi-bin/wiki/ Emacs Wiki]<br />
* [http://wikemacs.org WikEmacs - a more readable, but less complete Emacs Wiki]<br />
* [http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Useful introduction to Emacs and its shortcuts]<br />
* [http://www.dina.kvl.dk/~abraham/religion/ The Church of Emacs]<br />
* [http://repo.or.cz/w/emacs.git/blob/HEAD:/etc/refcards/refcard.pdf Official reference card]</div>HelloCodehttps://wiki.archlinux.org/index.php?title=Emacs_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=349117Emacs (简体中文)2014-12-08T14:31:01Z<p>HelloCode: /* 查找和替换 */</p>
<hr />
<div>[[Category:Text editors (简体中文)]]<br />
[[de:Emacs]]<br />
[[en:Emacs]]<br />
[[fr:Emacs]]<br />
[[ja:Emacs]]<br />
[[sr:Emacs]]<br />
{{TranslationStatus (简体中文)|Emacs|2012-10-17|229169}}<br />
{{Translateme (简体中文)}}<br />
[[Wikipedia:Emacs|Emacs]]是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在[[Wikipedia:Emacs Lisp|Emacs Lisp]]解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和[[vim]]比较。<br />
<br />
{{Note|入门建议直接使用starterkit扩展。本文档实际帮助不大}}<br />
<br />
== 安装 ==<br />
Emacs有众多变体发行版本(有时候称作''emacsen''). 最常见的莫过于 [http://www.gnu.org/software/emacs/ GNU Emacs],在[[Official repositories]]可以找到<br />
<br />
$ pacman -S emacs<br />
<br />
如果你总是在终端下工作的话,你可能会选择{{Pkg|emacs-nox}}。这是一个没有GTK+依赖的版本(也没有声音支持)。<br />
<br />
终端版Emacs存在以下问题:它支持更少的颜色和更少的字体控制功能(缺少在线控制字体大小、在一篇文档中使用多种字体等功能)。而且对于一些需要高级特性的功能比如Speedbar或者GUD(调试环境),它也不支持。另外在控制复杂的外观(face)时,emacs-nox比Emacs要慢。<br />
<br />
如果你想体验Emacs的所有扩展功能而不用装一堆依赖的话,你可以使用PKGBUILD来按你的需求定制Emacs。不使用{{ic|gtk3}}可以让Emacs避免使用gconf。图像和声音的支持也可以去除。在Emacs的源代码目录下运行{{ic|./configure --help}}可以看看有哪些配置选项。<br />
{{hc|PKGBUILD|<nowiki><br />
# ...<br />
./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \<br />
--localstatedir=/var --with-x-toolkit=gtk2 --with-xft \<br />
--without-gconf --without-sound<br />
# ...<br />
</nowiki>}}<br />
<br />
另外一个常见的变体就是{{Pkg|xemacs}}.<br />
<br />
== 快速入门 ==<br />
一般印象是Emacs十分复杂,学习曲线陡峭,但很多资深学习者并不这样认为,反而认为其非常易懂和可定制。因为其源码和配置文件语义化程度较高。简单了解下自定义和高扩展带来的好处花不了多少时间。何况还有很多成熟的功能拓展模块,很方便添加,可以让Emacs为任何文本编辑的需求配置强大的环境。<br />
<br />
Emacs自带一个入门教程,你可以点击欢迎界面上的第一个链接来打开它; 或者从菜单栏中选择''Help->Emacs Tutorial'',或者按'F1'键然后按't'. 我们设计这篇文章来为你在Emacs入门学习中提供额外的资源。<br />
<br />
Emacs也包括一系列引用链接,既有适合初学者的内容,也有骨灰级玩家所喜爱的.参见{{ic|/usr/share/emacs/<version>/etc/refcards/}} (将<version>换成你的emacs版本).<br />
<br />
===运行Emacs===<br />
<br />
在启动Emacs之前,你要先学会怎么关闭它(尤其是你要在终端里运行它的话):用{{ic|Ctrl+x}}{{ic|Ctrl+c}}来关闭它。<br />
<br />
====图形界面下打开方式====<br />
图形界面下可以直接点击图标打开。<br />
<br />
====虚拟终端下的常见方式====<br />
打开Emacs:<br />
<br />
$ emacs<br />
<br />
不打开图形界面,直接在终端中运行:<br />
<br />
$ emacs -nw<br />
<br />
也可以直接用下面的命令来打开一个文件:<br />
<br />
$ emacs filename.txt<br />
<br />
=====去掉颜色=====<br />
默认的emacs会带有颜色主题,如果不需要,可以关闭之:<br />
<br />
$ emacs -nw --color=no<br />
<br />
<br />
====作为守护进程====<br />
Emacs由于每次启动都需要加载大量自定义的配置文件,所以打开时候会有点慢。从Emacs23开始, Emacs可以以守护进程的形式运行,这样每个用户都可以链接到Emacs。以守护进程运行Emacs:<br />
<br />
$ emacs --daemon<br />
<br />
你可能在启动时打开一个守护进程,然后再将守护进程链接到窗口。另外,也可以将图形和终端客户端同时链接到守护进程上,这样启动图形界面速度就很快了。<br />
<br />
如果你仅仅想链接到守护进程,用下面的命令(注意,在桌面环境下这个命令会打开一个图形客户端,而在像tty这种命令行下,它会打开一个命令行版的emacs):<br />
<br />
$ emacsclient<br />
<br />
如果你想在桌面环境下打开一个命令行版的emacs,使用下面的命令:<br />
<br />
$ emacsclient -t<br />
<br />
另外,你可以在后面加上 {{ic|-a ""}} 参数.<br />
现在,你第一次使用这个命令时,它会把emacs作为守护进程来启动,它会留在后台以加快以后的启动速度(也会记住缓冲区).<br />
<br />
更聪明点,你可以在.bashrc中加上下面的别名:<br />
{{bc|1=<br />
alias em='emacsclient -t -a ""' #在终端中开启emacs<br />
alias emc='emacsclient -nc -a ""' #启动emacs图形界面<br />
EDITOR='emacsclient -a ""'<br />
}}<br />
<br />
在[[xfce]]桌面环境中,如果你想使用 emacsclient -c 来代替 emacs %f 打开一个新文件, 你可以修改你的 /usr/share/applications/emacs.desktop 文件,把下面这一行<br />
<br />
$ Exec=emacs %f<br />
<br />
修改为<br />
<br />
$ Exec=emacsclient -c<br />
<br />
使用这种方法,每次你打开一个文件时就只会启动客户端,因此速度非常快!<br />
<br />
===基本术语和约定===<br />
Emacs使用一些刚开始看起来很奇怪的术语和约定,我们会在合适的时候介绍。但是,对于部分术语,我们必须要在前面介绍,因为它们对于使用Emacs来说是非常基础的。<br />
<br />
第一个要介绍的术语是''缓冲区''的概念。一个缓冲区就是Emacs中的数据的一种表示方式,比如,当使用Emacs打开一个文件时,这个文件从磁盘中被读出来,它的内容被存储在了缓冲区里面,它的内容可以在这个缓冲区里面被编辑并且可以重新写进磁盘中。缓冲区中的内容不仅仅可以是文本,也可以是图片和widget。现在,让缓冲区可以显示应用程序的工作正在进行!换个角度思考,在磁盘中数据是以文件形式保存的,而在Emacs中,数据是以缓冲区的形式存在的。<br />
<br />
在Emacs中,对于按键组合的约定你可能很陌生。比如:<br />
<br />
'''C-x''' 代表 Ctrl-x<br />
<br />
'''M-x''' 代表 Meta-x<br />
<br />
{{注意|'Meta'一般代表Alt键,也可以用Esc键替代。}}<br />
<br />
举个例子,退出Emacs使用下面的按键组合'''C-x C-c'''。这个可以读做,"按住Ctrl键再按'x',释放,再按住Ctrl键再按'c'。虽然Emacs提供了一个菜单栏,但是强烈建议学习使用按键组合。这个指南将参考Emacs的按键绑定的约定。<br />
<br />
===移动===<br />
光标移动和其它图形编辑器非常类似,鼠标和方向键可以用来改变光标(在Emacs中称为''点'')的位置。在Emacs中,方向键代表的标准移动命令也有其它辅助的绑定。向前(forward)移动一个字符,使用 '''C-f''',向后(back)移动一个字符,使用'''C-b'''。 '''C-n''' 和 '''C-p''' 分别用于移动到下(next)一行和移动到上(previous)一行。再声明一下,强烈推荐使用组合键而不是使用方向键和鼠标。<br />
<br />
可以想像,Emacs提供了更多的光标高级移动命令,包括移动一个单词和一个句子。 '''M-f''' 表示光标向前移动一个单词, '''M-b''' 表示向后移动一个单词。类似地,'''M-e''' 把光标移动到一个句子的末尾(end), '''M-a''' 移动到句子的开头。<br />
<br />
直到现在,所有的移动命令都是和光标有关的。'''M-<''' 表示把光标移动到缓冲区的开头,和它相反的是 '''M->''', 把光标移动到缓冲区的末尾。要把光标移动到某一特定行,使用'''M-g g'''. '''M-g g''' 会提示输入行号。同样,要移动到一行的开头或者结尾,分别使用'''C-a''' 和 '''C-e'''。<br />
<br />
{{Note|这些命令(实际上是全部命令)的绑定,在不同的模式(mode)中,''稍微''会有不同。然而,覆盖的命令提供不同的功能这种情况很少见。更多信息请看[[Emacs#Modes|Modes]]。}}<br />
<br />
===文件和缓冲区===<br />
Emacs 提供了一系列命令来对文件操作,其中最常用的会在这里详细说明。'''C-x C-f''' 用来打开一个文件(在Emacs中叫做'查找文件')。如果指定的文件不存在,Emacs会打开一个空的缓冲区。保存一个缓冲区会创建一个包含缓冲区内容的文件。'''C-x C-s''' 就是用来保存缓冲区的。要保存一个文件名不一样的缓冲区,使用'''C-x C-w''' (这其实是'write-file'这条命令的助记符), 它会在写入磁盘之前提示输入新文件名。也可以使用'''C-x s'''来保存所有的缓冲区, 如果某个缓冲区在上次保存之后被修改了,则会提示进行哪项操作。<br />
<br />
{{Note|如果指向某个文件的缓冲区还在打开的话,'''C-x C-f''' 是不会重新从磁盘中读取文件的。要从磁盘中重新读取文件,先使用'''C-x k'''关掉缓冲区,再使用'''C-x C-f'''打开文件,或者使用'''M-x revert-buffer'''.}}<br />
<br />
很多互动的命令,比如"find-file" 或者 "write-file" 会在Emacs窗口的底部栏提示输入。这栏称为''minibuffer''。和很多*nix shell一样,minibuffer支持很多基本的操作和TAB补全。按两下'''<TAB>'''可以显示一个补全的选项列表,并且,如果你喜欢,可以用鼠标从列表中选择。minibuffer的补全在很多输入(包括命令和文件名)中都可以用。<br />
<br />
minibuffer也提供一个记住历史的特性。通过'''Up Arrow''' 或者 '''C-p'''可以取得这条命令的上一个条目.<br />
<br />
要在任意时刻退出minibuffer,使用'''C-g'''.<br />
<br />
打开几个文件后,切换缓冲区是非常必要的。打开一个指向那个缓冲区的文件可以切换到那个缓冲区。但是这不是最高效的方法。Emacs提供'''C-x b'''来提示要显示的新缓冲区(这里可以使用TAB补全)。输入一个不存在的缓冲区,则会新建一个空的缓冲区。<br />
<br />
{{Note|要切换到上一个缓冲区,使用'''C-x b <RET>''', 因为上一个缓冲区是默认的缓冲区。}}<br />
<br />
使用'''C-x C-b'''可以显示所有打开缓冲区的列表。如果某个缓冲区不需要使用了,使用'''C-x k'''来关掉它。<br />
<br />
===编辑===<br />
Emacs 内建有很多编辑命令。可能最重要的还没有介绍的是'undo',它的快捷键为 ''C-_'' 或者 ''C-/'' .移动光标的命令通常都有对应的删除字符的命令。例如, '''M-<backspace>''' 可以用来删除一个光标后的词,'''M-d'''可以用来删除光标前面的一个词。删除光标至行尾或者句尾的字符可以分别用'''C-k''' 或者 '''M-k'''。<br />
<br />
通常我们都约定一行不能超过80个字符。这是为了代码的可读性,尤其是一行中的字符可能会接触到窗口边缘。在Emacs,自动地插入或者删除换行符称为''filling''。我们可以用 '''M-q''' 重整当前的段落(重新分配换行符,删除段落中多余的空格和tab键)<br />
<br />
字符和单词可以分别通过 '''C-t''' 和 '''M-t''' 进行交换。比如: <code>Hello World!</code> → <code>World! Hello</code><br />
<br />
单词的大小写也可以调整。'''M-l''' 把光标处的单词变成小写 (<code>HELLO</code> → <code>hello</code>); '''M-u''' 把光标处的单词变成大写(<code>hello</code> → <code>HELLO</code>), '''M-c''' 把光标处的单词的第一个字母变成大写,并把后面的变成小写(<code>hElLo</code> → <code>Hello</code>).<br />
<br />
===移除,召回和区域===<br />
一个''区域''(region)是指在两个位置之间的一段字。其中一个位置被称为''标记''(mark),另一个是光标。'''C-<SPC>'''用来设置标记的位置,紧接着就可以通过移动光标来创造一个区域。在GNU Emacs 23.1及以后的版本中,这个区域默认是可见的。有许多命令是针对区域的,其中最常用的就是''kill''命令。<br />
<br />
在Emacs中,剪切和粘贴分别对应的命令叫做''kill''和''yank''。许多删除多个字符的命令(包括上面提到的'''C-k'''和'''M-d'''命令)实际上是把文字剪切下来,附加到一个叫''kill-ring''的地方。kill-ring 就是一个被删掉的文字的列表。在默认情况下,kill-ring会保存最多60次删除记录。连续的删除会连在一起。<br />
<br />
'''C-w''' 和 '''M-w''' 可以用来删除或复制一个区域。<br />
<br />
要想把删掉的文字插入进来(也就是'yanking'),可以用'''C-y'''命令。'''C-y''' 可以连续用好多次来重复插入。按刚刚所讲,之前删除的文字会排成一个列表,但是'''C-y'''只能获取列表中的第一个,也就是最后删掉的一个。再之前删掉的可以通过'''M-y'''来获取。它会把'''C-y'''刚刚插入的文字用再早删除的文字替换掉。'''M-y''' 必须紧跟着'''C-y'''命令执行,可以执行很多次以遍历kill-ring。<br />
<br />
===查找和替换===<br />
在文本编辑中进行字符串查找是很常见的任务。按'''C-s'''可以正向搜索,按'''C-r‘’‘则可以反向搜索。这些命令提示要搜索的字符串。搜索是增量的,你再次按键时会显示下一个匹配的位置,并且可以使用'''C-s’‘’向前或者使用'''C-r‘’‘向后。找到匹配结果之后,可以按下'''<RET>'''结束搜索。另外,如果你想回到发起搜索的位置,可以使用'''C-g'''。<br />
<br />
一旦搜索完成(不是由'''C-g'''之类的指令引起),当前搜索的字符串将会作为下一次搜索的默认参数。使用’‘’C-s C-s'''或者'''C-r C-r'''可以达到这样的效果。<br />
<br />
I-search 有一些有用的命令,使用'''M-e'''来编辑当且搜索区域,使用'''M-c'''来触发大小写敏感匹配。<br />
<br />
正则表达式搜索除了指令不同之外,其他方面和以上都相同。使用'''C-M-s'''或者'''C-M-r'''来使用正则表达式搜索。相应地,用'''C-s'''和'''C-r'''可以前后移动,和普通的搜索没什么两样。<br />
<br />
除了搜索之外,进行字符串替换也是有必要的。原始文本和替换文本都会有提示,替换的时候也会有提示。尽管有很多选项提供(按'''?'''可以了解完整的选项),最常用的还是'''y'''(进行替换),'''n'''(跳过),以及'''!'''(替换当前及之后所有匹配)。<br />
<br />
===缩进和前缀参数===<br />
Indentation is usually performed with either '''<TAB>''', to indent a single line, or with '''C-M-\''', to indent a region.<br />
<br />
Exactly how text is indented usually depends on the ''major-mode'' which is active. Major-modes often define indentation styles specialising in indenting a certain type of text. (See [[Emacs#Modes|Modes]] for more information.)<br />
<br />
In some cases, a suitable major-mode may not exist for a file type, in which case, manual indentation may be necessary. Create a region (see [[Emacs#Killing, yanking and regions|Killing, yanking and regions]]) then perform indentation with '''C-u <n> C-x <TAB>''' (where '<n>' is the number of columns which the text within the region should be indented). For example:<br />
<br />
Increase the region's indentation by four columns:<br />
<br />
C-u 4 C-x <TAB><br />
<br />
Decrease the region's indentation by two columns.<br />
<br />
C-u -2 C-x <TAB><br />
<br />
{{Note|The trick behind this is '''C-u''', which corresponds to the 'universal-argument' command. Providing a 'universal-argument' is a way to provide more information to a command (this information is referred to as a 'prefix argument'). In this case, we provided the amount of indentation desired to the command invoked by '''C-x <TAB>'''. Without providing an argument, '''C-x <TAB>''' will only increase indentation by 1 column.}}<br />
<br />
===窗口和外框架===<br />
Emacs的设计是可以同时方便地编辑多个文件。这是通过把Emacs的接口分成三个层次来实现的,即buffer(之前介绍过了),''window''和''frame''。<br />
<br />
''window'' 是显示buffer的一个viewport(社区)。一个window一次只能显示一个buffer。但是一个buffer可以在多个window中显示。在窗口下面有一个''mode-line'',它用于显示当前buffer的信息。<br />
<br />
''frame'' 是Emacs的一个"窗口"(这是标准的术语。比如,'窗口'是现代桌面的称谓),它包含了标题栏,菜单栏,还有一个或多个'window'(这是Emacs的术语,比如上面提到的'window')。<br />
<br />
从现在起,这些Emacs中存在的名词的定义就可以使用了。<br />
<br />
要把window水平分隔和垂直分隔,分别使用'''C-x 2'''和'''C-x 3'''。这种效果其实就是在当前frame中开户另外一个window。要在多个window中循环切换,使用'''C-x o'''。<br />
<br />
与分隔一个window相反的是删除window。要删掉当前window,使用'''C-x 0''',要删掉除了当前window之外的其它window,使用'''C-x 1'''。<br />
<br />
和window一样,创建和删除frame也是可以的。'''C-x 5 2'''会创建一个frame,'''C-x 5 0'''会删除当前的frame,'''C-x 5 1'''会删除除了当前frame之外的其它frame。<br />
<br />
{{注意|这些命令不影响buffer。比如删除一个window并不会删除在window中显示的buffer。}}<br />
<br />
===获得帮助===<br />
Emacs在设计的时候就自文档化了。比如,要查看一个命令的名字或者它的键的绑定,Emacs提供了很多帮助信息。下面是列出来的最有用的一些帮助命令:<br />
<br />
'''C-h t''' 启动Emacs官方教程<br />
<br />
'''C-h b''' 列出来所有的有效键绑定<br />
<br />
'''C-h k''' 查找一个键被绑定在了哪个命令上<br />
<br />
'''C-h w''' 查找一个命令被绑定在了哪些键上<br />
<br />
'''C-h a''' 查找一个匹配一段描述的命令<br />
<br />
'''C-h m''' 显示当前激活的所有模式的信息<br />
<br />
'''C-h f''' 显示给定函数的描述信息<br />
<br />
===模式===<br />
一个Emacs模式是用Emacs Lisp语言写的一个控制相关缓冲区行为的扩展。一般来说,它给编辑文本提供缩进,语法高亮和键绑定的功能。复杂的模式可以把Emacs变成一个完美的IDE (Integrated Development Environment). Emacs 一般会使用一个文件的扩展来确定应该加载那个模式。<br />
<br />
一些编写shell脚本比较有用的模式有sh-mode, line-number-mode 和 column-number-mode。它们可以并行地通过下面的方式激活:<br />
<br />
'''M-x sh-mode <RET>'''<br />
<br />
'''M-x column-number-mode <RET>'''<br />
<br />
line-number-mode 默认是激活的,它可以通过下面的命令来打开/关闭:<br />
<br />
'''M-x line-number-mode <RET>'''<br />
<br />
sh-mode 是一个 ''major-mode''. Major-modes 调整Emacs,并且经常提供了一些特定的命令来编辑某种类型的文本。一个缓冲区只能激活一种major-mode。除了支持语法高亮和缩进,sh-mode还定义了几条命令来帮助快速开发shell脚本。下面是其中的几条:<br />
<br />
'''C-c (''' 插入一个函数定义<br />
<br />
'''C-c C-f''' 插入一个for循环<br />
<br />
'''C-c TAB''' 插入一条if语句<br />
<br />
'''C-c C-w''' 插入一个while循环<br />
<br />
'''C-c C-l''' 插入一个从1到n的有下标的循环<br />
<br />
'line-number-mode' 和 'column-number-mode' 是 ''minor-modes''. Minor-modes 可以用来扩充major-mode的功能,多个minor-mode可以同时激活。<br />
<br />
==提示和技巧==<br />
前面的部分给出了基本编辑命令的概述,没有给出Emacs的一个指示。这个部分讲述一些高级的技巧和功能。<br />
<br />
===TRAMP===<br />
TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入一个文件名,输入特定的格式就可以使用TRAMPP。比如:<br />
<br />
在打开{{ic|/etc/hosts}}文件之前提示输入root的密码以获取root权限:<br />
<br />
C-x C-f /su::/etc/hosts<br />
<br />
要通过SSH使用'myuser'用户名登录'myhost'主机并打开文件{{ic|~/example.txt}}:<br />
<br />
C-x C-f /ssh:myuser@myhost:~/example.txt<br />
<br />
TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。<br />
<br />
===键盘宏和寄存器===<br />
这一部分会提供一个实用的指南来使用一些更强大的编辑特性。也就是“键盘宏”和“寄存器”。<br />
<br />
我们的目标是产生一个字符列表和它们在这个列表中对应的位置。虽然这可以通过手工格式化来完成,但是这样会很慢而且容易出错。如果我们采用一些Emacs更高级的编辑功能却可以起到四两拨千斤的功效。在介绍这个方法之前,需要先了解一些技术背后的细节。<br />
<br />
要介绍的第一个特性就是''寄存器''。寄存器的功能是用来保存和获取各种各样的数据。每个寄存器用一个字母来命名,这个字母就是用来调用这个寄存器的。<br />
<br />
另一个要介绍的就是''键盘宏''。一个键盘宏存储了一个命令序列以便以后可以重复使用。下面就一步一步地讲解这个方法。<br />
<br />
首先我们从一个包含如下字符的缓冲区开始:<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
通过`number-to-register' 命令 ('''C-x r n''')我们来准备一个寄存器,把数字'0'存储在寄存器'k'中:<br />
<br />
C-x r n k<br />
<br />
当光标在缓冲区开头的时候,开始录制键盘宏 ('''C-x (''') 然后开始对字符串进行格式化:<br />
<br />
C-x ( C-f M-4 .<br />
<br />
插入 ('''C-x r i''') 然后将寄存器'k'加1 ('''C-x r +''') 。开头的 ('''C-u''') 命令是用来在插入文字之后让光标移到插入的文字后面:<br />
<br />
C-u C-x r i k C-x r + k<br />
<br />
最后我们来插入一个回车来结束格式化。Emacs可以重复以上过程,从我们定义键盘宏的位置开始,直到最后一个字符。'''C-x e'''命令停止宏的录制并开始执行这段宏。开头的 '''M-0''' 命令是用来让宏在出错的时候停下来,这样在它走到这行的结尾就会停下来。<br />
<br />
<RET> M-0 C-x e<br />
<br />
下面是结果:<br />
<br />
A....0<br />
B....1<br />
C....2<br />
[...]<br />
x....49<br />
y....50<br />
z....51<br />
<br />
===正则表达式===<br />
From the Emacs Manual: "A regular expression, or ''regexp'' for short, is a pattern that denotes a (possibly infinite) set of strings." This section will not go into any detail regarding regular expressions themselves (as there is simply too much to cover). It will however provide a quick demonstration of their power. See [http://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html#Regular-Expressions Regular Expressions] section in the Emacs Manual for further reading.<br />
<br />
Given the same scenario presented above: A list of characters which are to be formatted to represent their respective position in the list. (see [[Emacs#Keyboard macros and registers|Keyboard macros and registers]]). Again, starting with a buffer containing.<br />
<br />
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<br />
<br />
At the beginning of the buffer, use '''C-M-%''' (if the key-sequence is difficult to perform, it may be more comfortable to use '''M-x query-replace-regexp'''). At the prompt:<br />
\(.\)<br />
which simply matches one character. Then, when prompted for the replacement:<br />
\1....\#^J<br />
{{Note|'^J' represents where a newline should be placed, it should not be entered into the prompt. The newline must instead be inserted literally using '''C-q C-j'''.}}<br />
The replacement expression reads: "Insert the matched text between the first set of parentheses (in this case, a single character), followed by 4 periods then insert an automatically incremented number followed by a newline.<br />
<br />
Finally, press '''!''' to apply this across the entire buffer. All of the formatting that was performed in the previous section was performed with a single regexp replacement.<br />
<br />
==定制==<br />
Emacs can configured by editing '~/.emacs' or using '''M-x customize'''. This section will focus on editing ~/.emacs by hand, and provide some example customizations to demonstrate commonly-configured aspects of Emacs. The customize command provides a simple interface to make adjustments, though it may become restricting as you grow more familiar with Emacs.<br />
<br />
All of the examples here can be performed while Emacs is running. To evaluate the expression within Emacs, use:<br />
<br />
'''C-M-x''' with point anywhere within the expression.<br />
<br />
or<br />
<br />
'''C-x C-e''' with point following the last ')'<br />
<br />
For some users, typing 'yes' and 'no' in prompts can quickly become tiring. To instead use the 'y' and 'n' keys at these prompts:<br />
<br />
(defalias 'yes-or-no-p 'y-or-n-p)<br />
<br />
To stop the cursor blinking, use:<br />
<br />
(blink-cursor-mode -1)<br />
<br />
Similarly, to enable column-number-mode, as discussed in the previous section:<br />
<br />
(column-number-mode 1)<br />
<br />
The similarities between the previous two commands are not a coincidence: blink-cursor-mode and column-number-mode are both minor-modes. As a rule, minor-modes can be enabled given positive argument or disabled with a negative argument. Should the argument be omitted, the minor-mode will be toggled on/off.<br />
<br />
Here are some more examples of minor-modes. The following will disable the scroll bars, menu-bar and tool-bar, respectively.<br />
<br />
(scroll-bar-mode -1)<br />
(menu-bar-mode -1)<br />
(tool-bar-mode -1)<br />
<br />
The variable, 'auto-mode-alist', can be modified to change the major-mode used by default for certain file names. The following example will make the default major-mode for '.tut' and '.req' files 'text-mode'.<br />
<br />
(setq auto-mode-alist<br />
(append<br />
'(("\\.tut$" . text-mode)<br />
("\\.req$" . text-mode))<br />
auto-mode-alist))<br />
<br />
Settings can also be applied on a per-mode basis. A common method for this is to add a function to a ''hook''. For example, to force indentation to use spaces instead of tabs, but only in text-mode:<br />
<br />
(add-hook 'text-mode-hook (lambda () (setq indent-tabs-mode nil)))<br />
<br />
Similarly, to only use spaces for indentation everywhere:<br />
<br />
(setq-default indent-tabs-mode nil)<br />
<br />
Keybindings can be adjusted in two ways. The first of which is 'define-key'. 'define-key' creates a keybinding for a command but only in one mode. The example below will make '''F8''' delete any whitespace from the end of each line of a 'text-mode' buffer:<br />
<br />
(define-key text-mode-map (kbd "<f8>") 'delete-trailing-whitespace)<br />
<br />
The other method is 'global-set-key'. This is used to bind a key to a command everywhere. To bind 'query-replace-regexp' ('''C-M-%''') to '<f7>'.<br />
<br />
(global-set-key (kbd "<f7>") 'query-replace-regexp)<br />
<br />
Binding a command to an alternate key does not replace any existing bindings. Which is to say, 'query-replace-regexp' would be bound to both '''F7''' and '''C-M-%''' after the above example.<br />
<br />
Almost anything within Emacs can be configured. Browsing through the [http://emacswiki.org/ Emacs Wiki] should give a solid place to start.<br />
<br />
<br />
=== Multiple configurations ===<br />
<br />
You can use several configurations and tell Emacs to load one or the other.<br />
<br />
For example, let's define two configuration files.<br />
<br />
{{hc|.emacs|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/plugins" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
This is the full configuration we load for the daemon. But the ''plugins'' file is huge and slow to load. If we want to spaqn a new Emacs instance that does not need the ''plutings'' features, it can be cumbersome to load it everytime in the long time.<br />
<br />
{{hc|.emacs-light|<br />
(load "~/.emacs.d/main" nil t)<br />
(load "~/.emacs.d/functions" nil t)<br />
(load "~/.emacs.d/modes" nil t)<br />
(load "~/.emacs.d/theme" nil t)<br />
}}<br />
<br />
And now we launch Emacs with<br />
emacs -q -l ~/.emacs-light<br />
You can create an alias to ease the call.<br />
<br />
=== Loading extensions ===<br />
<br />
You can load extensions using the ''require'' function. For instance<br />
(require 'mediawiki)<br />
<br />
If you try using the same configuration file on a machine where mediawiki is not installed, Emacs will primpt for an error. Besides, all extension-specific code would be parsed for nothing.<br />
<br />
The trick is to test the return value of ''require'':<br />
<br />
(if (require 'mediawiki nil t)<br />
(progn<br />
(setq mediawiki-site-alist '(<br />
("ArchLinux" "https://wiki.archlinux.org/" "UserName" "" "Main Page")<br />
)<br />
)<br />
(setq mediawiki-mode-hook<br />
(lambda ()<br />
(visual-line-mode 1)<br />
(turn-off-auto-fill)<br />
))<br />
)) <br />
<br />
=== Local and custom variables ===<br />
<br />
You can define variables in your configuration file that can be later one modified locally for a file.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation")<br />
<br />
Now in any file you can define local variables in two ways:<br />
* On the very first line, write<br />
// -*- my-compiler:g++; mode:c++ -*-<br />
* If you cannot (or do not want to) write this on the first line, you can put it at the end:<br />
// Local Variables:<br />
// my-compiler: g++<br />
// mode: c++<br />
// End:<br />
<br />
Note that the beginning characters need to be comments for the current language, that's why here we used two backslashes for C++. For Elisp you would use<br />
;; -*- mode:emacs-lisp -*-<br />
<br />
There is two functions that may help you in defining the variables: ''add-file-local-variable'' and ''add-file-local-variable-prop-line''.<br />
<br />
Finally, custom variable are considered insecure by default. If you try to open a file that contains local variable redefining insecure custom variables, Emacs will ask you for confirmation.<br />
<br />
If you know what you are doing, you can declare the variable as secure, thus removing the Emacs prompt for confirmation. You need to specify a predicate that any new value has to verify so that it can be considered safe.<br />
<br />
(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)<br />
<br />
In the previous example, if you attempt to set anything else than a string, Emacs will consider it insecure.<br />
<br />
=== Custom colors and theme ===<br />
<br />
Colors can be easily customized using the ''face'' facility.<br />
(set-face-background 'region "color-17")<br />
(set-face-foreground 'region "white")<br />
(set-face-bold-p 'font-lock-builtin-face t ) <br />
<br />
You can have let Emacs tell you the name of the face where the point is. Use the ''customize-face'' function for that. The facility will show you how to set colors, bold, underline, etc.<br />
<br />
Emacs in console can handle 256 colors, but you will have to use an appropriate terminal for that. For instance URxvt has support for 256 colors. You can use the ''list-colors-display'' for a comprehensive list of supported colors. This is highly terminal-dependent.<br />
<br />
=== SyncTeX support ===<br />
<br />
Emacs is definitely one of the most powerful LaTeX editor. This is mostly due to the fact you can adapt or create a LaTeX mode to fit your needs best.<br />
<br />
Still, there might be some challenges, like SyncTeX support. First you need to make sure your TeX distribution has it. If you installed TeX Live manually, you may need to install the ''synctex'' package.<br />
# umask 022 && tlmgr install synctex<br />
<br />
SyncTeX support is viewer-dependent. Here we will use Zathura as an example, so the code needs to be adapted if you want to use another PDF viewer.<br />
<br />
(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" <br />
"PDF Viewer for TeX documents. You may want to fork the viewer<br />
so that it detects when the same document is launched twice, and<br />
persists when Emacs gets closed.<br />
<br />
Simple command:<br />
<br />
zathura --fork<br />
<br />
We can use<br />
<br />
emacsclient --eval '(progn (switch-to-buffer (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'<br />
<br />
to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."<br />
:safe 'stringp)<br />
<br />
Here we define our custom variable. If you are using AucTeX or Emacs default LaTeX-mode, you will have to set the viewer accordingly.<br />
<br />
Now open a LaTeX source file with Emacs, compile the document, and launch the viewer. Zathura will spawn. If you press {{ic|Ctrl+Left click}} Emacs should place the point at the corresponding position.<br />
<br />
== Documentation ==<br />
<br />
You may find yourself overwhelmed by the amount of Emacs features. You may find it difficult to know how to use Emacs Lisp to customize your favorite modes, or even to create your own modes / packages. Thankfully Emacs takes a strong point to auto-documenting everything: its internals, current configuration, bindings, etc. Almost everything is documented.<br />
<br />
=== Contextual help ===<br />
<br />
Emacs is self-documenting by design. As such, a great deal of information is available to determine the name of a specific command or its keybinding, for example. The following is a listing of some of the most helpful of these:<br />
<br />
'''C-h a''' Find a command matching a description.<br />
<br />
'''C-h b''' List all active keybindings.<br />
<br />
'''C-h f''' Describe the given function.<br />
<br />
'''C-h k''' Find which command a key is bound to.<br />
<br />
'''C-h m''' Display information regarding the currently active modes.<br />
<br />
'''C-h t''' Start the Emacs tutorial.<br />
<br />
'''C-h v''' Describe the given variable.<br />
<br />
'''C-h w''' Find which key(s) a command is bound to.<br />
<br />
=== The manuals ===<br />
<br />
If you really want to master Emacs, the most recommanded source of documentation remains the official manuals:<br />
* Emacs: the complete Emacs user manual.<br />
* Emacs FAQ.<br />
* Emacs Lisp Intro: if you never used any programming language before.<br />
* Elisp: if you are already familiar with a programming language.<br />
<br />
You can access it as PDFs from [http://www.gnu.org/software/emacs/manual/ GNU.org] or directly from Emacs itself thanks to the embedded 'info' reader: '''C-h i'''. Press '''m''' to choose a book.<br />
<br />
Some users prefer to read books using 'info' because of its convenient shortcuts, its paragraphs adapting to window width and the font adapted to current screen resolution. Some find it less irritating to the eyes. Finally you can easily copy content from the book to any Emacs buffer, and you can even execute Lisp code snippets directly from the examples.<br />
<br />
You may want to read the '''Info''' book to know more about it: '''C-h i m info <RET>'''.<br />
Press '''?''' while in info mode for a quick list of shortcuts.<br />
<br />
== 拓展模块 ==<br />
<br />
虽然Emacs包含了成百上千种模式(mode),库和其它扩展,还有更多的扩展来增强Emacs。大多数扩展会详细说明安装它的时候要对~/.emacs作什么改动。这些说明一般会在一个elisp源文件开头的注释中,或者在一个README中(如果这个扩展包含了多个源文件)。<br />
<br />
在'community'仓库中有很多流行的扩展,更多的扩展还放在了[[AUR]]。这些软件包的名字有一个'emacs-'前缀(比如emacs-lua-mode)。在很多情况下,在安装的过程会显示怎样修改~/.emacs以安装该扩展到Emacs中。<br />
<br />
想知道怎样激活一个不在上面提到的地方的扩展,查看[http://emacswiki.org/ Emacs Wiki]中的相应页面,一般会提供一个配置的例子。Emacs Wiki也是一个寻找扩展的优秀资源。<br />
<br />
你也可以使用[http://tromey.com/elpa/ Emacs Lisp Package Archive (ELPA)] 来自动安装软件包。打开那个网站看说明。ELPA已经包括在了Emacs24中;它已经作为Emacs生态系统中的一部分了。<br />
<br />
== 疑难杂症 ==<br />
<br />
===彩色输出的问题===<br />
Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。<br />
<br />
在{{ic|~/.emacs}}中加入下面的代码解决这个问题:<br />
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)<br />
<br />
===菜单显示为空===<br />
一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550541 Debian bug report] 有一个应对措施。<br />
<br />
=== X 窗口下的字符显示问题 ===<br />
当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 {{pkg|xorg-fonts-75dpi}} 或者 {{pkg|xorg-fonts-100dpi}} 并且重启X窗口。<br />
<br />
=== 启动速度慢 ===<br />
启动速度慢经常是由下面两种情况引起的。<br />
<br />
要确定是哪种情况,这样打开Emacs:<br />
<br />
$ emacs -q<br />
<br />
如果Emacs还是启动很慢,则是[[Emacs#Incorrect network configuration|错误的网络配置]]。如果不是,则可以确定是[[Emacs#Init file loads slowly|.emacs的问题]]。<br />
<br />
====错误的网络配置====<br />
<br />
当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'[[Configuring_network#Set_the_hostname|set the hostname]]' 了解更多内容。<br />
<br />
====初始化文件加载慢====<br />
<br />
一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:<br />
<br />
(require 'anything)<br />
<br />
你应该这样:<br />
<br />
(autoload 'anything "anything" "Select anything" t)<br />
<br />
=== 不能打开配置文件: ... ===<br />
<br />
这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:<br />
<br />
(add-to-list 'load-path "/path/to/directory/")<br />
<br />
当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:<br />
<br />
(add-to-list 'load-path "/usr/share/emacs/site-lisp")<br />
<br />
如果手动编译Emacs,记住默认的前缀是'/usr/local'。<br />
<br />
=== Dead-accent keys problem: '<dead-acute> is undefined' ===<br />
<br />
Searching about this bug on Google, we find this link:<br />
http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html<br />
<br />
Explaining the problem: in recent versions of<br />
b72<br />
Emacs, the normal way to use accent keys doesn't work as expected. Trying to accent a word like 'fiancé' will produce the message above.<br />
<br />
A way to solve it is just put the line above on your startup file, {{ic|~/.emacs}}:<br />
<br />
(require 'iso-transl)<br />
<br />
And no, it isn't a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (http://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):<br />
<br />
:''It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be<br />
a3b<br />
classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. ''<br />
<br />
=== C-M-% and some other bindings do not work in emacs nox ===<br />
<br />
This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:<br />
* either use the graphical version,<br />
* or change the binding to a supported one.<br />
<br />
Example:<br />
{{hc|.emacs|<br />
(global-set-key (kbd "C-M-y") 'query-replace-regexp)<br />
}}<br />
<br />
=== Emacs client gets stuck when switching back to it ===<br />
<br />
If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an '''M-x''' for instance), then all other instance will wait for it to finish. Press '''C-g''' to cancel any input to make sure this Emacs session is not blocking.<br />
<br />
=== Emacs-nox output gets messy ===<br />
<br />
When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal.<br />
There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.<br />
<br />
Graphical Emacs does not suffer from this issue.<br />
<br />
=== Shift + Arrow keys not working in emacs within tmux ===<br />
<br />
First you must enable xterm-keys in your [[tmux]] config.<br />
{{hc|.tmux.conf|<br />
setw -g xterm-keys on<br />
}}<br />
<br />
But, this will break other key combinations. To fix them, put the following in your emacs config.<br />
{{hc|.emacs|<br />
;; handle tmux's xterm-keys<br />
;; put the following line in your ~/.tmux.conf:<br />
;; setw -g xterm-keys on<br />
(if (getenv "TMUX")<br />
(progn<br />
(let ((x 2) (tkey ""))<br />
(while (<&#61; x 8)<br />
;; shift<br />
(if (&#61; x 2)<br />
(setq tkey "S-"))<br />
;; alt<br />
(if (&#61; x 3)<br />
(setq tkey "M-"))<br />
;; alt + shift<br />
(if (&#61; x 4)<br />
(setq tkey "M-S-"))<br />
;; ctrl<br />
(if (&#61; x 5)<br />
(setq tkey "C-"))<br />
;; ctrl + shift<br />
(if (&#61; x 6)<br />
(setq tkey "C-S-"))<br />
;; ctrl + alt<br />
(if (&#61; x 7)<br />
(setq tkey "C-M-"))<br />
;; ctrl + alt + shift<br />
(if (&#61; x 8)<br />
(setq tkey "C-M-S-"))<br />
<br />
;; arrows<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))<br />
;; home<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))<br />
;; end<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))<br />
;; page up<br />
(define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))<br />
;; page down<br />
(define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))<br />
;; insert<br />
(define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; delete<br />
(define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))<br />
;; f1<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))<br />
;; f2<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))<br />
;; f3<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))<br />
;; f4<br />
(define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))<br />
;; f5<br />
(define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))<br />
;; f6<br />
(define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))<br />
;; f7<br />
(define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))<br />
;; f8<br />
(define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))<br />
;; f9<br />
(define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))<br />
;; f10<br />
(define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))<br />
;; f11<br />
(define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))<br />
;; f12<br />
(define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))<br />
;; f13<br />
(define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))<br />
;; f14<br />
(define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))<br />
;; f15<br />
(define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))<br />
;; f16<br />
(define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))<br />
;; f17<br />
(define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))<br />
;; f18<br />
(define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))<br />
;; f19<br />
(define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))<br />
;; f20<br />
(define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))<br />
<br />
(setq x (+ x 1))<br />
))<br />
)<br />
)<br />
}}<br />
<br />
== 替代方案 ==<br />
<br />
有很多Emacs的实现。GNU/Emacs 可能是最受欢迎的了。<br><br />
更轻量的兼容性较好的Emacs可以在Arch仓库或在[https://aur.archlinux.org/ AUR]中找到。<br />
<br />
=== mg ===<br />
<br />
mg(原来叫MicroGnuEmacs),是用C语言实现的轻量级Emacs。<br />
<br />
可以从{{ic|community}中安装mg<br />
# pacman -S mg<br />
或者从官方网站[http://homepage.boetes.org/software/mg/ page]中下载源代码。<br />
<br />
=== zile ===<br />
<br />
引用官方网站[https://www.gnu.org/software/zile/ page]的描述,"GNU Zile is a lightweight Emacs clone. Zile is short for Zile Is Lossy Emacs. Zile has been written to be as similar as possible to Emacs; every Emacs user should feel at home.",意思是'GNU Zile'是一个轻量级的Emacs的克隆。Zile是'Zile Is Lossy Emacs'的缩写。<br />
Zile的实现与Emacs如此相似以至于每个Emacs用户使用Zile一定会有一种宾至如归的感觉。<br />
<br />
zile 可以在{{ic|extra}}中找到<br />
<br />
# pacman -S zile<br />
<br />
最新的tarball可以在GNU的官方源[http://ftp.sh.cvut.cz/MIRRORS/gnu/pub/gnu/zile/ mirrors]中找到。<br />
<br />
=== uemacs ===<br />
<br />
uemacs 是由Linus Torvalds定制的微型Emacs版本。<br />
它可以在 [https://aur.archlinux.org/ AUR] 的 [https://aur.archlinux.org/packages.php?ID=31502 uemacs]中找到。<br />
<br />
== 资源 ==<br />
* [http://www.gnu.org/software/emacs/ GNU Emacs home page]<br />
* [http://www.gnu.org/software/emacs/manual/emacs.html GNU Emacs Manual]<br />
* [http://www.emacswiki.org/cgi-bin/wiki/ Emacs Wiki]<br />
* [http://wikemacs.org WikEmacs - a more readable, but less complete Emacs Wiki]<br />
* [http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Useful introduction to Emacs and its shortcuts]<br />
* [http://www.dina.kvl.dk/~abraham/religion/ The Church of Emacs]<br />
* [http://repo.or.cz/w/emacs.git/blob/HEAD:/etc/refcards/refcard.pdf Official reference card]</div>HelloCodehttps://wiki.archlinux.org/index.php?title=ArchWiki:Translation_Team_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=349112ArchWiki:Translation Team (简体中文)2014-12-08T14:13:13Z<p>HelloCode: /* 页面维护列表 */</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:ArchWiki (简体中文)]]<br />
[[ar:ArchWiki Translation Team]]<br />
[[el:ArchWiki Translation Team]]<br />
[[en:ArchWiki Translation Team]]<br />
[[es:ArchWiki Translation Team]]<br />
[[hr:ArchWiki Translation Team]]<br />
[[it:ArchWiki Translation Team]]<br />
[[ja:ArchWiki Translation Team]]<br />
[[pl:ArchWiki Translation Team]]<br />
[[pt:ArchWiki Translation Team]]<br />
[[ru:ArchWiki Translation Team]]<br />
[[tr:ArchWiki_Çeviri_Ekibi]]<br />
Arch Wiki 上有许多中文页面,这些页面是无数中文志愿者劳动的结晶。随着时间推移,有些页面因为没有及时维护,内容严重过时。而目前的翻译工作缺少组织,效率偏低。所以参照西班牙和意大利翻译组的做法,添加这个页面。<br />
<br />
如果希望进行翻译和维护,只需要编辑下面的[[#页面维护列表]],将自己加为页面的维护者。如果列表中还没有要认领翻译的页面,请自行添加。如果因为时间原因无法再维护页面,请及时将自己从维护者列表中删除。<br />
<br />
== 创建翻译 ==<br />
{{注意|如果不准备翻译页面的大部分内容,请尽量不要新建简体中文页面。检查英文页面的更新需要花费不少精力,没有翻译的页面会增加维护负担。}}<br />
# 如果还不知道如何编辑 wiki,请阅读 [[Help:Editing (简体中文)|编辑帮助]]。<br />
# 阅读 [[Help:i18n (简体中文)|i18n帮助]],文章给出了 ArchWiki 国际化和本地化的指南。<br />
# [[Special:UserLogin |登录]] 以进行编辑。<br />
# 选择要翻译的页面,例如从 [[Special:Random|随机页面]] 或[[#页面维护列表 | 页面维护列表]] 中选择一个未翻译完成的页面。假设要翻译 [[Some Page]].<br />
# 进入选择的英文页面,点击页面顶部的 '''编辑'''。<br />
# 添加要翻译文件的语言间链接, 中文的话加入<nowiki>[[zh-cn:Some Page]]</nowiki>,其它语言参见[[Help:i18n#Interlanguage links]])。<br />
# 复制所有页面代码。<br />
# 保存页面 (新加了语言链接)<br />
# 访问页面左边新添加的语言链接,应该会进到 [[Some Page (简体中文)]] : {{ic|<nowiki>https://wiki.archlinux.org/index.php/Some_Page_(</nowiki>''简体中文'')}}<br />
# 因为页面不存在,点击 '''创建'''。<br />
# 将显示一个编辑器 - 粘贴复制的英文页面。<br />
# 将文章分类修改为本地化版本,例如将 {{ic|<nowiki>[[Category:Internationalization]]</nowiki>}} 修改为 {{ic|<nowiki>[[Category:Internationalization (简体中文)]]</nowiki>}},参阅[[Help:Category (简体中文)]].<br />
# 修改语言间链接,指向英文页面(将 {{ic|zh-CN}} 修改为 {{ic|en}},并将英文页面移到文章顶部。<br />
# 翻译页面,进行保存。<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
# 更新所有其它语言页面,加入刚翻译文章的语言间链接。<br />
# (可选)创建一个简体中文名称的页面,指向新创建的页面:访问 {{ic|<nowiki>https://wiki.archlinux.org/index.php/</nowiki>''页面的中文名称''}}.<br />
# (可选)建立新页面,并加入:{{bc|<nowiki>#REDIRECT [[Some Page (简体中文)</nowiki>]]}}<br />
<br />
== 完善翻译 ==<br />
[https://wiki.archlinux.org/index.php?title=Special:WhatLinksHere/Template:Translateme_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&limit=100 这个页面] 包含了需要完善翻译的简体中文页面。完善翻译的基本步骤:<br />
# 选择自己比较熟悉的文章进行翻译<br />
# 先检查英文页面的对应段落,更新成最新的英文后再翻译,避免翻译过时的内容,减少信息遗漏。<br />
# 翻译完成后删除页面中的 <nowiki>{{translateme (简体中文)}}</nowiki> 标记<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
<br />
== 更新过期页面 == <br />
如果发现有 Wiki 页面过期或错误:<br />
* 小的改动,有时间可以立即进行修改同步,维护者并不控制页面的编辑权限,越多的人参与维护越好。如果改动较大,请先联系维护者,避免重复劳动。<br />
* 没有时间查看更改,请给页面加上 {{ic|<nowiki>{{out of date}}</nowiki>}} 模版,这样其他贡献者更容易发现需要更新的页面,而读者看到过期标记就可以直接查看英文页面,以免被错误内容误导,白白耽误时间。<br />
* 没有时间翻译,请将过期的中文部分删去,从英文页面中复制更改的部分到中文页面的相应部分,去掉{{ic|<nowiki>{{out of date}}</nowiki>}}模板(如果页面上有的话)并加上{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他贡献者就更容易发现需要翻译的页面,而读者也不会被过期的内容误导。<br />
如果发现有页面未翻译:<br />
* 有时间的话,请将页面中的英文部分翻译为中文,并去掉{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板。<br />
* 没有时间翻译,请为页面添加{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他的贡献者就能更容易发现需要翻译的页面。<br />
{{注意|在修改页面上的模板时,请同时更新页面维护列表的翻译状态。}}<br />
<br />
== 贡献列表 ==<br />
为翻译做出贡献的用户请加入列表,感谢所有人做出的贡献。<br />
* [[User:Fengchao|Fengchao]] &ndash; [[Special:Contributions/Fengchao|贡献]] &ndash; [[Special:EmailUser/Fengchao|Send Email]] &ndash; [[ArchWiki:Administrators|ArchWiki Administrators]]<br />
* [[User:Skydiver|Skydiver]] &ndash; [[Special:Contributions/Skydiver|贡献]] &ndash; [[Special:EmailUser/Skydiver|Send Email]] &ndash; [[ArchWiki:Maintainers|ArchWiki Maintainers]]<br />
* [[User:Alswl|Alswl]] &ndash; [[Special:Contributions/Alswl|贡献]] &ndash; [[Special:EmailUser/Alswl|Send Email]]<br />
* [[User:Joshua83|Joshua]] &ndash; [[Special:Contributions/Joshua83|贡献]] &ndash; [[Special:EmailUser/Joshua83|Send Email]]<br />
* [[User:Reverland|Reverland]] &ndash; [[Special:Contributions/Reverland|贡献]] &ndash; [[Special:EmailUser/Reverland|Send Email]]<br />
* [[User:Cuihao|cuihao]] &ndash; [[Special:Contributions/Cuihao|贡献]] &ndash; [[Special:EmailUser/Cuihao|Send Email]]<br />
* [[User:Cael|Cael]] &ndash; [[Special:Contributions/Cael|贡献]] &ndash; [[Special:EmailUser/Cael|Send Email]]<br />
* [[User:Flockyrocky|Flockyrocky]] &ndash; [[Special:Contributions/Flockyrocky|贡献]] &ndash; [[Special:EmailUser/Flockyrocky|Send Email]]<br />
* [[User:Tuxzz|Tuxzz]] &ndash; [[Special:Contributions/Tuxzz|贡献]] &ndash; [[Special:EmailUser/Tuxzz|Send Email]]<br />
* [[User:Aaron_chen|Aaron_chen]] &ndash; [[Special:Contributions/Aaron_chen|贡献]] &ndash; [[Special:EmailUser/Aaron_chen|Send Email]]<br />
* [[User:Shibao Zhao|Shibao Zhao]] &ndash; [[Special:Contributions/Shibao Zhao|贡献]] &ndash; [[Special:EmailUser/Shibao Zhao|Send Email]]<br />
* [[User:Radflum|Yk]] &ndash; [[Special:Contributions/Radflum|贡献]] &ndash; [[Special:EmailUser/Radflum|Send Email]]<br />
* [[User:Hang yan|Hang yan]] &ndash; [[Special:Contributions/Hang yan|贡献]] &ndash; [[Special:EmailUser/Hang yan|Send Email]]<br />
* [[User:Acgtyrant|Acgtyrant]] &ndash; [[Special:Contributions/Acgtyrant|贡献]] &ndash; [[Special:EmailUser/Acgtyrant|Send Email]]<br />
* [[User:Xuchunyang|Xuchunyang]] &ndash; [[Special:Contributions/Acgtyrant|贡献]] &ndash; [[Special:EmailUser/Acgtyrant|Send Email]]<br />
* [[User:Stlt1sean|Stlt1sean]] &ndash; [[Special:Contributions/Stlt1sean|贡献]] &ndash; [[Special:EmailUser/Stlt1sean|Send Email]]<br />
* [[User:Carl_tw|Carl X. Su]] &ndash; [[Special:Contributions/Carl_tw|贡献]] &ndash; [[Special:EmailUser/Carl_tw|Send Email]]<br />
* [[User:SteamedFish|SteamedFish]] &ndash; [[Special:Contributions/SteamedFish|贡献]] &ndash; [[Special:EmailUser/SteamedFish|Send Email]]<br />
* [[User:Zer4tul|Zer4tul]] &ndash; [[Special:Contributions/Zer4tul|贡献]] &ndash; [[Special:EmailUser/Zer4tul|Send Email]]<br />
* [[User:Mac_uestc|Mac.Bloom]] &ndash; [[Special:Contributions/Mac_uestc|贡献]] &ndash; [[Special:EmailUser/Mac_uestc|Send Email]]<br />
* [[User:Zguangyu0000|Guangyu Zhang]] &ndash; [[Special:Contributions/Zguangyu0000|贡献]] &ndash; [[Special:EmailUser/Zguangyu0000|Send Email]]<br />
* [[User:Xinkai|Xinkai]] &ndash; [[Special:Contributions/Xinkai|贡献]] &ndash; [[Special:EmailUser/Xinkai|Send Email]]<br />
* [[User:Spaike97|_spaike97]] &ndash; [[Special:Contributions/Spaike97|贡献]] &ndash; [[Special:EmailUser/Spaike97|Send Email]]<br />
* [[User:jazzi|jazzi]] &ndash; [[Special:Contributions/jazzi|贡献]] &ndash; [[Special:EmailUser/jazzi|Send Email]]<br />
* [[User:HelloCode|HelloCode]] &ndash; [[Special:Contributions/HelloCode|贡献]] &ndash; [[Special:EmailUser/HelloCode|Send Email]]<br />
<br />
== 翻译任务 ==<br />
=== 模板 Article summary 变更为 Related ===<br />
因为 Summary 中的简介基本上和正文的介绍一样,所以页面左边的介绍栏进行了简化,只保留相关文章功能。英文页面正在进行大规模修改,相应的中文页面也需要同步更新。<br />
<br />
需要注意的地方:<br />
* 将第一行改成<br />
: <nowiki>{{Related articles start (简体中文)}}</nowiki><br />
* 如果英文的相关文章存在中文翻译,则替换为简体中文页面。示例:<br />
: <nowiki>{{Related2|Display Manager (简体中文)|显示管理器}}</nowiki><br />
* 示例:[https://wiki.archlinux.org/index.php?title=Start_X_at_Login&diff=0&oldid=270155 英文变更], [https://wiki.archlinux.org/index.php?title=Start_X_at_Login_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=285643&oldid=242662 对应的翻译]<br />
<br />
== 维护翻译 ==<br />
完成页面的翻译只是初步完成任务,及时同步英文页面改动、更新翻译是一个持续性的工作,可能会耗费更多的时间。<br />
<br />
=== 页面认领 ===<br />
所有人都可以认领页面。认领后的责任包括进行翻译,关注英文页面的改动,及时同步翻译。<br />
<br />
为了更好的跟踪英文页面的修改,请务必在设置中启用监视列表邮件通知,并监视对应的英文页面(从设置中找到监视列表,加入英文页面。或者直接到英文页面点击页面顶端的监视标签。这样只要有改动,就会收到邮件通知)。<br />
<br />
{{小贴士|如果收到邮件通知后没有访问页面或者访问了页面却没有登录用户,下次页面改动时就不会再发邮件通知。可以点击监视列表中的'''标记所有页面为已读'''再次获取更新。}}<br />
<br />
如果页面有维护者但长期得不到更新,将会在维护列表中删除维护者。<br />
<br />
=== 翻译状态模板 ===<br />
Arch 作为滚动发行版,软件变化比较快,对应的文档变化也比较快。许多翻译的文章由于缺乏更新,会产生命令运行出错或不起作用等问题。而由于这些过期页面没有及时标记出来,所以用户无法及时获得更新。[[Template:TranslationStatus (简体中文)|翻译状态模板]]就是为了解决这个问题而创建。<br />
<br />
此模板可以起到如下作用:<br />
* 为用户提供翻译状况,包括翻译时间、英文页面的最后版本等<br />
* 用户可以点击查看翻译后,英文页面的改动,这样英文不是很好的用户可以只查看很小一部分英文内容,并判断出是否影响操作。<br />
* 翻译人员可以跟踪页面状况,通过[https://wiki.archlinux.org/index.php/Special:WhatLinksHere/Template:TranslationStatus_(简体中文) 模板的反向链接]可以查找到所有标记页面,查看需要更新翻译的部分。<br />
<br />
[[Template:TranslationStatus (简体中文)|模板页面]]有详细的使用方法。<br />
<br />
=== 页面维护列表 ===<br />
{{注意|请按照拉丁字母顺序添加页面。}}<br />
<br />
翻译状态说明:<br />
;过期:页面内容未与英文页面同步,对应{{ic|<nowiki>{{out of date}}</nowiki>}} 模版<br />
;未翻译:页面中含有英文内容,对应{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板<br />
;完成:页面已与英文页面同步<br />
<br />
需要优先翻译的页面:<br />
<br />
{| class="wikitable sortable collapsible" border="1"<br />
|-<br />
! 页面<br />
! 翻译状态<br />
! 维护者<br />
! class="unsortable" width="30%" | 备注<br />
|-<br />
| [[acpid (简体中文)]]<br />
| 过期<br />
| Cael<br />
|-<br />
| [[Advanced Linux Sound Architecture (简体中文)]]<br />
| 翻译中<br />
| ihonliu<br />
| 无<br />
|-<br />
| [[Arch Based Distributions (Active) (简体中文)]]<br />
| 完成<br />
| Joshua<br />
| 勘误中<br />
|-<br />
| [[ATI (简体中文)]]<br />
| 过期<br />
| 无<br />
| 请优先翻译此文<br />
|-<br />
| [[AUR Helpers (简体中文)]]<br />
| 进行中<br />
| Stonex<br />
| 无<br />
|-<br />
| [[awesome (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无<br />
|-<br />
| [[BIND (简体中文)]]<br />
| 翻译中<br />
| SteamedFish<br />
| 无<br />
|-<br />
| [[Bumblebee (简体中文)]]<br />
| 未翻译<br />
| Peter<br />
| 无<br />
|-<br />
| [[AMD Catalyst (简体中文)]]<br />
| 过期<br />
| Shibao Zhao<br />
| 无<br />
|-<br />
| [[Chromium (简体中文)]]<br />
| 翻译中<br />
| Bobby<br />
| 部分未翻译 <br />
|-<br />
| [[Cinnamon (简体中文)]]<br />
| 部分翻译 <br />
| Bobby<br />
| 部分未翻译 <br />
|- <br />
| [[Common Applications (简体中文)]]<br />
| 部分翻译 <br />
| DavidChen<br />
| 翻译中<br />
|-<br />
| [[Common Applications/Science (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 无<br />
|-<br />
| [[Compiz (简体中文)]]<br />
| 翻译中<br />
| xiii_1991<br />
| 20140813开始<br />
|-<br />
| [[Core Utilities (简体中文)]]<br />
| 翻译中<br />
| rentaro<br />
| 同步翻译至2014年7月23日08:13英文页面,完善中<br />
|-<br />
| [[Disk Cloning (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Emacs (简体中文)]]<br />
| 翻译中<br />
| Jaurung yuanhang<br />
| 未完成<br />
|-<br />
| [[File recovery (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Font Configuration (简体中文)]]<br />
| 翻译中<br />
| Jaurung<br />
| 完善中<br />
|-<br />
| [[Fonts (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[LAMP (简体中文)]]<br />
| 完成<br />
| Liuzhengyi<br />
| 勘误中<br />
|-<br />
| [[LibreOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Local Mirror (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[NetworkManager (简体中文)]]<br />
| 部分翻译 <br />
| Jack-lijing <br />
| 请优先翻译<br />
|-<br />
| [[Network Time Protocol daemon (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 部分未翻译<br />
|-<br />
| [[OpenOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Opera (简体中文)]]<br />
| 未翻译<br />
| Bobby<br />
| 请优先翻译此文 <br />
|-<br />
| [[Pacman GUI Frontends (简体中文)]]<br />
| 翻译中<br />
| KaiYuan Guo<br />
| 无<br />
|-<br />
| [[Pidgin (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无 <br />
|- <br />
| [[Plasma (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 无<br />
|-<br />
| [[ranger (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[Reporting_Bug_Guidelines_(简体中文)]]<br />
| 翻译中<br />
| Jason Zhang<br />
| <br />
|-<br />
| [[Smart Common Input Method platform (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Secure Shell (简体中文)]]<br />
| 完成<br />
| HelloCode<br />
| 完成<br />
|-<br />
| [[VirtualBox (简体中文)]] || 翻译中 || Carl X. Su || 请优先翻译此文<br />
|-<br />
| [[VirtualBox Extras (简体中文)]] || 部分翻译 || 无 || 需要合并到 [[VirtualBox (简体中文)]]<br />
|-<br />
| [[VMware (简体中文)]] || 翻译中 || Jason Zhang || 无<br />
|- <br />
| [[Xfce (简体中文)]] || 翻译中 || ZaticWu || 请优先翻译<br />
|-<br />
| [[Xmonad (简体中文)]]<br />
| 未翻译<br />
| Rns<br />
| 翻译中<br />
|-<br />
| [[Xrandr (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=349106OpenSSH (简体中文)2014-12-08T14:06:13Z<p>HelloCode: /* SSH服务开启并且在监听吗? */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务是否开启并且正在监听吗? ====<br />
$ ssh -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{ic|/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是NAT路由的问题,祝你好运!)<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
最近版本的openssh有时候会因为以上信息崩溃,据说是elliptic curve 加密的bug。在这种情况下,请编辑这个文件:<br />
<br />
~/.ssh/config<br />
<br />
如果不存在,就创建它,然后加入以下内容:<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
在openssh5.9中,以上的修复工作不会奏效。不过,还可以这样做:<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
可以访问[http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion]来查看openssh的bug问题.<br />
<br />
=== "[your shell]: No such file or directory" / ssh认证问题 ===<br />
<br />
对于这个问题,一个可能的原因是需要SSH客户端在{{Ic|$SHELL}}中提供绝对路径(例如可以通过{{Ic|whereis -b [your shell]}}得到),即使你的shell在{{Ic|$PATH}}中。另一个原因也可能是,用户不是''network''组的成员。<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348294OpenSSH (简体中文)2014-12-05T11:35:20Z<p>HelloCode: /* Read from socket failed: Connection reset by peer */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是NAT路由的问题,祝你好运!)<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
最近版本的openssh有时候会因为以上信息崩溃,据说是elliptic curve 加密的bug。在这种情况下,请编辑这个文件:<br />
<br />
~/.ssh/config<br />
<br />
如果不存在,就创建它,然后加入以下内容:<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
在openssh5.9中,以上的修复工作不会奏效。不过,还可以这样做:<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
可以访问[http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion]来查看openssh的bug问题.<br />
<br />
=== "[your shell]: No such file or directory" / ssh认证问题 ===<br />
<br />
对于这个问题,一个可能的原因是需要SSH客户端在{{Ic|$SHELL}}中提供绝对路径(例如可以通过{{Ic|whereis -b [your shell]}}得到),即使你的shell在{{Ic|$PATH}}中。另一个原因也可能是,用户不是''network''组的成员。<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348292OpenSSH (简体中文)2014-12-05T11:31:29Z<p>HelloCode: /* Is the traffic even getting to your computer? */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是NAT路由的问题,祝你好运!)<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh认证问题 ===<br />
<br />
对于这个问题,一个可能的原因是需要SSH客户端在{{Ic|$SHELL}}中提供绝对路径(例如可以通过{{Ic|whereis -b [your shell]}}得到),即使你的shell在{{Ic|$PATH}}中。另一个原因也可能是,用户不是''network''组的成员。<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348290OpenSSH (简体中文)2014-12-05T11:27:47Z<p>HelloCode: </p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh认证问题 ===<br />
<br />
对于这个问题,一个可能的原因是需要SSH客户端在{{Ic|$SHELL}}中提供绝对路径(例如可以通过{{Ic|whereis -b [your shell]}}得到),即使你的shell在{{Ic|$PATH}}中。另一个原因也可能是,用户不是''network''组的成员。<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=ArchWiki:Translation_Team_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348289ArchWiki:Translation Team (简体中文)2014-12-05T11:26:37Z<p>HelloCode: /* 贡献列表 */</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:ArchWiki (简体中文)]]<br />
[[ar:ArchWiki Translation Team]]<br />
[[el:ArchWiki Translation Team]]<br />
[[en:ArchWiki Translation Team]]<br />
[[es:ArchWiki Translation Team]]<br />
[[hr:ArchWiki Translation Team]]<br />
[[it:ArchWiki Translation Team]]<br />
[[ja:ArchWiki Translation Team]]<br />
[[pl:ArchWiki Translation Team]]<br />
[[pt:ArchWiki Translation Team]]<br />
[[ru:ArchWiki Translation Team]]<br />
[[tr:ArchWiki_Çeviri_Ekibi]]<br />
Arch Wiki 上有许多中文页面,这些页面是无数中文志愿者劳动的结晶。随着时间推移,有些页面因为没有及时维护,内容严重过时。而目前的翻译工作缺少组织,效率偏低。所以参照西班牙和意大利翻译组的做法,添加这个页面。<br />
<br />
如果希望进行翻译和维护,只需要编辑下面的[[#页面维护列表]],将自己加为页面的维护者。如果列表中还没有要认领翻译的页面,请自行添加。如果因为时间原因无法再维护页面,请及时将自己从维护者列表中删除。<br />
<br />
== 创建翻译 ==<br />
{{注意|如果不准备翻译页面的大部分内容,请尽量不要新建简体中文页面。检查英文页面的更新需要花费不少精力,没有翻译的页面会增加维护负担。}}<br />
# 如果还不知道如何编辑 wiki,请阅读 [[Help:Editing (简体中文)|编辑帮助]]。<br />
# 阅读 [[Help:i18n (简体中文)|i18n帮助]],文章给出了 ArchWiki 国际化和本地化的指南。<br />
# [[Special:UserLogin |登录]] 以进行编辑。<br />
# 选择要翻译的页面,例如从 [[Special:Random|随机页面]] 或[[#页面维护列表 | 页面维护列表]] 中选择一个未翻译完成的页面。假设要翻译 [[Some Page]].<br />
# 进入选择的英文页面,点击页面顶部的 '''编辑'''。<br />
# 添加要翻译文件的语言间链接, 中文的话加入<nowiki>[[zh-cn:Some Page]]</nowiki>,其它语言参见[[Help:i18n#Interlanguage links]])。<br />
# 复制所有页面代码。<br />
# 保存页面 (新加了语言链接)<br />
# 访问页面左边新添加的语言链接,应该会进到 [[Some Page (简体中文)]] : {{ic|<nowiki>https://wiki.archlinux.org/index.php/Some_Page_(</nowiki>''简体中文'')}}<br />
# 因为页面不存在,点击 '''创建'''。<br />
# 将显示一个编辑器 - 粘贴复制的英文页面。<br />
# 将文章分类修改为本地化版本,例如将 {{ic|<nowiki>[[Category:Internationalization]]</nowiki>}} 修改为 {{ic|<nowiki>[[Category:Internationalization (简体中文)]]</nowiki>}},参阅[[Help:Category (简体中文)]].<br />
# 修改语言间链接,指向英文页面(将 {{ic|zh-CN}} 修改为 {{ic|en}},并将英文页面移到文章顶部。<br />
# 翻译页面,进行保存。<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
# 更新所有其它语言页面,加入刚翻译文章的语言间链接。<br />
# (可选)创建一个简体中文名称的页面,指向新创建的页面:访问 {{ic|<nowiki>https://wiki.archlinux.org/index.php/</nowiki>''页面的中文名称''}}.<br />
# (可选)建立新页面,并加入:{{bc|<nowiki>#REDIRECT [[Some Page (简体中文)</nowiki>]]}}<br />
<br />
== 完善翻译 ==<br />
[https://wiki.archlinux.org/index.php?title=Special:WhatLinksHere/Template:Translateme_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&limit=100 这个页面] 包含了需要完善翻译的简体中文页面。完善翻译的基本步骤:<br />
# 选择自己比较熟悉的文章进行翻译<br />
# 先检查英文页面的对应段落,更新成最新的英文后再翻译,避免翻译过时的内容,减少信息遗漏。<br />
# 翻译完成后删除页面中的 <nowiki>{{translateme (简体中文)}}</nowiki> 标记<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
<br />
== 更新过期页面 == <br />
如果发现有 Wiki 页面过期或错误:<br />
* 小的改动,有时间可以立即进行修改同步,维护者并不控制页面的编辑权限,越多的人参与维护越好。如果改动较大,请先联系维护者,避免重复劳动。<br />
* 没有时间查看更改,请给页面加上 {{ic|<nowiki>{{out of date}}</nowiki>}} 模版,这样其他贡献者更容易发现需要更新的页面,而读者看到过期标记就可以直接查看英文页面,以免被错误内容误导,白白耽误时间。<br />
* 没有时间翻译,请将过期的中文部分删去,从英文页面中复制更改的部分到中文页面的相应部分,去掉{{ic|<nowiki>{{out of date}}</nowiki>}}模板(如果页面上有的话)并加上{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他贡献者就更容易发现需要翻译的页面,而读者也不会被过期的内容误导。<br />
如果发现有页面未翻译:<br />
* 有时间的话,请将页面中的英文部分翻译为中文,并去掉{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板。<br />
* 没有时间翻译,请为页面添加{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他的贡献者就能更容易发现需要翻译的页面。<br />
{{注意|在修改页面上的模板时,请同时更新页面维护列表的翻译状态。}}<br />
<br />
== 贡献列表 ==<br />
为翻译做出贡献的用户请加入列表,感谢所有人做出的贡献。<br />
* [[User:Fengchao|Fengchao]] &ndash; [[Special:Contributions/Fengchao|贡献]] &ndash; [[Special:EmailUser/Fengchao|Send Email]] &ndash; [[ArchWiki:Administrators|ArchWiki Administrators]]<br />
* [[User:Skydiver|Skydiver]] &ndash; [[Special:Contributions/Skydiver|贡献]] &ndash; [[Special:EmailUser/Skydiver|Send Email]] &ndash; [[ArchWiki:Maintainers|ArchWiki Maintainers]]<br />
* [[User:Alswl|Alswl]] &ndash; [[Special:Contributions/Alswl|贡献]] &ndash; [[Special:EmailUser/Alswl|Send Email]]<br />
* [[User:Joshua83|Joshua]] &ndash; [[Special:Contributions/Joshua83|贡献]] &ndash; [[Special:EmailUser/Joshua83|Send Email]]<br />
* [[User:Reverland|Reverland]] &ndash; [[Special:Contributions/Reverland|贡献]] &ndash; [[Special:EmailUser/Reverland|Send Email]]<br />
* [[User:Cuihao|cuihao]] &ndash; [[Special:Contributions/Cuihao|贡献]] &ndash; [[Special:EmailUser/Cuihao|Send Email]]<br />
* [[User:Cael|Cael]] &ndash; [[Special:Contributions/Cael|贡献]] &ndash; [[Special:EmailUser/Cael|Send Email]]<br />
* [[User:Flockyrocky|Flockyrocky]] &ndash; [[Special:Contributions/Flockyrocky|贡献]] &ndash; [[Special:EmailUser/Flockyrocky|Send Email]]<br />
* [[User:Tuxzz|Tuxzz]] &ndash; [[Special:Contributions/Tuxzz|贡献]] &ndash; [[Special:EmailUser/Tuxzz|Send Email]]<br />
* [[User:Aaron_chen|Aaron_chen]] &ndash; [[Special:Contributions/Aaron_chen|贡献]] &ndash; [[Special:EmailUser/Aaron_chen|Send Email]]<br />
* [[User:Shibao Zhao|Shibao Zhao]] &ndash; [[Special:Contributions/Shibao Zhao|贡献]] &ndash; [[Special:EmailUser/Shibao Zhao|Send Email]]<br />
* [[User:Radflum|Yk]] &ndash; [[Special:Contributions/Radflum|贡献]] &ndash; [[Special:EmailUser/Radflum|Send Email]]<br />
* [[User:Hang yan|Hang yan]] &ndash; [[Special:Contributions/Hang yan|贡献]] &ndash; [[Special:EmailUser/Hang yan|Send Email]]<br />
* [[User:Acgtyrant|Acgtyrant]] &ndash; [[Special:Contributions/Acgtyrant|贡献]] &ndash; [[Special:EmailUser/Acgtyrant|Send Email]]<br />
* [[User:Xuchunyang|Xuchunyang]] &ndash; [[Special:Contributions/Acgtyrant|贡献]] &ndash; [[Special:EmailUser/Acgtyrant|Send Email]]<br />
* [[User:Stlt1sean|Stlt1sean]] &ndash; [[Special:Contributions/Stlt1sean|贡献]] &ndash; [[Special:EmailUser/Stlt1sean|Send Email]]<br />
* [[User:Carl_tw|Carl X. Su]] &ndash; [[Special:Contributions/Carl_tw|贡献]] &ndash; [[Special:EmailUser/Carl_tw|Send Email]]<br />
* [[User:SteamedFish|SteamedFish]] &ndash; [[Special:Contributions/SteamedFish|贡献]] &ndash; [[Special:EmailUser/SteamedFish|Send Email]]<br />
* [[User:Zer4tul|Zer4tul]] &ndash; [[Special:Contributions/Zer4tul|贡献]] &ndash; [[Special:EmailUser/Zer4tul|Send Email]]<br />
* [[User:Mac_uestc|Mac.Bloom]] &ndash; [[Special:Contributions/Mac_uestc|贡献]] &ndash; [[Special:EmailUser/Mac_uestc|Send Email]]<br />
* [[User:Zguangyu0000|Guangyu Zhang]] &ndash; [[Special:Contributions/Zguangyu0000|贡献]] &ndash; [[Special:EmailUser/Zguangyu0000|Send Email]]<br />
* [[User:Xinkai|Xinkai]] &ndash; [[Special:Contributions/Xinkai|贡献]] &ndash; [[Special:EmailUser/Xinkai|Send Email]]<br />
* [[User:Spaike97|_spaike97]] &ndash; [[Special:Contributions/Spaike97|贡献]] &ndash; [[Special:EmailUser/Spaike97|Send Email]]<br />
* [[User:jazzi|jazzi]] &ndash; [[Special:Contributions/jazzi|贡献]] &ndash; [[Special:EmailUser/jazzi|Send Email]]<br />
* [[User:HelloCode|HelloCode]] &ndash; [[Special:Contributions/HelloCode|贡献]] &ndash; [[Special:EmailUser/HelloCode|Send Email]]<br />
<br />
== 翻译任务 ==<br />
=== 模板 Article summary 变更为 Related ===<br />
因为 Summary 中的简介基本上和正文的介绍一样,所以页面左边的介绍栏进行了简化,只保留相关文章功能。英文页面正在进行大规模修改,相应的中文页面也需要同步更新。<br />
<br />
需要注意的地方:<br />
* 将第一行改成<br />
: <nowiki>{{Related articles start (简体中文)}}</nowiki><br />
* 如果英文的相关文章存在中文翻译,则替换为简体中文页面。示例:<br />
: <nowiki>{{Related2|Display Manager (简体中文)|显示管理器}}</nowiki><br />
* 示例:[https://wiki.archlinux.org/index.php?title=Start_X_at_Login&diff=0&oldid=270155 英文变更], [https://wiki.archlinux.org/index.php?title=Start_X_at_Login_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=285643&oldid=242662 对应的翻译]<br />
<br />
== 维护翻译 ==<br />
完成页面的翻译只是初步完成任务,及时同步英文页面改动、更新翻译是一个持续性的工作,可能会耗费更多的时间。<br />
<br />
=== 页面认领 ===<br />
所有人都可以认领页面。认领后的责任包括进行翻译,关注英文页面的改动,及时同步翻译。<br />
<br />
为了更好的跟踪英文页面的修改,请务必在设置中启用监视列表邮件通知,并监视对应的英文页面(从设置中找到监视列表,加入英文页面。或者直接到英文页面点击页面顶端的监视标签。这样只要有改动,就会收到邮件通知)。<br />
<br />
{{小贴士|如果收到邮件通知后没有访问页面或者访问了页面却没有登录用户,下次页面改动时就不会再发邮件通知。可以点击监视列表中的'''标记所有页面为已读'''再次获取更新。}}<br />
<br />
如果页面有维护者但长期得不到更新,将会在维护列表中删除维护者。<br />
<br />
=== 翻译状态模板 ===<br />
Arch 作为滚动发行版,软件变化比较快,对应的文档变化也比较快。许多翻译的文章由于缺乏更新,会产生命令运行出错或不起作用等问题。而由于这些过期页面没有及时标记出来,所以用户无法及时获得更新。[[Template:TranslationStatus (简体中文)|翻译状态模板]]就是为了解决这个问题而创建。<br />
<br />
此模板可以起到如下作用:<br />
* 为用户提供翻译状况,包括翻译时间、英文页面的最后版本等<br />
* 用户可以点击查看翻译后,英文页面的改动,这样英文不是很好的用户可以只查看很小一部分英文内容,并判断出是否影响操作。<br />
* 翻译人员可以跟踪页面状况,通过[https://wiki.archlinux.org/index.php/Special:WhatLinksHere/Template:TranslationStatus_(简体中文) 模板的反向链接]可以查找到所有标记页面,查看需要更新翻译的部分。<br />
<br />
[[Template:TranslationStatus (简体中文)|模板页面]]有详细的使用方法。<br />
<br />
=== 页面维护列表 ===<br />
{{注意|请按照拉丁字母顺序添加页面。}}<br />
<br />
翻译状态说明:<br />
;过期:页面内容未与英文页面同步,对应{{ic|<nowiki>{{out of date}}</nowiki>}} 模版<br />
;未翻译:页面中含有英文内容,对应{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板<br />
;完成:页面已与英文页面同步<br />
<br />
需要优先翻译的页面:<br />
<br />
{| class="wikitable sortable collapsible" border="1"<br />
|-<br />
! 页面<br />
! 翻译状态<br />
! 维护者<br />
! class="unsortable" width="30%" | 备注<br />
|-<br />
| [[acpid (简体中文)]]<br />
| 过期<br />
| Cael<br />
|-<br />
| [[Advanced Linux Sound Architecture (简体中文)]]<br />
| 翻译中<br />
| ihonliu<br />
| 无<br />
|-<br />
| [[Arch Based Distributions (Active) (简体中文)]]<br />
| 完成<br />
| Joshua<br />
| 勘误中<br />
|-<br />
| [[ATI (简体中文)]]<br />
| 过期<br />
| 无<br />
| 请优先翻译此文<br />
|-<br />
| [[AUR Helpers (简体中文)]]<br />
| 进行中<br />
| Stonex<br />
| 无<br />
|-<br />
| [[awesome (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无<br />
|-<br />
| [[BIND (简体中文)]]<br />
| 翻译中<br />
| SteamedFish<br />
| 无<br />
|-<br />
| [[Bumblebee (简体中文)]]<br />
| 未翻译<br />
| Peter<br />
| 无<br />
|-<br />
| [[AMD Catalyst (简体中文)]]<br />
| 过期<br />
| Shibao Zhao<br />
| 无<br />
|-<br />
| [[Chromium (简体中文)]]<br />
| 翻译中<br />
| Bobby<br />
| 部分未翻译 <br />
|-<br />
| [[Cinnamon (简体中文)]]<br />
| 部分翻译 <br />
| Bobby<br />
| 部分未翻译 <br />
|- <br />
| [[Common Applications (简体中文)]]<br />
| 部分翻译 <br />
| DavidChen<br />
| 翻译中<br />
|-<br />
| [[Common Applications/Science (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 无<br />
|-<br />
| [[Compiz (简体中文)]]<br />
| 翻译中<br />
| xiii_1991<br />
| 20140813开始<br />
|-<br />
| [[Core Utilities (简体中文)]]<br />
| 翻译中<br />
| rentaro<br />
| 同步翻译至2014年7月23日08:13英文页面,完善中<br />
|-<br />
| [[Disk Cloning (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Emacs (简体中文)]]<br />
| 翻译中<br />
| Jaurung yuanhang<br />
| 未完成<br />
|-<br />
| [[File recovery (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Font Configuration (简体中文)]]<br />
| 翻译中<br />
| Jaurung<br />
| 完善中<br />
|-<br />
| [[Fonts (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[LAMP (简体中文)]]<br />
| 完成<br />
| Liuzhengyi<br />
| 勘误中<br />
|-<br />
| [[LibreOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Local Mirror (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[NetworkManager (简体中文)]]<br />
| 部分翻译 <br />
| Jack-lijing <br />
| 请优先翻译<br />
|-<br />
| [[Network Time Protocol daemon (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 部分未翻译<br />
|-<br />
| [[OpenOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Opera (简体中文)]]<br />
| 未翻译<br />
| Bobby<br />
| 请优先翻译此文 <br />
|-<br />
| [[Pacman GUI Frontends (简体中文)]]<br />
| 翻译中<br />
| KaiYuan Guo<br />
| 无<br />
|-<br />
| [[Pidgin (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无 <br />
|- <br />
| [[Plasma (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 无<br />
|-<br />
| [[ranger (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[Reporting_Bug_Guidelines_(简体中文)]]<br />
| 翻译中<br />
| Jason Zhang<br />
| <br />
|-<br />
| [[Smart Common Input Method platform (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Secure Shell (简体中文)]]<br />
| 未翻译<br />
| 无<br />
| 部分未翻译<br />
|-<br />
| [[VirtualBox (简体中文)]] || 翻译中 || Carl X. Su || 请优先翻译此文<br />
|-<br />
| [[VirtualBox Extras (简体中文)]] || 部分翻译 || 无 || 需要合并到 [[VirtualBox (简体中文)]]<br />
|-<br />
| [[VMware (简体中文)]] || 翻译中 || Jason Zhang || 无<br />
|- <br />
| [[Xfce (简体中文)]] || 翻译中 || ZaticWu || 请优先翻译<br />
|-<br />
| [[Xmonad (简体中文)]]<br />
| 未翻译<br />
| Rns<br />
| 翻译中<br />
|-<br />
| [[Xrandr (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348287OpenSSH (简体中文)2014-12-05T11:20:05Z<p>HelloCode: /* "[your shell]: No such file or directory" / ssh_exchange_identification Problem */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh认证问题 ===<br />
<br />
对于这个问题,一个可能的原因是需要SSH客户端在{{Ic|$SHELL}}中提供绝对路径(例如可以通过{{Ic|whereis -b [your shell]}}得到),即使你的shell在{{Ic|$PATH}}中。另一个原因也可能是,用户不是''network''组的成员。<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348286OpenSSH (简体中文)2014-12-05T11:15:56Z<p>HelloCode: /* Speed up SSH */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== 加速SSH ===<br />
为了加速连续的到同一台主机的连接,你可以在远程主机的{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
改变SSH的计算来减少cpu使用能够提高速度。关于这一点,最好的选择是arcfour和blowfish-cbc。<br />
'''除非你清楚你在做什么,否则不要做; arcfour有大量众所周知的缺点'''。 通过增加参数{{Ic|"c"}}:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
为了持续地使用这个,可以在{{ic|/etc/ssh/ssh_config}}中增加以下内容:<br />
Ciphers arcfour,blowfish-cbc<br />
其他能够加速的选项是{{Ic|"C"}}参数,同样,以下将是长久的解决方案:<br />
Compression yes<br />
登陆时间可以通过{{Ic|"4"}}来减少,它是通过IPv6旁路进行寻路。同上:<br />
AddressFamily inet<br />
或者在{{ic|~/.bashrc}}中增加以下内容也能够达到长久的效果(前提是你使用bash):<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348282OpenSSH (简体中文)2014-12-05T11:05:28Z<p>HelloCode: /* 转发其他端口 */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348281OpenSSH (简体中文)2014-12-05T11:04:51Z<p>HelloCode: /* Forwarding Other Ports */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== 转发其他端口 ===<br />
出了SSH内建的对X11的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一个SSH,一个安全的VNC连接。本地转发可以通过{{Ic|-L}}来设置,后面可以指定一个地址及端口{{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在192.168.0.110的shell,同时也会创建一个从本机1000端口到mai.google.com上的25端口的隧道。建立之后,localhost:1000会连接到Gmail的SMTP端口。任何从192.168.0.100到Google的连接(即使不必要)都会以这样的方式建立,并且,在本机和192.168.0.100之间的数据传递都是安全的,除非你采取了别的手段。<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到localhost:2000的连接直接转发到远程主机的6001端口。对于使用VNC服务器(tightvns包的一部分)建立的VNC连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过SSH隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过{Ic|-R}}参数,以及{{Ic|<tunnel port>:<destination address>:<destination>}}能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
将会在192.168.0.200上得到一个shell,同时,从192.168.0.200到它的3000端口的连接将会通过隧道发送到本机然后到irc.freenode.net的6667端口。因此,在这个例子中,在远程主机上IRC程序能够被使用,即使端口6667被阻止。<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348278OpenSSH (简体中文)2014-12-05T10:33:57Z<p>HelloCode: /* X11 Forwarding */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348129OpenSSH (简体中文)2014-12-04T11:00:05Z<p>HelloCode: /* Connection Refused or Timeout Problem */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== 拒绝连接或者超时问题 ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348128OpenSSH (简体中文)2014-12-04T10:59:21Z<p>HelloCode: /* Troubleshooting */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== 问题解决 ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== SSH服务开启并且在监听吗? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示SSH端口是打开的,那么说明SSH服务没有启动。查看{{/var/log/messages}}来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
更新你的防火墙规则来排除干扰:<br />
<br />
# rc.d stop iptables<br />
<br />
或者:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348126OpenSSH (简体中文)2014-12-04T10:55:23Z<p>HelloCode: /* Automatically logout all ssh users when the sshd server is shutdown */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== 当sshd服务器宕机时自动登出所有客户端 ===<br />
为了在sshd服务器宕机(比如重启或关机)时自动登出所有客户端,需要在sshd服务器的/etc/rc.local.shutdown 增加以下内容:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
这防止了ssh客户端在超时之后挂起,最终得到这样的结果:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348125OpenSSH (简体中文)2014-12-04T10:50:52Z<p>HelloCode: /* Change bash prompt when logged over ssh */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== 更改ssh主机prompt ===<br />
区别你的电脑和远程主机是很有必要的,特别是它们的prompt相同时。只要把一下内容插入到你的bashrc文件即可达到这个效果。<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
可以访问[[Color Bash Prompt]]了解更多关于PS1变量定制的更多信息。<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348124OpenSSH (简体中文)2014-12-04T10:46:49Z<p>HelloCode: /* Save connection data in ssh config */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
===在配置文件中保存连接信息 ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== Change bash prompt when logged over ssh ===<br />
It can sometimes be useful to be able to make the difference between your local and your remote prompt, in particular when they are both configured in the same way. To do that, just insert this in your bashrc:<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
See [[Color Bash Prompt]] for more information about the PS1 variable customization.<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348123OpenSSH (简体中文)2014-12-04T10:46:11Z<p>HelloCode: /* Save connection data in ssh config */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
=== Save connection data in ssh config ===<br />
通常当你想登录到一台远程主机的时候,你至少需要输入主机名和ID地址。为了减少这个重复劳动,你可以使用本地的{{ic|$HOME/.ssh/config}} 或者全局的{{ic|/etc/ssh/ssh_config}}:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
现在你能用指定的名称来简单地连接到远程主机:<br />
<br />
$ ssh myserver<br />
<br />
如果需要查看完整选项,可以查看你的系统上的ssh_config文档, 或者它的官方网站[http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation]。<br />
<br />
=== Change bash prompt when logged over ssh ===<br />
It can sometimes be useful to be able to make the difference between your local and your remote prompt, in particular when they are both configured in the same way. To do that, just insert this in your bashrc:<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
See [[Color Bash Prompt]] for more information about the PS1 variable customization.<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348122OpenSSH (简体中文)2014-12-04T10:41:27Z<p>HelloCode: /* 保持在线 */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把以下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
=== Save connection data in ssh config ===<br />
Whenever you want to connect to a ssh server, you usually have to type at least its address and the username. To save that typing work for servers you regularly connect to, you can use the personal {{ic|$HOME/.ssh/config}} or the global {{ic|/etc/ssh/ssh_config}} files as shown in the following example:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
Now you can simply connect to the server by using the name you specified:<br />
<br />
$ ssh myserver<br />
<br />
To see a complete list of the possible options, check out ssh_config's manpage on your system or the [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation] on the official website.<br />
<br />
=== Change bash prompt when logged over ssh ===<br />
It can sometimes be useful to be able to make the difference between your local and your remote prompt, in particular when they are both configured in the same way. To do that, just insert this in your bashrc:<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
See [[Color Bash Prompt]] for more information about the PS1 variable customization.<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348121OpenSSH (简体中文)2014-12-04T10:41:01Z<p>HelloCode: /* Keep Alive */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== 保持在线 ===<br />
如果你的会话空闲,它会自动登出。为了保持会话, 可以把一下内容增加到客户端的{{ic|~/.ssh/config}}或者{{ic|/etc/ssh/ssh_config}}。<br />
<br />
ServerAliveInterval 120<br />
<br />
这将会使得客户端每120秒发送一个“alive”的信号到服务器。<br />
<br />
反过来,为了保持到达本地的会话,你可以设置:<br />
<br />
ClientAliveInterval 120<br />
<br />
(或者其他任何大于0的数字)在服务器的{{ic|/etc/ssh/sshd_config}}。<br />
<br />
=== Save connection data in ssh config ===<br />
Whenever you want to connect to a ssh server, you usually have to type at least its address and the username. To save that typing work for servers you regularly connect to, you can use the personal {{ic|$HOME/.ssh/config}} or the global {{ic|/etc/ssh/ssh_config}} files as shown in the following example:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
Now you can simply connect to the server by using the name you specified:<br />
<br />
$ ssh myserver<br />
<br />
To see a complete list of the possible options, check out ssh_config's manpage on your system or the [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation] on the official website.<br />
<br />
=== Change bash prompt when logged over ssh ===<br />
It can sometimes be useful to be able to make the difference between your local and your remote prompt, in particular when they are both configured in the same way. To do that, just insert this in your bashrc:<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
See [[Color Bash Prompt]] for more information about the PS1 variable customization.<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCodehttps://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=348119OpenSSH (简体中文)2014-12-04T10:36:23Z<p>HelloCode: /* Troubleshooting */</p>
<hr />
<div>[[Category:Secure Shell (简体中文)]]<br />
{{translateme (简体中文)}}<br />
[[ar:Ssh]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fr:ssh]]<br />
[[it:Secure Shell]]<br />
[[ja:Secure Shell]]<br />
[[ko:Secure Shell]]<br />
[[pl:Secure Shell]]<br />
[[pt:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
[[sr:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|Sshfs}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related articles end}}<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器,默认地,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专利的,自由软件的以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(Source: [[Wikipedia:Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH是由Theo de Raadt领导的OpenBSD项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{ic|openssh}}<br />
# pacman -S openssh<br />
<br />
=== 配置SSH ===<br />
====客户端====<br />
SSH客户端的配置文件是{{ic|/etc/ssh/ssh_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/ssh_config|<br />
# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for some commonly used options. For a comprehensive<br />
# list of available options, their meanings and defaults, please see the<br />
# ssh_config(5) man page.<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# GSSAPIAuthentication no<br />
# GSSAPIDelegateCredentials no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc<br />
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160<br />
# EscapeChar ~<br />
# Tunnel no<br />
# TunnelDevice any:any<br />
# PermitLocalCommand no<br />
# VisualHostKey no<br />
# ProxyCommand ssh -q -W %h:%p gateway.example.com<br />
}}<br />
<br />
推荐将“Protocol”行改为:<br />
Protocol 2<br />
<br />
这表示只有协议2将被用到,因为协议1被认为一定程度上不太安全。<br />
<br />
====守护进程====<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
以下是一个范例::<br />
<br />
{{hc|/etc/ssh/sshd_config|2=<br />
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#AddressFamily any<br />
#ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# The default requires explicit activation of protocol 1<br />
#Protocol 2<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh_host_key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh_host_rsa_key<br />
#HostKey /etc/ssh/ssh_host_dsa_key<br />
#HostKey /etc/ssh/ssh_host_ecdsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 1024<br />
<br />
# Logging<br />
# obsoletes QuietMode and FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
#MaxSessions 10<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
ChallengeResponseAuthentication no<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing, <br />
# and session processing. If this is enabled, PAM authentication will <br />
# be allowed through the ChallengeResponseAuthentication and<br />
# PasswordAuthentication. Depending on your PAM configuration,<br />
# PAM authentication via ChallengeResponseAuthentication may bypass<br />
# the setting of "PermitRootLogin without-password".<br />
# If you just want the PAM account and session checks to run without<br />
# PAM authentication, then enable this but set PasswordAuthentication<br />
# and ChallengeResponseAuthentication to 'no'.<br />
UsePAM yes<br />
<br />
#AllowAgentForwarding yes<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression delayed<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
#PermitTunnel no<br />
#ChrootDirectory none<br />
<br />
# no default banner path<br />
#Banner none<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
# Example of overriding settings on a per-user basis<br />
#Match User anoncvs<br />
# X11Forwarding no<br />
# AllowTcpForwarding no<br />
# ForceCommand cvs server<br />
}}<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers user1 user2<br />
<br />
要禁止通过SSH进行root用户登录,加入以下行:<br />
PermitRootLogin no<br />
<br />
你也可以取消BANNER选项的注释,然后编辑{{ic|/etc/issue}}加入友好的欢迎信息内容。<br />
<br />
{{小贴士|你可能想要把默认的端口从22改成其它更高的端口(参考 [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]).}} <br />
<br />
尽管ssh的运行端口可以被像nmap这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目。<br />
<br />
{{小贴士|完全取消密码登录方式可以极大的增强安全性,(参考 [[SSH Keys (简体中文)|SSH Keys]]).}}<br />
<br />
=== 管理sshd守护进程 ===<br />
你可以使用下面的命令启动sshd:<br />
# systemctl start sshd<br />
<br />
你可以使用下面的命令开机启动sshd:<br />
# systemctl enable sshd.service<br />
<br />
{{警告|Systemd 是一个异步启动的进程。如果你绑定 SSH 守护进程到某个特定的 IP 地址 {{ic|ListenAddress 192.168.1.100}},它可能会在引导时启动失败,因为默认的 sshd.service 单元文件没有对网络接口启动的依赖。当绑定到一个 IP 地址时,你需要添加 {{ic|After&#61;network.target}} 到自定义的 sshd.service 单元文件中。参见 [[Systemd#Replacing provided unit files]].}}<br />
<br />
或者你可以启用SSH Daemon socket,这样当第一次传入连接时启动守护进程:<br />
# systemctl enable sshd.socket<br />
如果你使用非默认端口22,你必须在文件(/lib/systemd/system/sshd.socket)中设置"ListenStream"为相应的端口。<br />
<br />
===连接到服务器===<br />
<br />
运行下面的命令:<br />
$ ssh -p port user@server-address<br />
<br />
== 小细节和小戏法 ==<br />
<br />
=== 加密Socks通道 ===<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的SSH服务器,比如在家里或办公室。用动态的DNS服务[http://www.dyndns.org/ DynDNS]也可能是很有用的,这样你就不必记住你的IP了。<br />
<br />
==== 第一步:开始连接 ====<br />
你只要在你喜欢的终端中执行这一个命令就能开始你的连接:<br />
$ ssh -ND 4711 user@host<br />
这里的“user”是你在“host”这台SSH服务器上运行的用户名。它会让你输入密码,然后你就能连上了。“N”表示不采用交互提示,而“D”表示指定监听的本地端口(你可以使用任何你喜欢的数字)<br />
<br />
一个办法可以让这个过程更简单,那就是在~/.bashrc中加入这样一行:<br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
加入冗长的“-v”标志更好,因为这样你可以验证是真的是从那个端口连接的。现在你只要执行命令“sshtunnel”就可以。 :)<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你不配置你的web浏览器以便使用新创建的socks通道的话,上面的一步完全没用!<br />
<br />
* 对于Firefox: ''Edit -> Preferences -> Advanced -> Network -> Connection -> Setting'':<br />
: 检查"Manual proxy configuration" radio button?, 并且在"SOCKS host" 文本段输入"localhost" , 然后在接下来的一个文本框中输入你的端口数(上面我们用的是4711)。<br />
<br />
: 确定你选择使用SOCKS4。这个程序对不会对SOCKS5起作用.<br />
<br />
:享受你的安全通道吧!<br />
<br />
=== X11 Forwarding ===<br />
<br />
为了通过SSH运行图形程序你必须使用X11 Forwarding。一个选项就是需要设置服务器和客户端的配置文件(这里所说的“客户端”指运行你的X11服务器的电脑,而你的X应用程序运行在“服务器”上)。<br />
<br />
在服务器上安装xorg-xauth:<br />
# pacman -S xorg-xauth<br />
<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''AllowTcpForwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11Forwarding'''选项。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}将'''X11DisplayOffset'''选项设为10。<br />
* 在'''服务器'''上,编辑{{ic|ssh'''d'''_config}}启用'''X11UseLocalhost'''选项。<br />
同时:<br />
* 在'''客户端'''上,编辑{{ic|ssh_config}}启用'''ForwardX11'''选项。<br />
<br />
当GUI大量绘制时,请启用'''ForwardX11Trusted'''。<br />
<br />
为了使用X11 forwarding,首先通过SSH登陆到你的服务器:<br />
$ ssh -X -p port user@server-address<br />
如果你在运行图形应用程序时收到了一些错误,请尝试可信的X11 forwarding:<br />
$ ssh -Y -p port user@server-address<br />
你现在可以在远程服务器上启用任何的X程序,输出将会被转发到你的本地会话中:<br />
$ xclock<br />
<br />
如果你遇到了“Cannot open display”错误,请尝试使用非root账户执行下述命令:<br />
$ xhost +<br />
<br />
上述命令将会允许任何用户转发X11应用程序。为了限制只能转发到特定主机:<br />
$ xhost +hostname<br />
<br />
上述命令中的hostname是你想要转发到的主机名。使用“man xhost”获取更多信息。<br />
<br />
值得注意的是,一些应用程序会检查本地正在运行的实例。Firefox就是一个例子。你可以关闭正在执行的Firefox,或者使用下述启动参数来在本地启动一个远程实例:<br />
$ firefox -no-remote<br />
<br />
=== Forwarding Other Ports ===<br />
In addition to SSH's built-in support for X11, it can also be used to securely tunnel any TCP connection, by use of local forwarding or remote forwarding.<br />
<br />
Local forwarding opens a port on the local machine, connections to which will be forwarded to the remote host and from there on to a given destination. Very often, the forwarding destination will be the same as the remote host, thus providing a secure shell and, e.g. a secure VNC connection, to the same machine. Local forwarding is accomplished by means of the {{Ic|-L}} switch and it's accompanying forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
will use SSH to login to and open a shell on 192.168.0.100, and will also create a tunnel from the local machine's TCP port 1000 to mail.google.com on port 25. Once established, connections to localhost:1000 will connect to the Gmail SMTP port. To Google, it will appear that any such connection (though not necessarily the data conveyed over the connection) originated from 192.168.0.100, and such data will be secure as between the local machine and 192.168.0.100, but not between 192.168.0.100, unless other measures are taken.<br />
<br />
Similarly:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
will allow connections to localhost:2000 which will be transparently sent to the remote host on port 6001. The preceding example is useful for VNC connections using the vncserver utility--part of the tightvnc package--which, though very useful, is explicit about its lack of security.<br />
<br />
Remote forwarding allows the remote host to connect to an arbitrary host via the SSH tunnel and the local machine, providing a functional reversal of local forwarding, and is useful for situations where, e.g., the remote host has limited connectivity due to firewalling. It is enabled with the {{Ic|-R}} switch and a forwarding specification in the form of {{Ic|<tunnel port>:<destination address>:<destination port>}}.<br />
<br />
Thus:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
will bring up a shell on 192.168.0.200, and connections from 192.168.0.200 to itself on port 3000 (remotely speaking, localhost:3000) will be sent over the tunnel to the local machine and then on to irc.freenode.net on port 6667, thus, in this example, allowing the use of IRC programs on the remote host to be used, even if port 6667 would normally be blocked to it.<br />
<br />
Both local and remote forwarding can be used to provide a secure "gateway," allowing other computers to take advantage of an SSH tunnel, without actually running SSH or the SSH daemon by providing a bind-address for the start of the tunnel as part of the forwarding specification, e.g. {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}. The {{Ic|<tunnel address>}} can be any address on the machine at the start of the tunnel, {{Ic|localhost}}, {{Ic|*}} (or blank), which, respectively, allow connections via the given address, via the loopback interface, or via any interface. By default, forwarding is limited to connections from the machine at the "beginning" of the tunnel, i.e. the {{Ic|<tunnel address>}} is set to {{Ic|localhost}}. Local forwarding requires no additional configuration, however remote forwarding is limited by the remote server's SSH daemon configuration. See the {{Ic|GatewayPorts}} option in {{Ic|sshd_config(5)}} for more information.<br />
<br />
=== Speed up SSH ===<br />
You can make all sessions to the same host use a single connection, which will greatly speed up subsequent logins, by adding these lines under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
ControlMaster auto<br />
ControlPath ~/.ssh/socket-%r@%h:%p<br />
<br />
Changing the ciphers used by SSH to less cpu-demanding ones can improve speed. In this aspect, the best choices are arcfour and blowfish-cbc. '''Please do not do this unless you know what you are doing; arcfour has a number of known weaknesses'''. To use them, run SSH with the {{Ic|"c"}} flag, like this:<br />
$ ssh -c arcfour,blowfish-cbc user@server-address<br />
To use them permanently, add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Ciphers arcfour,blowfish-cbc<br />
Another option to improve speed is to enable compression with the {{Ic|"C"}} flag. A permanent solution is to add this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
Compression yes<br />
Login time can be shorten by using the {{Ic|"4"}} flag, which bypasses IPv6 lookup. This can be made permanent by adding this line under the proper host in {{ic|/etc/ssh/ssh_config}}:<br />
AddressFamily inet<br />
Another way of making these changes permanent is to create an alias in {{ic|~/.bashrc}}:<br />
alias ssh='ssh -C4c arcfour,blowfish-cbc'<br />
<br />
==== 问题解决 ====<br />
确定你的“DISPLAY”变量在远程主机上能被解析:<br />
<br />
$ ssh -X user@server-address<br />
server $ echo $DISPLAY<br />
localhost:10.0<br />
server $ telnet localhost 6010<br />
localhost/6010: lookup failure: Temporary failure in name resolution <br />
<br />
这个问题能通过添加localhost到 {{ic|/etc/hosts}}来解决。<br />
<br />
=== 用SSHFS挂载远程文件系统 ===<br />
<br />
安装sshfs<br />
# pacman -S sshfs<br />
<br />
将你想要允许挂载SSH文件夹的用户添加到fuse组里<br />
<br />
# gpasswd -a USER fuse<br />
<br />
加载fuse模块(比如说在/etc/rc.conf中)<br />
<br />
And then然后,在登录后,你就可以试着挂用sshfs载远程文件夹了:<br />
# mkdir ~/remote_folder<br />
# sshfs USER@remote_server:/tmp ~/remote_folder<br />
<br />
上面的命令将把远程服务器上的/tmp文件夹挂载到本地的~/remote_folder目录下。复制任何文件到这个目录将使文件通过SCP通过网络传输。<br />
Same concerns direct file editing, creating or removing.<br />
<br />
当我们完成在远程文件夹下的工作,我们可以这样来卸载它:<br />
# fusermount -u ~/remote_folder<br />
<br />
如果我们需要经常在这个文件夹下,让它通过/etc/fstab挂载是一个明智的选择。这个办法可以让它在启动的时候挂载或者通过手动挂载(如果是noauto选项的话),而不需要每次都去挂载它。下面是一个简单的样本: <br />
sshfs#USER@remote_server:/tmp /full/path/to/directory fuse defaults,auto 0 0<br />
=== Keep Alive ===<br />
Your ssh session will automatically log out if it is idle. To keep the connection active (alive) add this to {{ic|~/.ssh/config}} or to {{ic|/etc/ssh/ssh_config}} on the client.<br />
<br />
ServerAliveInterval 120<br />
<br />
This will send a "keep alive" signal to the server every 120 seconds.<br />
<br />
Conversely, to keep incoming connections alive, you can set<br />
<br />
ClientAliveInterval 120<br />
<br />
(or some other number greater than 0) in {{ic|/etc/ssh/sshd_config}} on the server.<br />
<br />
=== Save connection data in ssh config ===<br />
Whenever you want to connect to a ssh server, you usually have to type at least its address and the username. To save that typing work for servers you regularly connect to, you can use the personal {{ic|$HOME/.ssh/config}} or the global {{ic|/etc/ssh/ssh_config}} files as shown in the following example:<br />
<br />
{{hc|$HOME/.ssh/config|<br />
Host myserver<br />
HostName 123.123.123.123<br />
Port 12345<br />
User bob<br />
Host other_server<br />
HostName test.something.org<br />
User alice<br />
CheckHostIP no<br />
Cipher blowfish<br />
}}<br />
<br />
Now you can simply connect to the server by using the name you specified:<br />
<br />
$ ssh myserver<br />
<br />
To see a complete list of the possible options, check out ssh_config's manpage on your system or the [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config ssh_config documentation] on the official website.<br />
<br />
=== Change bash prompt when logged over ssh ===<br />
It can sometimes be useful to be able to make the difference between your local and your remote prompt, in particular when they are both configured in the same way. To do that, just insert this in your bashrc:<br />
<br />
{{hc|$HOME/.bashrc|2=<br />
if [ -n "$SSH_CLIENT" ]; then<br />
PS1='\[\e[0;33m\]\u@\h:\wSSH$\[\e[m\] '<br />
else<br />
PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\ e[m\] '<br />
fi<br />
}}<br />
<br />
See [[Color Bash Prompt]] for more information about the PS1 variable customization.<br />
<br />
=== Automatically logout all ssh users when the sshd server is shutdown ===<br />
To automatically log out all remote ssh users when the sshd server system shuts down, for reboot or halt, add this line to /etc/rc.local.shutdown on the sshd server:<br />
<br />
who | cut -d " " -f1 | uniq | xargs pkill -KILL -u<br />
<br />
This prevents ssh client terminals from hanging during a lengthy timeout, which eventually ends with:<br />
<br />
Write failed: Broken pipe<br />
<br />
== Troubleshooting ==<br />
=== Connection Refused or Timeout Problem ===<br />
==== Is SSH running and listening? ====<br />
$ ss -tnlp<br />
<br />
If the above command do not show SSH port is open, SSH is NOT running. Check {{ic|/var/log/messages}} for errors etc.<br />
<br />
==== Are there firewall rules blocking the connection? ====<br />
Flush your iptables rules to make sure they are not interfering:<br />
<br />
# rc.d stop iptables<br />
<br />
or:<br />
<br />
# iptables -P INPUT ACCEPT<br />
# iptables -P OUTPUT ACCEPT<br />
# iptables -F INPUT<br />
# iptables -F OUTPUT<br />
<br />
==== Is the traffic even getting to your computer? ====<br />
Start a traffic dump on the computer you're having problems with:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
This should show some basic information, then wait for any matching traffic to happen before displaying it. Try your connection now. If you do not see any output when you attempt to connect, then something outside of your computer is blocking the traffic (e. g., hardware firewall, NAT router etc.).<br />
<br />
==== Read from socket failed: Connection reset by peer ====<br />
Recent versions of openssh sometimes fail with the above error message, due to a bug involving elliptic curve cryptography. In that case, edit the file<br />
<br />
~/.ssh/config<br />
<br />
or create it, if it doesn't already exist. Add the line<br />
<br />
HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss<br />
<br />
With openssh 5.9, the above fix doesn't work. Instead, put the following lines in ~/.ssh/config<br />
<br />
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc <br />
MACs hmac-md5,hmac-sha1,hmac-ripemd160<br />
<br />
See also the [http://www.gossamer-threads.com/lists/openssh/dev/51339 discussion] on the openssh bug forum.<br />
<br />
=== "[your shell]: No such file or directory" / ssh_exchange_identification Problem ===<br />
<br />
One possible cause for this is the need of certain SSH clients to find an absolute path (one returned by {{Ic|whereis -b [your shell]}}, for instance) in {{Ic|$SHELL}}, even if the shell's binary is located in one of the {{Ic|$PATH}} entries. Another reason can be that the user is no member of the ''network'' group.<br />
<br />
== See Also ==<br />
*[[SSH keys]]<br />
*[[Pam abl]]<br />
*[[fail2ban]]<br />
*[[sshguard]]<br />
*[[Sshfs]]<br />
*[http://www.soloport.com/iptables.html A Cure for the Common SSH Login Attack]<br />
*[[使用SSH密钥]]<br />
*[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
*[http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks</div>HelloCode