13.8. OpenSSH

Contributed by Chern Lee.

OpenSSH是一套网路连线工具,可安全的存取远端的主机,此外,透过SSH联机可以建立TCP/ IP 联机信道或安全的转送TCP/ IP 的封包。OpenSSH会对所有传输的数据做加密,可有效的避免窃听(Eavesdropping)、或联机劫持(Connection hijacking)与其他网络层的攻击。

OpenSSH由OpenBSD项目所维护且在FreeBSD预设会安装,它可同时兼容SSH版本1与2通信协定。

当以未加密的方式在网路上传送数据时,任何在客户端与服务器之间的网络窃听程序(Network sniffer)皆可窃取使用者/密码信息或者在联机阶段传送的数据,OpenSSH提供了数种认证与加密方式来避免这种事情发生。更多有关OpenSSH的信息可于http://www.openssh.com/取得。

本节会简单介绍如何使用内置的客户端工具安全的存取其他系统及安全的传输档案到FreeBSD系统,然后会说明如何设定在FreeBSD系统上的SSH服务器。更多的信息可于本章节所提及的操作手册(Man page)取得。

13.8.1. 使用SSH客户端工具

要登入一台SSH服务器,可使用ssh然后指定在服务器上存在的使用者名称与 IP 位址或服务器的主机名称。若这是第一次联机到指定的服务器,会提示该使用者服务器的指纹做第一次检验:

# ssh user@example.com
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? yes
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: user_password

SSH会在客户端联机时利用密钥指纹(Key fingerprint)系统来验证服务器的真伪,当使用者在第一次联机时输入yes接受了这个密钥指纹,便会将该密钥的复本储存到使用者家目录的.ssh/known_hosts,未来尝试登入时便会以这个存好的密钥来验证,若服务器的密钥与储存的密钥不同将会显示警告信息。若出现这个警告时,使用者应在继续联机之前检查密钥变动的原因。

最近版本的OpenSSH预设只会接受SSHv2的联机。客户端预设会尽可能使用版本2的通信协定,若服务器不支持版本2的通信协定便会向下兼容版本1的协定。要强制ssh只能使用指定的通信协定,可使用-1-2,其他的选项在ssh(1)中有说明。

使用scp(1)可从远端主机安全的复制一个档案,以下示例会复制在远端主机的COPYRIGHT到本地主机的目前目录:

# scp user@example.com:/COPYRIGHT COPYRIGHT
Password for user@example.com: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#

由于这个主机的指纹已验证过,在提示用者输入密码之前服务器的密钥已自动检查。

传给scp的参数与传给cp的参数相似。第一个参数是要复制的档案,第二个参数是目地,由于档案是透过网络取得,档案参数需要使用user@host:<path_to_remote_file>格式。注意,在scp要递归复制目录是使用-r,如同cp使用-R

要开启可互动的联机来复制档案可使用sftp,请参考sftp(1)来取得在sftp联机时可用的指令清单。

13.8.1.1. 以密钥为基础的认证

除了使用密码之外,客户端可以设定成使用密钥来联机到远端的主机。要产生RSA认证密钥可使用ssh-keygen。要产生成对的公钥与私钥,可指定密钥的类型并依提示操作。建议使用容易记住但较难猜出的密码来保护这个密钥。

% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):  1
Enter same passphrase again:                 2
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|        . o..    |
|       .S*+*o    |
|      . O=Oo . . |
|       = Oo= oo..|
|      .oB.* +.oo.|
|       =OE**.o..=|
+----[SHA256]-----+

1

在此输入密码,密码不可含有空白或符号。

2

再输入一次密码验证。

私钥会储存于~/.ssh/id_rsa而公钥会储存于~/.ssh/id_rsa.pub公钥必须复制到远端主机的~/.ssh/authorized_keys来让以密钥为基础的认证可以运作。

警告:

许多使用者认为密钥的设计是安全的并在产生密钥时未使用密码,这样的行为其实很危险。管理者可以手动查看私钥来检查密钥对是否受密码保护,如果私钥档案中包含 ENCRYPTED字词,则代表密钥的拥有者有使用密码。此外,要更进一步保护最终使用者的安全,可在公钥档案中放入from,例如,在ssh-rsa前加上from=“192.168.10.5”将只允许指定的使用者由该IP位址登入。

不同版本OpenSSH的选项与档案会不同,要避免发生问题请参考ssh-keygen(1)

若使用了密码,在每次联机到服务器时都会提示使用者输入密码。要将SSH密钥加载到內存并让每次联机时不必再输入密码,可使用ssh-agent(1)ssh-add(1)

认证可用ssh-agent来管理,只要将私钥加载,ssh-agent可用在执行其他应用程序,如Shell或视窗管理程序。

要在Shell使用ssh-agent,使用Shell做为参数来启动ssh-agent。执行ssh-add来加入识别码,然后输入私钥的密码。使用者将可使用ssh联机到任何有安装对应公钥的主机,例如:

% ssh-agent csh
% ssh-add
Enter passphrase for key '/usr/home/user/.ssh/id_rsa':  1
Identity added: /usr/home/user/.ssh/id_rsa (/usr/home/user/.ssh/id_rsa)
%

1

输入密钥的密码。

要在Xorg使用ssh-agent可在~/.xinitrc加入一个设定项目,这可让ssh-agent对所有在Xorg中执行的程序提供服务。~/.xinitrc示例如下:

exec ssh-agent startxfce4

这会在每次启动Xorg时,反过来先执行ssh-agent再由执行XFCE,一但Xorg被重新启动,要让所有变更生效需执行 ssh-add来加载所有的SSH密钥。

13.8.1.2. SSH信道

OpenSSH可以建立一个信道(Tunnel)来封装其他通信协定到一个加密的联机。

以下指令会告诉ssh建立一个供telnet使用的信道:

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

这个例子使用了以下选项:

-2

强制ssh使用版本2的通信协定联机到服务器。

-N

代表不需下指令、只建立信道。若省略这个选项ssh会初始化一个正常的联机。

-f

强制ssh在背景执行。

-L

代表这是一个本地信道,使用localport:remotehost:remoteport格式。

user@foo.example.com

在指定的远端SSH服务器要使用的登入名称。

SSH信道会建立一个倾听localhost指定localport的Socket,然后会透过SSH联机转送任何在localport接收的联机。以这个例子来说在客户端的Port 5023会被转送到远端主机的Port23,由于Port 23是由telnet使用,所以这会透过SSH信道建立一个加密的telnet联机。

这个方法可用来包装许多不安全的TCP通信协定,例如SMTPPOP3以及FTP,如下例所示。

例 13.1. 建立供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与另一个使用者帐号与来建立一个更无缝的SSH信道环境,可使用密钥来代替手动输入密码,然后该信道便可以另一个使用者执行。


例 13.2. 安全存取POP3服务器

在这个例子中有一个SSH服务器会接受来自外部的联机,在同个网段下有一个邮件服务器执行POP3服务器。要使用较安全的方式检查有没有新邮件可建立一个 SSH联机到SSH服务器然后透过信道联机到邮件服务器:

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

一但信道启动并执行后,指定邮件客户端将POP3请求传送到localhost的Port 2110,这个联机将会被安全的透过信道转送到mail.example.com


例 13.3. 跳过防火墙

有些防火墙会同时过滤传入与传出的联机。例如,防火墙很可能会限制来自远端主机只能存取Port 22与80来只让SSH与网页浏览器联机,这会使得Port使用22或80以外的服务无法存取。

这问题的解决方法是建立一个SSH联机到在防火墙防护之外主机然后使用该联机的信道连到想要使用的服务:

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

在这个例子中,串流Ogg Vorbis客户端现在可以指向localhost Port 8888,联机将会被转送到music.example.com于Port 8000,成功的跳过防火墙。


13.8.2. 开启SSH服务器

除了提供内置的SSH客户端工具外,还可以设定FreeBSD系统为一个SSH服务器,以接受来自其他SSH客户端的联机。

要查看sshd是否正在运作,可使用service(8)指令:

# service sshd status

若服务未执行,请加入下行到/etc/rc.conf

sshd_enable="YES"

这会让下次系统开机时启动OpenSSH的Daemon程序sshd。若要立即启动:

# service sshd start

在FreeBSD系统第一次启动sshd时便会自动产生系统的主机密钥且会显示指纹在Console上,这个指纹可供使用者在第一次联机到服务器时验证用。

请参考sshd(8)可取得在启动sshd时可用选项的清单以及更多完整有关认证、登入程序与各种配置文件的信息。

现在,sshd应可供所有在系统上有使用者名称及密码的使用者使用。

13.8.3. SSH服务器安全性

在FreeBSD广泛使用sshd做为远端管理基础设施的同时,所有暴露在公有网络上的系统也会时常受到暴力攻击(Brute force attack)与路过攻击(Drive by attack)。在本节会介绍一些可用来避免这些攻击的参数。

使用在OpenSSH服务器配置文件的AllowUsers关键字限制可以登入到SSH服务器的使用者及来源是一个不错的方式。例如要只允许来自192.168.1.32root登入,可加入下行到/etc/ssh/sshd_config

AllowUsers root@192.168.1.32

要允许来自任何地方的admin登入,可只列出使用者名称,不指定 IP 位址:

AllowUsers admin

有多位使用者也应列在同一行,例如:

AllowUsers root@192.168.1.32 admin

在对/etc/ssh/sshd_config做完变更后,执行以下指令告诉sshd重新加载配置文件:

# service sshd reload

注意:

在使用了这个关键字时,列出每一位需要登入此主机的使用者很重要,任何未被在该行指定的使用者将无法登入。同时,在OpenSSH服务器配置文件使用的关键字是区分大小写的,若关键字未正确的拼写(含其大小写),则将会被忽略,永远要记得测试对这个档案所做的更改来确保服务器有如预期的方式运作。请参考sshd_config(5)来检查拼写以及可用的关键字。

此外,使用者可能被强制要透过公钥与私钥使用双重认证(Two factor authentication)。当需要时,使用者可以透过使用ssh-keygen(1)产生一堆密钥然后将公钥传送给管理者,这个密钥档会如以上在客户端章节所述的被放在authorized_keys。要强制使用者只能使用这个密钥,可能需要设定以下选项:

AuthenticationMethods publickey

提示:

请不要将/etc/ssh/sshd_config以及/etc/ssh/ssh_config搞混(注意在第一节文件名有多出个d),第一个档案用来设定服务器,而第二个档案用来设定客户端。请参考ssh_config(5)来取得可用的客户端设定清单。

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

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

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