FreeBSD 使用手册
上一页 | 第14章 　安全 | 下一页

# 14.10 OpenSSH

原著 Chern Lee.

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

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

## 14.10.1 使用 OpenSSH 的好处

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

## 14.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

## 14.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: *******

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

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

## 14.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 在网上传递的， 因此某些文件的名字需要写成 `用户名@主机名:<远程文件路径>`。

## 14.10.5 配置

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

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

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

## 14.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`， 文件名取决于您选择的 DSA 和 RSA 密钥类型。 RSA 或者 DSA 公钥必须被存放到远程机器上的 `~/.ssh/authorized_keys` 才能够使系统正确运转。

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

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

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

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

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

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

## 14.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 密钥了。

## 14.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 连接转发到远程主机/端口。

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

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

例 14-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 隧道环境。 密钥可以被用在需要输入口令的地方， 而且可以为不同的用户配置不同的隧道。

### 14.10.8.1 实用的 SSH 通道例子

#### 14.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`。

#### 14.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 端口， 从而绕过防火墙。

## 14.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

## 14.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)

上一页 | 起始页 | 下一页
IPsec 上的 VPN | 上一级 | 文件系统访问控制表

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

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.