使用 OpenSSH 为运行远程终端提供安全环境。OpenSSH 和终端的基本用法非常简单,不过,本文还将介绍允许自动登录到远程主机的其他元素、运行远程应用程序的方法,以及如何在主机之间安全地复制文件。
关于本系列
典型的 UNIX® 管理员拥有一套经常用于辅助管理过程的关键实用工具、诀窍和系统。存在各种用于简化不同过程的关键实用工具、命令行链和脚本。其中一些工具来自于操作系统,而大部分的诀窍则来源于长期的经验积累和减轻系统管理员工作压力的要求。本系列文章主要专注于最大限度地利用各种 UNIX 环境中可用的工具,包括简化异构环境中的管理任务的方法。
为何使用 OpenSSH?
您每天使用的标准网络服务(如 FTP、Telnet、RCP 和远程 Shell (rsh) 等)在封闭环境中运行良好,但使用这些服务在网络上传输的信息是未加密的。任何人都可以在您的网络或远程计算机上使用包嗅探器查看交换的信息,有时甚至可以查看密码信息。
而且,使用所有此类服务时,在登录过程中用于自动登录的选项会受到限制,并且通常依赖于将纯文本密码嵌入到命令行才能执行语句,从而使登录过程变得更加不安全。
开发的安全 Shell (SSH) 协议可以排除这些限制。SSH 能够为整个通信通道提供加密,其中包括登录和密码凭据交换,它与公钥和私钥一起使用可以为登录提供自动化身份验证。您还可以将 SSH 用作基础传输协议。以这种方式使用 SSH 意味着在打开安全连接后,加密通道可以交换所有类型的信息,甚至 HTTP 和 SMTP 可以使用该方法来保证通信机制的安全。
OpenSSH 是 SSH 1 和 SSH 2 协议的免费实现。它最初是作为 OpenBSD (Berkeley Software Distribution) 操作系统的一部分开发的,现在被发布为 UNIX 或 Linux® 和类似操作系统的常规解决方案。
安装 OpenSSH
OpenSSH 是免费软件,可以从 OpenSSH 的主要网站下载(请参见参考资料)。可以使用多种系统(包括 Linux、HP-UX、AIX®、Solaris、Mac OS X 等)上的源代码构建 OpenSSH 系统。通常可以找到所选平台和版本的预编译二进制代码。有些供应商甚至作为操作系统的一部分提供 OpenSSH 工具包。
要构建OpenSSH,您需要以下内容:
如果您需要使用缺省配置设置,请使用常规构建序列,如下面的清单 1 所示。
$ ./configure $ make $ make install |
这会将二进制文件、库文件和配置文件安装到 /usr/local 目录中,例如,二进制文件安装到 /usr/local/bin,配置文件安装到 /usr/local/etc。如果希望将各种工具集成到主环境中,那么您可能需要指定设置基本目录的 --prefix 选项和设置配置文件位置的 --sysconfdir 选项:
$ ./configure --prefix=/usr --sysconfidir=/etc/ssh |
您可能指定的一些其他常规选项包括:
完成配置后,使用 make 以正常方式构建。
构建和安装过程完成后,您需要配置系统,先创建唯一标识系统的 SSH 密钥,然后启用客户机和主机之间的安全通信。您可以运行:
$ make host-key |
或者,您可以在命令行上手动执行各个步骤。您需要创建三个密钥(每个密钥对应于一个主要加密算法:rsa1、rsa 和 dsa)。例如,清单 2 显示了如何创建 rsa1 密钥。
$ ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key Generating public/private rsa1 key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /etc/ssh//ssh_host_key. Your public key has been saved in /etc/ssh//ssh_host_key.pub. The key fingerprint is: 43:aa:58:3c:d8:30:de:43:af:66:2a:b2:8d:02:08:86 root@remotehost |
系统提示您输入密码。对于主机密钥,您可能不需要密钥密码,所以您可以按 Return 使用空密码。或者,您可以在命令行上使用 -N 选项加速该过程(请参见清单 3)。
$ ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N "" Generating public/private rsa1 key pair. Your identification has been saved in /etc/ssh/ssh_host_key. Your public key has been saved in /etc/ssh/ssh_host_key.pub. The key fingerprint is: a3:e3:21:4f:b5:9f:ff:05:46:66:bc:36:a1:47:a0:64 root@remotehost |
现在重复该过程,以创建 rsa 和 dsa 密钥(请参见清单 4)。
$ ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" $ ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" |
这将为每个密钥类型创建两个文件:公钥(在以 .pub 结尾的文件中)和私钥。您应确保私钥仅由根和 SSH 流程读取——这应自动配置。您可能需要将公钥复制到网络文件系统 (NFS) 共享中的中央位置,使人们能够将其添加到已知主机密钥列表中。
最后,您需要启动 sshd 过程,并对其进行配置,以便在启动时执行。对于 Linux 主机,您可以在 contrib/redhat/sshd.init 中找到合适的可以添加到 /etc/init.d 的 init 脚本。
将 SSH 用于基本终端访问
OpenSSH 的主要角色是用作 SSH 工具,它是 Telnet 协议的安全替代方法,用于安全地远程登录到 UNIX 或 Linux 主机。
要使用标准 Shell 连接到远程主机,您只需键入主机名:
$ ssh remotehost |
在缺省情况下,系统尝试使用当前用户名作为登录名称。要使用不同的登录名称,请在主机名前加上该登录名称,并使用 @ 符号分开。例如:
$ ssh mc@remotehost |
系统提示您输入用户密码——这与 Telnet 相似。
您第一次连接到主机时,系统会询问您是否需要将远程主机公钥的副本保存在“已知主机”文件中(请参见清单 5)。
$ ssh root@remotehost The authenticity of host 'remotehost (10.211.55.3)' can't be established. RSA key fingerprint is cc:c8:8b:75:3d:b6:00:2f:a9:9c:53:4c:03:0f:3d:1b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'remotehost' (RSA) to the list of known hosts. |
以后,您不会收到此警告,但是,当系统检测到远程主机返回的公钥与该主机文件中的公钥不符时就会发出警告,指示可能存在黑客攻击。这还可能意味着管理员仅重新生成了主机密钥。
从本质上讲,SSH 和 Telnet 会话之间没有什么不同,只不过 SSH 会话进行了加密,任何人几乎不可能探听到您的会话内容,也不可能知道您的密码或您正在执行的命令和操作。
您还可以使用 SSH 直接在远程主机上运行命令,而无需使用 Shell。例如,要在远程主机上运行 who 命令,请参见清单 6。
清单 6. 在远程主机上运行 who 命令
$ ssh mc@remotehost who admin console Nov 23 14:04 mc ttyp1 Dec 2 10:53 (sulaco.mcslp.pri) mc ttyp2 Dec 10 06:50 (sulaco.mcslp.pri) admin ttyp3 Dec 12 13:33 mc ttyp4 Dec 15 12:38 (nautilus.mcslp.p) |
远程执行还模拟客户端主机的标准输入、输出和错误。这意味着您可以将输出重新定向到远程命令。例如,您可以直接将信息附加到远程文件,方法是通过管道将输出从命令传输到远程主机上的 SSH(请参见清单 7)。
清单 7. 直接将信息附加到远程文件
$ echo "Hello World" |ssh mc@remotehost 'cat >> helloworlds.txt' |
在使用 SSH 简化登录过程时,您可以使用此方法提高工作效率。
使用 SFTP 交换文件
sft 命令是一种与 FTP 类似的替代方法,它使用 SSH 协议提供的安全通信通道。
要打开 SFTP 连接,请在命令行上指定主机名:
$ sftp remotehost |
请记住,上面的命令假设您希望使用的登录方式与当前主机相同。要使用不同的登录方式,请将在主机名前加上用户名:
$ sftp mc@remotehost |
尽管 SFTP 的工作方式与 FTP 类似,但仍存在一些局限性和差异。例如,FTP 中的 dir 提供了一个长文件列表(请参见清单 8)。
ftp> dir 502 'EPSV': command not understood. 227 Entering Passive Mode (192,168,0,110,150,159) 150 Opening ASCII mode data connection for directory listing. total 1472 drwx------ 3 mc staff 102 Nov 4 11:17 Desktop drwx------ 3 mc staff 102 Nov 4 11:17 Documents drwx------ 18 mc staff 612 Nov 5 18:01 Library drwx------ 3 mc staff 102 Nov 4 11:17 Movies drwx------ 3 mc staff 102 Nov 4 11:17 Music drwx------ 4 mc staff 136 Nov 4 11:17 Pictures drwxr-xr-x 4 mc staff 136 Nov 4 11:17 Public drwxr-xr-x 6 mc staff 204 Nov 4 11:17 Sites drwxrwxrwx 3 root staff 102 Dec 24 07:30 tmp drwxr-xr-x 7 root staff 238 Dec 11 08:39 trial 226 Transfer complete. |
在 SFTP 中,dir 的作用相当于主机目录列表命令的别名,它在 UNIX 或 Linux 中为 ls。在缺省情况下,dir 仅提供一个简短列表(请参见清单 9)。
sftp> dir Desktop Documents Library Movies Music Pictures Public Sites tmp trial |
要获得长列表,请使用与 ls 相同的选项(请参见清单 10)。
sftp> dir -l drwx------ 3 mc staff 102 Nov 4 11:17 Desktop drwx------ 3 mc staff 102 Nov 4 11:17 Documents drwx------ 18 mc staff 612 Nov 5 18:01 Library drwx------ 3 mc staff 102 Nov 4 11:17 Movies drwx------ 3 mc staff 102 Nov 4 11:17 Music drwx------ 4 mc staff 136 Nov 4 11:17 Pictures drwxr-xr-x 4 mc staff 136 Nov 4 11:17 Public drwxr-xr-x 6 mc staff 204 Nov 4 11:17 Sites drwxrwxrwx 3 root staff 102 Dec 24 07:30 tmp drwxr-xr-x 7 root staff 238 Dec 11 08:39 trial |
其他命令,如更改目录(cd,本地为 lcd)、创建目录(mkdir)以及发送(put)和接收(get)文件保持不变。后两个命令 put 和 get 都接受通配符(类似于 FTP 中的 mput 和 mget),但在 SFTP 中传输不带通配符的多个文件时要小心。例如,sftp> mget file1 file2 file3 被识别为试图获取 file1 和 file2,并将它们放置在本地目录 file3 中,但该目录可能不存在。
使用 scp 在主机之间复制文件
scp 命令的工作方式与 rc 命令相似,只不过是使用 SSH 协议传输文件。在传输内容相关文件或在 Internet 上自动交换文件时,选用 scp 要好得多。
其格式类似于 rcp;您可以指定之间复制的文件路径,必要时应将主机名合并到该路径。例如,要将 .bashrc 文件从远程主机复制到本地计算机,请使用:
$ scp remotehost:/users/mc/.bashrc ~/.bashrc |
和前面一样,若指定要使用的用户名,请在主机前面加上用户名,并用 @ 符号分开:
$ scp mc@remotehost:/users/mc/.bashrc ~/.bashrc |
假设您用于连接的用户有读取权限,还需要使用元字符 ~ 才能访问主目录中的信息。
$ scp mc@remotehost:~mc/.bashrc ~/.bashrc |
要从登录用户的主目录中进行复制,请使用:
$ scp mc@remotehost:.bashrc ~/.bashrc |
scp 命令还支持标准扩展规则。所以,要复制所有的 .bash* 文件,您可以使用:
$ scp mc@remotehost:.bash* ~ |
您甚至还可以通过使用展开的大括号 ({}) 更具体地选择单个文件:
$ scp mc@remotehost:".bash{rc,_path,_aliases,_vars}" ~ |
请注意,文件路径中展开的大括号(不是完整的远程路径表达式)已用双引号括上。
在上面所有的示例中,系统都会提示您输入远程主机的密码。通过为主机提供您自己的个人密钥的公共部分可以避免这种情况。
使用公共密钥启用自动登录
当您使用 ssh、sftp 或 scp 登录到远程系统后,您仍需要使用密码才能完成登录过程。通过创建公钥或私钥,将密钥的公共部分附加到 ~/.ssh/authorized_keys 文件,并与远程站点交换了有效密钥后,您可以省去提供密码的要求并允许自动登录。
要创建公钥或私钥,您需要使用 ssh-keygen 来指定密钥加密的类型。在演示中使用了 rsa 密钥类型,但是其他密钥类型也有效。要创建密钥,请参见清单 11。
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): |
您应输入保存密钥(公共和私有组件)的文件的位置。使用缺省值(在主目录中的 .ssh 目录中)一般就可以了(请参见清单 12)。
Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): |
如果您在此阶段输入了密码,则会创建安全密钥文件,但是在每次使用密钥时,还必须输入密码。按 Return 意味着不需要任何密码(请参见清单 13)。
清单 13. 通过按 Return 键跳过密码需求
Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 98:da:8d:48:a8:09:44:b1:b3:62:51:2d:a9:6b:61:ba root@remotehost |
现在已创建了公钥 (id_rsa.pub) 和对应的私钥 (id_rsa)。
要启用自动登录,您必须将公钥的内容复制到远程主机上 ~/.ssh 目录中的 authorized_keys 文件中。您可以使用 SSH 自动完成此操作(请参见清单 14)。
$ cat ./.ssh/id_rsa.pub | ssh mc@remotehost 'cat >> .ssh/authorized_keys'; |
还有,如果在多个主机中经常执行此操作,则可以使用小脚本或 Shell 函数来执行所有必需步骤,如清单 15 所示。
OLDDIR='pwd'; if [ -z "$1" ]; then echo Need user@host info; exit; fi; cd $HOME; if [ -e "./.ssh/id_rsa.pub" ]; then cat ./.ssh/id_rsa.pub | ssh $1 'cat >> .ssh/authorized_keys'; else ssh-keygen -t rsa; cat ./.ssh/id_rsa.pub | ssh $1 'cat >> .ssh/authorized_keys'; fi; cd $OLDDIR |
您可以使用 setremotekey 脚本复制现有密钥,如果密钥不存在,可在复制之前创建一个:
$ setremotekey mc@remotehost |
现在,每当需要使用公钥登录到远程主机时,您可以结合使用个人密钥脚本和远程主机上该用户接受的密钥列表。
总结
OpenSSH 是一个重要工具,它可以保护计算机之间的通信和信息传输的安全。它不仅是常规工具(如 Telnet、FTP 和 RCP)的安全替代方法,而且还可以充当其他服务(如 Subversion、X Windows System 和 rsync)的传输协议。本文向您介绍了启动和运行 OpenSSH 所需的基本步骤,如何最有效地使用 OpenSSH 提供的主要工具,以及如何使用密钥交换工具来简化登录和连接性问题。