15.10. OpenSSH

原著 Chern Lee.

OpenSSH 是一组用于安全地访问远程计算机的连接工具。 它可以作为 rloginrsh rcp 以及 telnet 的直接替代品使用。 更进一步, 其他任何 TCP/IP 连接都可以通过 SSH 安全地进行隧道/转发。 OpenSSH 对所有的传输进行加密, 从而有效地阻止了窃听、 连接劫持, 以及其他网络级的攻击。

OpenSSH 由 OpenBSD project 维护, 它基于 SSH v1.2.12 并包含了最新的错误修复和更新。 它同时兼容 SSH 协议的 1 和 2 两个版本。

15.10.1. 使用 OpenSSH 的好处

一般说来, 在使用 telnet(1)rlogin(1) 时, 数据是以未经加密的明文的形式发送的。 这样一来, 在客户机和服务器之间的网络上运行的听包程序, 便可以在会话中窃取到传输的用户名/密码和数据。 OpenSSH 提供了多种的身份验证和加密方法来防止这种情况的发生。

15.10.2. 启用 sshd

sshd 的启用是作为 FreeBSD 安装中 Standard 安装过程中的一步来进行的。 要查看 sshd 是否已被启用, 请检查 rc.conf 文件中的:

sshd_enable="YES"

这表示在下次系统启动时加载 OpenSSH 的服务程序 sshd(8)。 此外, 也可以手动使用 rc(8) 脚本 /etc/rc.d/sshd 来启动 OpenSSH

/etc/rc.d/sshd start

15.10.3. SSH 客户

ssh(1) 的工作方式和 rlogin(1) 非常类似。

# ssh user@example.com
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)? yes
Host 'example.com' added to the list of known hosts.
user@example.com's password: *******

登录过程和使用 rlogintelnet 建立的会话非常类似。 在连接时, SSH 会利用一个密钥指纹系统来验证服务器的真实性。 只有在第一次连接时, 用户会被要求输入 yes。 之后的连接将会验证预先保存下来的密钥指纹。 如果保存的指纹与登录时接收到的不符, 则将会给出警告。 指纹保存在 ~/.ssh/known_hosts 中, 对于 SSH v2 指纹, 则是 ~/.ssh/known_hosts2

默认情况下, 较新版本的 OpenSSH 只接受 SSH v2 连接。 如果能用版本 2 则客户程序会自动使用, 否则它会返回使用版本 1 的模式。 此外, 也可以通过命令行参数 -1-2 来相应地强制使用版本 1 或 2。 保持客户端的版本 1 能力是为了考虑较早版本的兼容性。

15.10.4. 安全复制

scp(1) 命令和 rcp(1); 的用法类似, 它用于将文件复制到远程的机器上, 或复制过来, 区别是它是安全的。

#  scp user@example.com:/COPYRIGHT COPYRIGHT
user@example.com's password: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#

由于先前的例子中已经保存了指纹, 使用 scp(1) 时会自动地加以验证。

scp(1) 使用的参数同 cp(1) 类似。 第一个参数是一个或一组文件, 然后是复制的目标。 由于文件是通过 SSH 在网上传递的, 因此某些文件的名字需要写成 用户名@主机名:<远程文件路径>

15.10.5. 配置

针对 OpenSSH 服务程序和客户端的系统级配置文件在 /etc/ssh 目录中。

ssh_config 用于配置客户端的设定, 而 sshd_config 则用于配置服务器端。

另外 sshd_program (默认是 /usr/sbin/sshd), 以及 sshd_flags 这两个 rc.conf 选项提供了更多的配置选择。

15.10.6. ssh-keygen

用于取代口令的一种方法是使用 ssh-keygen(1) 来生成 DSA 或 RSA 密钥对用于验证用户的身份:

% ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_dsa):
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_dsa.
Your public key has been saved in /home/user/.ssh/id_dsa.pub.
The key fingerprint is:
bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com

ssh-keygen(1) 会生成一个包含公私钥对用于验证身份。 私钥将保存到 ~/.ssh/id_dsa~/.ssh/id_rsa, 而公钥则被存放到 ~/.ssh/id_dsa.pub~/.ssh/id_rsa.pub, 文件名取决于您选择的 DSARSA 密钥类型。 RSA 或者 DSA 公钥必须被存放到远程机器上的 ~/.ssh/authorized_keys 才能够使系统正确运转。

这将允许从远程连接时以基于 SSH 密钥的验证来代替口令验证。

如果在 ssh-keygen(1) 中使用了通行字, 则每次使用私钥时都需要输入它。 ssh-agent(1) 能够缓解多次输入长通行字的压力, 并将在接下来的 第 15.10.7 节 “ssh-agent 和 ssh-add” 予以详述。

警告:

选项和配置文件可能随 OpenSSH 的版本不同而不同; 为了避免出现问题, 您应参考 ssh-keygen(1) 联机手册。

这将使到远程机器的连接基于 SSH 密钥而不是口令。

如果在运行 ssh-keygen(1) 时使用了通行字, 每次使用私钥的时候用户都将被要求输入通行字。 ssh-agent(1) 能够减缓重复输入较长通行字的负担, 有关更详细的探究在 第 15.10.7 节 “ssh-agent 和 ssh-add” 下一节 .

警告:

随着你系统上的 OpenSSH 版本的不同,各种选项和配置文件也会不同; 为了避免此类问题, 你需要参阅 ssh-keygen(1) 联机手册。

15.10.7. ssh-agent 和 ssh-add

ssh-agent(1)ssh-add(1) 这两个工具, 提供了一种将 SSH 秘钥加载到内存中以便使用, 而不必每次都输入通行字的方法。

ssh-agent(1) 工具能够使用加载到其中的私钥来处理验证过程。 ssh-agent(1) 应被用于启动另一个应用程序。 最基本的用法是, 使用它来启动 shell, 而高级一些的用法则是用它来启动窗口管理器。

要在 shell 中使用 ssh-agent(1), 首先应把 shell 作为参数来启动它。 随后, 应通过 ssh-add(1) 并输入通行字, 来向它提供身份验证信息。 一旦这些步骤都做完了, 用户就应该能够 ssh(1) 到任何一个安装了对应公钥的机器了。 例如:

% ssh-agent csh
% ssh-add
Enter passphrase for /home/user/.ssh/id_dsa:
Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa)
%

要在 X11 中使用 ssh-agent(1), 调用 ssh-agent(1) 的过程应置于 ~/.xinitrc 之中。 这将把 ssh-agent(1) 服务提供给所有在 X11 中运行的程序。 下面是一个 ~/.xinitrc 文件的实例:

exec ssh-agent startxfce4

这将启动 ssh-agent(1), 而后者将在每次 X11 启动时运行 XFCE。 作完这些之后就可以重启 X11 以便使修改生效。 随后您就可以运行 ssh-add(1) 来加载全部 SSH 密钥了。

15.10.8. SSH 隧道

OpenSSH 能够创建隧道以便用加密的会话来封装其他协议。

下面的命令告诉 ssh(1)telnet 创建一个隧道:

% ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com
%

上述 ssh 命令使用了下面这些选项:

-2

强制 ssh 使用第2版的协议 (如果需要和较老的 SSH 一同工作请不要使用这个选项)。

-N

表示不使用命令行, 或者说只使用隧道。 如果省略, ssh 将同时初始化会话。

-f

强制 ssh 在后台执行。

-L

表示产生一条 本地端口:远程主机:远程端口 形式的隧道。

user@foo.example.com

远程 SSH 服务器。

SSH 隧道通过监听 localhost 上面指定端口来完成工作。 它将把本机主机/端口上接收到的连接通过 SSH 连接转发到远程主机/端口。

本例中, 位于 localhost5023 端口 被用于转发 localhost 的连接到远程主机的 23 端口。 由于 23telnet 使用的, 因此它将通过 SSH 隧道完成 telnet 会话。

这可以用来封装任意不安全的 TCP 协议, 例如 SMTP、 POP3、 FTP等等。

例 15.1. 使用 SSH 为 SMTP 创建安全隧道
% ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com
user@mailserver.example.com's password: *****
% telnet localhost 5025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mailserver.example.com ESMTP

这可以与 ssh-keygen(1) 以及额外的用户帐号配合来建立一个更透明的 SSH 隧道环境。 密钥可以被用在需要输入口令的地方, 而且可以为不同的用户配置不同的隧道。


15.10.8.1. 实用的 SSH 通道例子

15.10.8.1.1. 加强 POP3 服务的安全

工作时, 有一个允许外来连接的 SSH 服务器。 同一个办公网络中有一个邮件服务器提供 POP3 服务。 这个网络, 或从您家到办公室的网络可能不, 或不完全可信。 基于这样的原因, 您需要以安全的方式来查看邮件。 解决方法是创建一个到办公室 SSH 服务器的连接, 并通过这个连接来访问 POP3 服务:

% ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com
user@ssh-server.example.com's password: ******

当这个通道连上时, 您可以把 POP3 请求发到 localhost 端口 2110。 这个连接将通过通道安全地转发到 mail.example.com

15.10.8.1.2. 绕过严厉的防火墙

一些大脑长包的网络管理员会使用一些极端的防火墙策略, 不仅过滤进入的连接, 而且也过滤连出的连接。 一些时候您可能只能连接远程机器 22 端口,以及 80 端口用来进行 SSH 和网页浏览。

您可能希望访问一些其它的 (也许与工作无关的) 服务, 例如提供音乐的 Ogg Vorbis 流媒体服务器。 如果 Ogg Vorbis server 在 22 或 80 端口以外的端口播放音乐, 则您将无法访问它。

解决方法是建立一个到您的网络的防火墙之外的网络上的 SSH 服务器, 并通过它提供的通道连接到 Ogg Vorbis 服务器上。

% ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org
user@unfirewalled-system.example.org's password: *******

现在您可以把客户程序指定到 localhost 的 8888 端口, 它将把请求转发给 music.example.com 的 8000 端口, 从而绕过防火墙。

15.10.9. 允许用户登录 AllowUsers 选项

通常限制哪些用户能够登录, 以及从何处登录会是好主意。 采用 AllowUsers 选项能够方便地达到这一目的。 例如, 想要只允许 root 用户从 192.168.1.32 登录, 就可以在 /etc/ssh/sshd_config 文件中加入下述设置:

AllowUsers root@192.168.1.32

要允许用户 admin 从任何地方登录, 则只需列出用户名:

AllowUsers admin

可以在同一行指定多个用户, 例如:

AllowUsers root@192.168.1.32 admin

注意:

列出需要登录机器的用户很重要; 否则他们将被锁在外面。

在完成对 /etc/ssh/sshd_config 的修改之后您必须告诉 sshd(8) 重新加载其配置文件, 方法是执行:

# /etc/rc.d/sshd reload

15.10.10. 进一步的资料

OpenSSH

ssh(1) scp(1) ssh-keygen(1) ssh-agent(1) ssh-add(1) ssh_config(5)

sshd(8) sftp-server(8) sshd_config(5)

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.