使用 OpenSSH 完成所有操作,第 2 部分
欢迎回到系统管理员专栏,继续关于安全通信(SSH 风格)的传奇故事。登录到 SSH 服务器非常容易,并且为您提供安全的通信,但仍然向全世界开放。您可以设置一个防火墙,仅允许某些 IP 地址访问端口 22,但这会带来另一个问题。如果您在旅途中,并且需要访问自己的系统,则可能从具有动态 IP 的不受信任的系统进行连接。一个好的 iptables 规则在这里无济于事,除非您有人永久待命,可以接听您的电话并为您输入命令——而且这个人还需要拥有 root 访问权限。无论您怎么看,这都可能变得很麻烦。
另一种选择是保持端口 22 完全开放,并将您的服务器设置为仅允许公钥身份验证。此选项比仅仅运行 sshd 并忘记它需要更多的工作。但作为一个额外的奖励,您可以安全地登录而无需密码。他刚才说“无需密码”吗?是的,他说过,而且您可以安全地这样做。事实上,公钥身份验证可能比传统的密码系统更安全,因为仅仅知道密码是不够的。
以下是它的工作原理。使用密钥生成程序,您创建一个密钥对,其中包含一个公钥(复制到服务器)和一个私钥(您将其保存在您的 PC 上并像保护生命一样保护它)。没有这两个密钥,就无法进行身份验证。
要生成您自己的公钥,请使用 ssh-keygen 命令,并指定加密类型。在以下示例中,我使用了 RSA 加密,这是大多数人应该使用的加密方式。其他加密类型包括 rsa 和 dsa。还有一个用于旧协议 1 ssh 的 rsa1,但您很可能不需要它——至少现在不需要。
如果您键入 ssh-keygen -t rsa,命令的输出如下所示
Generating public/private rsa key pair. Enter file in which to save the key (/home/mgagne/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mgagne/.ssh/id_rsa. Your public key has been saved in /home/mgagne/.ssh/id_rsa.pub. The key fingerprint is: 0b:76:f2:a3:54:20:86:74:fe:9d:64:56:c4:85:a9:7f mgagne@ultraman
对于有关密钥存储位置的问题,您几乎可以接受默认设置。但是,请注意第二个问题,即对口令的要求。如果您愿意,您可以在此处不输入任何内容,将您的密钥上传到服务器,并且在连接时无需任何密码。毕竟,这听起来像是您只是用一个密码换了另一个密码。但是,这个想法有一个陷阱。如果有人获得了您私钥的副本,那么这个人可以毫不费力地进入您的所有其他系统。考虑到这种危险,您肯定希望使用口令来保护自己——那么您获得了什么呢?
嗯,事实证明,有一种方法可以绕过这个障碍,我稍后会告诉您。但首先,我想告诉您如何处理您的公钥。 ssh-keygen 命令为您的公钥创建一个名为 id_rsa.pub 的文件,您需要将其内容传输到远程系统。该密钥是一个文本文件,其内容如下所示。尽管下面的内容跨越了几行,但实际上,这是一行不间断的文本。
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAp1Z/aG2VrRzstY6D4eNZ5PM1ank0h1CUrku RTJowLW65ucAWVokAxOS6Ao26ymYMmVB/0+bVip3Bm1w5hGb/hLZQmD87ZgCwyU WhWaPd+YE1fmqzU2nBRxQ1Ud2xqjFCcwdSWesE= mgagne@ultraman
您的下一步是连接到正在运行 sshd 进程的远程服务器。您可能需要打开另一个窗口来执行此操作,因为我们将进行一些复制和粘贴。这应该使您进入用户的主目录。从那里,cd 到主目录中的 .ssh 目录,并查找名为 authorized_keys 的文件。如果它不存在,请创建它。现在,将 id_rsa.pub 密钥复制并粘贴到 authorized_keys 文件中,请记住密钥必须完全复制。您也可以将其传输到远程系统并将其附加到 authorized_keys 文件,如下所示
cat id_rsa.pub >> $HOME/.ssh/authorized_keys
在我们继续之前,请注意:此文件的权限不能是组或世界可写的,否则此过程将无法工作。您必须执行 chmod 644 authorized_keys 以确保该文件只能由所有者写入。
当您下次使用 ssh -l user_name remote_sys 连接到远程系统时,您将无需输入密码即可连接。正如我提到的,但是,在没有密码的情况下创建您的公钥/私钥对可能是一个坏主意。如果有人得到了您的密钥,那么一切都完了;您通过运行安全 shell 可能获得的任何安全性都几乎消失殆尽。您唯一的选择是在使用 ssh-keygen 生成密钥对时使用口令,但这样您又回到了使用密码——这是我在文章开头向您承诺要摆脱的东西。难道没有出路了吗?
这个难题正是一个名为 ssh-agent 的优秀小程序发挥作用的地方。如果您已经创建了无口令的密钥对,请重新开始并这次提供口令。将公钥移动到您的服务器(记住从 .ssh/authorized_keys 文件中删除旧的公钥),并测试您的连接。您应该被要求输入您的口令,而不是用户的密码。到目前为止,一切顺利?
在启动 ssh-agent 之前,您可能需要查找它的进程,因为您的窗口管理器可能会为您启动它。例如,在我的 Mandrake 9.1 系统上,系统范围的 /etc/X11/Xsession 文件中存在这一小段代码。
AGENT=$(type -p ssh-agent) if [ -x "$AGENT" -a -z "$SSH_AUTH_SOCK" ]; then if [ -r $HOME/.ssh/identity -o -r $HOME/.ssh2/identificati SSH_AGENT="$AGENT --" fi fi
事实上,如果我在我的笔记本电脑上执行 ps ax | grep ssh-agent,我会看到以下内容
3209 ? S 0:00 ssh-agent 3475 ? S 0:00 /usr//bin/ssh-agent -- /bin/sh -c #!/b
因此,ssh-agent 显然正在运行,但当我连接到我的远程系统时,我仍然被要求输入口令。显然,仅仅运行 ssh-agent 是不够的。那是因为虽然 ssh-agent 可能正在运行,但它还不知道您的口令。您可以使用 ssh-add 命令来告知该进程。
$ ssh-add Enter passphrase for /home/mgagne/.ssh/id_rsa: Identity added: /home/mgagne/.ssh/id_rsa (/home/mgagne/.ssh/id_
如您所见,我被要求输入我的私钥的口令。在我输入之后,我就可以在没有口令的情况下连接到远程系统了——简单且安全。幸运的是,ssh-agent 在您注销后不会记住这些信息。否则,一旦使用 ssh-add 输入了口令,如果有人侵入您的系统,受保护口令的安全性将毫无意义。
顺便说一句,即使您没有运行 X 窗口图形环境,也可以使用 ssh-agent。让我们假设您已登录到纯文本会话。从命令行,您可以键入 ssh-agent /bin/bash,此时您将拥有一个由 ssh-agent 包装的 bash shell。从那里,您可以执行 ssh-add 命令,输入您的口令并相应地使用您的各种系统。
我们现在又回到了起点。一切都按预期工作,您已准备好将您的 sshd 服务器切换到完全不允许密码的身份验证。这样,您可以将端口 22 连接向世界开放,因为您知道只有完全通过身份验证的公钥客户端才能连接到您的系统。以下是您的操作步骤。打开 /etc/ssh/sshd_config 文件并查找以下行
# PasswordAuthentication yes
该行很可能被注释掉了,因为允许密码身份验证是默认设置。取消注释该行,并将 yes 更改为 no。然后,重新启动您的 sshd 服务器守护进程。如果您有点担心将自己锁定在外面,您可以让当前进程运行,并在另一个端口(例如 2222)上启动第二个服务器,正如我在我之前的专栏文章中介绍的那样。
/usr/sbin/sshd -p 2222
现在,如果您尝试在端口 2222 上登录服务器,而服务器上没有相应的公钥,您将无法进一步操作。
$ ssh -p 2222 -l marcel remotesys Permission denied (publickey,keyboard-interactive).
嗯,我想我已经用完了今天的字数配额了。下次,我将告诉您如何在您的 (gasp!) Windows PC 上执行此操作。我还将讨论远程程序执行、安全传输和许多其他令人兴奋的事情。在下次之前,我希望您感觉更安全一点。
Marcel Gagné 是 Linux Journal 的法式主厨和 Linux 的真正信徒。他的新书 Moving to Linux: Kiss the Blue Screen of Death Goodbye! 将于 2003 年 8 月出版。您可以从他的网站 www.marcelgagne.com 了解更多信息。
电子邮件:mggagne@salmar.com