14.12. OpenSSH

原著 Chern Lee.

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

OpenSSH 由 OpenBSD project 维护, 它基于 SSH v1.2.12 并包含了最新的错误修复和更新。 它同时兼容 SSH 协议的 1 和 2 两个版本。 从 FreeBSD 4.0 开始, OpenSSH 成为了基本系统的一部分。

14.12.1. 使用 OpenSSH 的好处

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

14.12.2. 启用 sshd

确信已将下面这行加入了 rc.conf 文件:

sshd_enable="YES"

将在下次启动系统时加载 OpenSSHsshd(8) 服务程序。 另外, 也可以简单地使用 sshd 来直接启动 sshd 服务。

14.12.3. SSH 客户

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

# ssh [email protected]
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.
[email protected]'s password: *******

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

默认情况下 OpenSSH 服务器的配置会接受 SSH v1 和 SSH v2 的连接。 然而, 客户端则可以选择两者之一。 一般认为, 第2版更加健壮和安全。

通过 -1-2 参数, 可以强制 ssh(1) 使用 v1 或 v2 的协议。

14.12.4. 安全复制

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

# scp [email protected]:/COPYRIGHT COPYRIGHT
[email protected]'s password: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#

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

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

14.12.5. 配置

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

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

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

14.12.6. ssh-keygen

ssh-keygen(1) 可以被用来生成 RSA 密钥对来代替使用口令验证用户的身份:

% ssh-keygen -t rsa1
Initializing random number generator...
Generating p:  .++ (distance 66)
Generating q:  ..............................++ (distance 498)
Computing the keys...
Key generation complete.
Enter file in which to save the key (/home/user/.ssh/identity):
Enter passphrase:
Enter the same passphrase again:
Your identification has been saved in /home/user/.ssh/identity.
...

ssh-keygen(1) 将产生一个公私密钥对来用于验证身份。 私钥被保存到 ~/.ssh/identity, 而公钥则保存到 ~/.ssh/identity.pub。 远程机器上的 ~/.ssh/authorized_keys 中必须有对应的公钥, 才能够完成身份验证过程。

这将允许从远程以基于 RSA 的验证来代替口令验证连接到本机上。

Note: 使用 -t rsa1 这个选项将创建用于 第1版 SSH 协议的 RSA 密钥对。 如果您希望使用用于 SSH 第2版协议的 RSA密钥对, 则应使用 ssh-keygen -t rsa 这个命令。

如果在 ssh-keygen(1) 中使用了通行字, 则每次使用私钥时都需要输入它。

另外, 还可以使用 ssh-keygen -t dsa 来创建一个用于第2版 SSH 协议的 DSA 密钥。 这将生成一对 DSA 公/私钥, 并且只能用于第2版的 SSH 协议会话。 公钥将保存为 ~/.ssh/id_dsa.pub, 而私钥保存为 ~/.ssh/id_dsa

DSA 公钥也应该放到远程主机的 ~/.ssh/authorized_keys 里面。

ssh-agent(1)ssh-add(1) 是用于管理多个受密码保护的私钥的工具。

Warning随版本的不同, OpenSSH 可能会使用不同的文件和选项。 为了避免出现问题, 请参考 ssh-keygen(1) 联机手册。

14.12.7. SSH 隧道

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

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

% ssh -2 -N -f -L 5023:localhost:23 [email protected]
%

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

-2

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

-N

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

-f

强制 ssh 在后台执行。

-L

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

[email protected]

远程 SSH 服务器。

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

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

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

Example 14-1. 使用 SSH 为 SMTP 创建安全隧道

% ssh -2 -N -f -L 5025:localhost:25 [email protected]
[email protected]'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 隧道环境。 密钥可以被用在需要输入口令的地方, 而且可以为不同的用户配置不同的隧道。

14.12.7.1. 实用的 SSH 通道例子

14.12.7.1.1. 加强 POP3 服务的安全

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

% ssh -2 -N -f -L 2110:mail.example.com:110 [email protected]
[email protected]'s password: ******

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

14.12.7.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 [email protected]
[email protected]'s password: *******

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

14.12.8. 进一步的资料

OpenSSH

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

sshd(8) sftp-server(8)