通常,在远程主机上执行命令并将该命令的输入或输出从网络连接读取或写入网络连接非常有用。
用于在远程主机上执行命令的传统命令是 rlogin、rsh 和 rcp。我们在第 1 章的 1.2.1 节中看到了 rlogin 命令的示例。”我们在 1.5.1 节” 中简要讨论了与其相关的安全问题,并建议使用 ssh 作为替代方案。ssh 软件包提供了名为 slogin、ssh 和 scp 的替代品。
这些命令中的每一个都会在远程主机上生成一个 shell,并允许用户执行命令。当然,客户端需要在远程主机上拥有一个帐户,才能执行命令。因此,所有这些命令都使用身份验证过程。r 命令使用主机之间简单的用户名和密码交换,没有加密,因此任何监听的人都可以轻松拦截密码。ssh 命令套件提供了更高级别的安全性:它使用一种称为 公钥加密的技术,该技术在主机之间提供身份验证和加密,以确保密码和会话数据都不会轻易被其他主机拦截。
甚至可以进一步放宽对某些用户的身份验证检查。例如,如果您经常需要登录到 LAN 上的其他机器,您可能希望在无需每次都键入密码的情况下被允许登录。这对于 r 命令始终是可能的,但 ssh 套件允许您更轻松地执行此操作。但这仍然不是一个好主意,因为它意味着如果一台机器上的帐户被攻破,则可以访问该用户配置为无密码登录的所有其他帐户,但这非常方便,人们会使用它。
让我们来谈谈删除 r 命令并让 ssh 取代它的方法。
首先,如果安装了 r 命令,请将其删除。禁用旧 r 命令的最简单方法是在/etc/inetd.conf文件中注释掉(或删除)它们的条目。相关条目看起来像这样
# Shell, login, exec and talk are BSD protocols. shell stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rshd login stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rlogind exec stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rexecd |
OpenSSH 是 ssh 程序套件的免费版本;Linux 端口可以在 http://violet.ibs.com.au/openssh/ 和大多数现代 Linux 发行版中找到。[1] 我们不会在此处描述编译;源代码中包含很好的说明。如果您可以从预编译包中安装它,那么这样做可能是明智的。
一个 ssh 会话包含两个部分。有一个 ssh 客户端,您需要在本地主机上配置和运行它,以及一个 ssh 守护进程,它必须在远程主机上运行。
sshd 守护进程是监听来自 ssh 客户端的网络连接、管理身份验证和执行请求命令的程序。它有一个主配置文件,名为/etc/ssh/sshd_config和一个特殊文件,其中包含身份验证和加密过程使用的密钥,以表示主机端。每个主机和每个客户端都有自己的密钥。
一个名为 ssh-keygen 的实用程序用于生成随机密钥。这通常在安装时使用一次以生成主机密钥,系统管理员通常将其存储在名为/etc/ssh/ssh_host_key的文件中。密钥的长度可以是 512 位或更长。默认情况下,ssh-keygen 生成长度为 1024 位的密钥,大多数人使用默认值。要生成随机密钥,您可以像这样调用 ssh-keygen 命令
# ssh-keygen -f /etc/ssh/ssh_host_key |
系统将提示您输入密码短语。但是,主机密钥不得使用密码短语,因此只需按回车键将其留空即可。程序输出将类似于
Generating RSA keys: ......oooooO...............................oooooO Key generation complete. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /etc/ssh/ssh_host_key Your public key has been saved in /etc/ssh/ssh_host_key.pub The key fingerprint is: 1024 3a:14:78:8e:5a:a3:6b:bc:b0:69:10:23:b7:d8:56:82 root@moria |
您将在最后发现创建了两个文件。第一个称为私钥,必须保密,将在/etc/ssh/ssh_host_key中。第二个称为公钥,您可以共享它;它将在/etc/ssh/ssh_host_key.pub.
中。有了用于 ssh 通信的密钥,您需要创建一个配置文件。ssh 套件非常强大,配置文件可能包含许多选项。我们将提供一个简单的示例来帮助您入门;您应该参考 ssh 文档以启用其他功能。以下代码显示了一个安全且最小的 sshd 配置文件。其余配置选项在 sshd (8) 手册页中详细说明
# /etc/ssh/sshd_config # # The IP adddresses to listen for connections on. 0.0.0.0 means all # local addresses. ListenAddress 0.0.0.0 # The TCP port to listen for connections on. The default is 22. Port 22 # The name of the host key file. HostKey /etc/ssh/ssh_host_key # The length of the key in bits. ServerKeyBits 1024 # Should we allow root logins via ssh? PermitRootLogin no # Should the ssh daemon check users' home directory and files permissions? # are safe before allowing login? StrictModes yes # Should we allow old ~/.rhosts and /etc/hosts.equiv authentication method? RhostsAuthentication no # Should we allow pure RSA authentication? RSAAuthentication yes # Should we allow password authentication? PasswordAuthentication yes # Should we allow /etc/hosts.equiv combined with RSA host authentication? RhostsRSAAuthentication no # Should we ignore ~/.rhosts files? IgnoreRhosts yes # Should we allow logins to accounts with empty passwords? PermitEmptyPasswords no |
确保配置文件的权限正确非常重要,以确保系统安全得到维护。使用以下命令
# chown -R root:root /etc/ssh # chmod 755 /etc/ssh # chmod 600 /etc/ssh/ssh_host_key # chmod 644 /etc/ssh/ssh_host_key.pub # chmod 644 /etc/ssh/sshd_config |
sshd 管理守护进程的最后阶段是运行它。通常,您会为其创建一个rc文件或将其添加到现有文件中,以便在启动时自动执行。守护进程独立运行,不需要在/etc/inetd.conf文件中进行任何条目。守护进程必须以root用户身份运行。语法非常简单
/usr/sbin/sshd |
有许多 ssh 客户端程序:slogin、scp 和 ssh。它们都读取相同的配置文件,通常称为/etc/ssh/ssh_config。它们也都从.ssh目录中读取配置文件,该目录位于执行它们的用户的主目录中。其中最重要的文件是.ssh/config文件,其中可能包含覆盖/etc/ssh/ssh_config文件中的选项,.ssh/identity文件,其中包含用户自己的私钥,以及相应的.ssh/identity.pub文件,其中包含用户的公钥。其他重要文件是.ssh/known_hosts和.ssh/authorized_keys;我们稍后将在 12.5.2.3 节” 中讨论这些文件。首先,让我们创建全局配置文件和用户密钥文件。
/etc/ssh/ssh_config与服务器配置文件非常相似。同样,您可以配置许多功能,但最小配置看起来像 示例 12-5 中所示的那样。其余配置选项在 sshd(8) 手册页中详细说明。您可以添加与特定主机或主机组匹配的部分。“Host”语句的参数可以是主机的完整名称或通配符规范,正如我们在示例中使用的那样,以匹配所有主机。我们可以创建一个条目,例如使用Host *.vbrew.com来匹配vbrew.com域中的任何主机。
示例 12-5。ssh 客户端配置文件示例
# /etc/ssh/ssh_config # Default options to use when connecting to a remote host Host * # Compress the session data? Compression yes # .. using which compression level? (1 - fast/poor, 9 - slow/good) CompressionLevel 6 # Fall back to rsh if the secure connection fails? FallBackToRsh no # Should we send keep-alive messages? Useful if you use IP masquerade KeepAlive yes # Try RSA authentication? RSAAuthentication yes # Try RSA authentication in combination with .rhosts authentication? RhostsRSAAuthentication yes |
我们在服务器配置部分提到,每个主机和用户都有一个密钥。用户的密钥存储在其~/.ssh/identity文件中。要生成密钥,请使用与我们用于生成主机密钥相同的 ssh-keygen 命令,不同的是,这次您不需要指定保存密钥的文件名。ssh-keygen 默认使用正确的位置,但它会提示您输入文件名,以防您想将其保存在其他位置。有时拥有多个身份文件很有用,因此 ssh 允许这样做。与之前一样,ssh-keygen 将提示您输入密码短语。密码短语增加了另一个安全级别,这是一个好主意。当您键入密码短语时,密码短语不会在屏幕上回显。
警告 |
如果您忘记了密码短语,则无法恢复。确保它是您会记住的东西,但与所有密码一样,使其成为不明显的东西,例如专有名词或您的姓名。为了使密码短语真正有效,它应该在 10 到 30 个字符之间,并且不是纯英语散文。尝试加入一些不寻常的字符。如果您忘记了密码短语,您将被迫生成新密钥。 |
$ ssh-keygen Generating RSA keys: .......oooooO.............................. Key generation complete. Enter file in which to save the key (/home/maggie/.ssh/identity): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/maggie/.ssh/identity. Your public key has been saved in /home/maggie/.ssh/identity.pub. The key fingerprint is: 1024 85:49:53:f4:8a:d6:d9:05:d0:1f:23:c4:d7:2a:11:67 maggie@moria $ |
现在 ssh 已准备好运行。
我们现在应该已经安装了 ssh 命令及其关联程序并准备好运行。现在让我们快速了解一下如何运行它们。
首先,我们将尝试远程登录到主机。我们可以使用 slogin 程序,其方式与我们在本书前面示例中使用的 rlogin 程序非常相似。当您第一次尝试连接到主机时,ssh 客户端将检索主机的公钥,并通过提示您提供称为 指纹的公钥缩短版本来要求您确认其身份。
远程主机上的管理员应事先向您提供其公钥指纹,您应将其添加到您的.ssh/known_hosts文件中。如果远程管理员没有向您提供相应的密钥,您可以连接到远程主机,但 ssh 会警告您它确实有一个密钥,并提示您是否要接受远程主机提供的密钥。假设您确信没有人进行 DNS 欺骗,并且您实际上正在与正确的主机通信,请对提示回答是。然后,相关密钥将自动存储在您的.ssh/known_hosts中,并且不会再次提示您输入它。如果在以后的连接尝试中,从该主机检索到的公钥与存储的公钥不匹配,您将收到警告,因为这表示潜在的安全漏洞。
首次登录到远程主机将如下所示
$ slogin vchianti.vbrew.com The authenticity of host 'vchianti.vbrew.com' can't be established. Key fingerprint is 1024 7b:d4:a8:28:c5:19:52:53:3a:fe:8d:95:dd:14:93:f5. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'vchianti.vbrew.com,172.16.2.3' to the list of/ known hosts. maggie@vchianti.vbrew.com's password: Last login: Tue Feb 1 23:28:58 2000 from vstout.vbrew.com $ |
系统将提示您输入密码,您应该使用远程帐户的密码(而不是本地帐户的密码)回答。当您键入密码时,密码不会回显。
在没有任何特殊参数的情况下,slogin 将尝试使用与本地机器上相同的用户 ID 登录。您可以使用-l参数覆盖此设置,并在远程主机上提供备用登录名。这就是我们在本书前面的示例中所做的。
我们可以使用 scp 程序将文件复制到远程主机和从远程主机复制文件。其语法类似于传统的 cp,但例外的是,您可以在文件名之前指定主机名,这意味着文件路径位于指定的主机上。以下示例通过复制名为/tmp/fred的本地文件到远程主机 chianti.vbrew.com 的/home/maggie/来说明 scp 语法
$ scp /tmp/fred vchianti.vbrew.com:/home/maggie/ maggie@vchianti.vbrew.com's password: fred 100% |*****************************| 50165 00:01 ETA |
同样,系统会提示您输入密码。scp 命令默认显示有用的进度消息。您可以同样轻松地从远程主机复制文件;只需将远程主机名和文件路径指定为源,并将本地路径指定为目标即可。甚至可以将文件从远程主机复制到其他远程主机,但这通常不是您想要做的事情,因为所有数据都通过您的主机传输。
您可以使用 ssh 命令在远程主机上执行命令。同样,其语法非常简单。让我们让我们的用户maggie检索远程主机 vchianti.vbrew.com 的根目录。她将使用以下命令执行此操作
$ ssh vchianti.vbrew.com ls -CF / maggie@vchianti.vbrew.com's password: bin/ console@ dos/ home/ lost+found/ pub@ tmp/ vmlinuz@ boot/ dev/ etc/ initrd/ mnt/ root/ usr/ vmlinuz.old@ cdrom/ disk/ floppy/ lib/ proc/ sbin/ var/ |
您可以将 ssh 放在命令管道中,并将程序输入/输出通过管道传输到或从管道传输,就像任何其他命令一样,只是输入或输出通过 ssh 连接定向到或从远程主机定向。以下是如何将此功能与 tar 命令结合使用,以将整个目录及其子目录和文件从远程主机复制到本地主机的示例
$ ssh vchianti.vbrew.com "tar cf - /etc/" | tar xvf - maggie@vchianti.vbrew.com's password: etc/GNUstep etc/Muttrc etc/Net etc/X11 etc/adduser.conf .. .. |
在这里,我们用引号将我们要执行的命令括起来,以明确传递给 ssh 的参数是什么,以及本地 shell 使用的是什么。此命令在远程主机上执行 tar 命令,以归档/etc/目录,并将输出写入标准输出。我们通过管道将其传输到本地主机上运行的 tar 命令实例,该实例以提取模式从标准输入读取。
同样,我们被提示输入密码。现在您可以看到为什么我们鼓励您配置 ssh,使其不会一直提示您输入密码!现在让我们配置本地 ssh 客户端,使其在连接到 vchianti.vbrew.com 主机时不会提示输入密码。我们之前提到了.ssh/authorized_keys文件;这就是它的用途。.ssh/authorized_keys文件包含我们希望自动登录的任何远程用户帐户的公钥。您可以通过将远程帐户中的.ssh/identity.pub的内容复制到本地.ssh/authorized_keys文件中来设置自动登录。至关重要的是,.ssh/authorized_keys的文件权限仅允许您读取和写入它;任何人都可以窃取和使用密钥登录到该远程帐户。为了确保权限正确,请更改.ssh/authorized_keys,如下所示
$ chmod 600 ~/.ssh/authorized_keys |
公钥是一长串单行纯文本。如果您使用复制和粘贴将密钥复制到本地文件中,请务必删除沿途可能引入的任何行尾字符。.ssh/authorized_keys文件可能包含许多此类密钥,每个密钥占一行。
ssh 工具套件非常强大,还有许多其他有用的功能和选项,您会有兴趣探索。有关更多信息,请参阅手册页和软件包随附的其他文档。
[1] | OpenSSH 由 OpenBSD 项目开发,是自由软件益处的一个很好的例子。 |