学习使用 SSH 是 Linux 系统管理员必备技能。本文涵盖基本的 SSH 配置、基于密码的身份验证以及一般安全设置。
译自 Linux: SSH and Key-Based Authentication,作者 Damon M Garn。
Secure Shell (SSH) 是 Linux 系统和网络设备的关键远程管理工具。它也是 macOS 访问的必要条件,通常会添加到 Windows 计算机中(或与 PowerShell 结合使用)。我将使用 OpenSSH 演示概念和配置。
SSH 的主要优势包括:
- 远程访问各种平台。
- 远程命令执行。
- 大多数 Linux 发行版默认安装。
- 强身份验证机制。
- 支持安全文件传输,例如 SCP 和 SFTP。
- 为其他不安全的应用程序提供隧道。
- 增强自动化和脚本编写。
学习利用 SSH 是 Linux 系统管理员的一项基本技能。本文介绍了基本的 SSH 配置、基于密码的身份验证和一般安全设置。它还展示了如何使用基于密钥的身份验证来改进 SSH 功能,以实现更好的远程管理和与自动化工具的集成。
SSH 通过加密身份验证和网络流量来帮助减轻窃听攻击。它是保护对服务器、路由器、交换机、物联网设备甚至云连接的管理连接的关键手段。
本文提供了用于管理远程 Linux 系统的命令。我建议在完成这些练习时使用 Linux 实验室环境。查看 了解 Linux 命令行 以更好地使用这些命令。
您可能已经知道连接到远程机器的基本 SSH 语法。使用
ssh
命令并定位特定的主机名或 IP 地址:
$ ssh server07
通过包含要进行身份验证的远程用户帐户的用户名来增强命令。例如,要使用远程用户 admin03 连接,请键入:
$ ssh admin03@server07
SSH 会提示您输入托管在远程系统上的用户帐户的密码。在大多数系统上,命令提示符将更改为显示远程计算机的主机名。
此时,您可以开始执行 Linux 命令并运行安装在远程设备上的任何程序,例如 Vim、Apache 或 MariaDB。请记住,您可能需要使用 sudo
在远程系统上提升您的权限。
完成远程管理任务后,键入 exit
或 logout
断开 SSH 会话。
使用远程 SSH 连接有很多示例,包括:
- 使用 Duplicity、Kopia、tar 或其他工具运行远程备份。
- 使用编译器或包管理器编译或安装应用程序。
- 修改 Web 和数据库服务的系统和应用程序配置文件。
- 重启服务。(请记住,如果您重启网络或防火墙服务,您将断开连接。)
但是,上述用例仅允许手动远程管理,管理员一次连接到一个系统并运行命令(或脚本)。这也意味着必须跟踪和维护密码,这在处理多个远程设备时可能很困难。
现代 SSH 实现提供了一种更强大的方法来证明您的身份,称为基于密钥的身份验证。实施基于密钥的身份验证最初简化了远程管理的身份验证,但它对于自动化功能尤其重要。
基于密钥的身份验证允许自动化工具在无需管理员输入密码(或将密码存储在配置文件中)的情况下对远程系统进行身份验证。我将在下面更详细地探讨这个想法。
基于密钥的身份验证是 SSH 身份验证的一项重大改进,它取代了密码身份验证。它依赖于非对称密钥加密。这种方法依赖于两个数学相关的密钥。每个密钥都扮演着特定的角色。密钥是:
- 公钥:此密钥可以跨网络传输到远程系统。任何使用公钥加密的数据只能使用相关的私钥解密。
- 私钥:此密钥安全地存储在本地设备上,绝不会跨网络传输。任何使用私钥加密的数据只能使用公钥解密。
您将在管理工作站(管理员的本地计算机)上生成一个公钥-私钥对,然后将公钥复制到一个或多个远程服务器。
在连接尝试期间,远程服务器使用管理员工作站的公钥加密一条消息挑战。此消息只能使用管理员工作站的私钥解密。如果工作站解密挑战并回复正确的信息,则远程服务器知道其身份已确认。
非对称密钥比标准密码更难猜测或暴力破解,这使得这种方法比可能基于可预测的单词或短语的密码更安全可靠。
实现基于密钥的 SSH 身份验证很简单。一般步骤是生成密钥对、将公钥复制到远程设备并测试连接。
以下是步骤说明:
- 使用
ssh-keygen
命令生成密钥对。它在当前用户的 home 目录中创建两个隐藏文件。文件是~/.ssh/id_rsa
(私钥)和~/.ssh/id_rsa.pub
(公钥)。您通常会按 Enter 键完成交互式提示。 - 使用
ssh-copy-id
命令将公钥复制到远程 SSH 设备,并指定用户。您必须在此步骤中输入密码,但这是您最后一次这样做。该实用程序还会提示您进行 yes 或 no 确认。公钥文件将驻留在远程主机上的~/.ssh/authorized_users
文件中。 - 通过键入
ssh admin03@server07
(替换您自己的凭据和主机名)来测试连接。远程系统不应向您索要密码。身份验证是静默的。
从现在开始,您将使用密钥对建立经过身份验证的远程连接。
以下列表总结了命令:
$ sudo ssh-keygen
$ sudo ssh-copy-id admin03@server07
$ sudo ssh admin03@server07
图 1:使用 ssh-keygen 命令生成公钥/私钥对。
当您生成密钥对时,您将有机会添加密码短语。您也可以在此处指定加密算法和密钥大小。大多数管理员会按 Enter 键完成这些提示,绕过额外的密码短语访问。
将客户端的公钥复制到远程服务器后,您在连接尝试期间将不再被要求输入密码。键入常规 SSH 连接命令,身份验证过程将静默成功。
基于密钥的身份验证的最初好处是简单性。您将不再被要求输入难以记住的密码。身份验证会静默进行。该过程更快,您可以立即开始您的管理任务。
当您使用 SSH 快速运行单个远程命令而无需手动干预时,这尤其方便,例如:
# ssh admin03@server07 'run-backup.sh'
毫无疑问,这种更快的身份验证很有帮助,但基于密钥的 SSH 身份验证的真正好处是在自动化介入时。
SSH 连接在现代 DevOps 和基础设施即代码 (IaC) 环境中仍然很重要。许多配置管理实用程序必须连接到远程系统以对软件进行清单、管理设置或启动软件测试。如果这些工具使用 SSH,它们仍然必须对远程系统进行身份验证。
早期的做法是暂停配置管理任务,直到管理员手动输入密码。显然,这种方法不会增强自动化。其他设计将密码或其他身份验证信息直接嵌入管理文件中,从而有可能意外地将这些信息暴露给任何可以访问这些文件的人(或这些文件的实例,例如备份中找到的那些)。
使用 SSH 的现代配置管理工具可以利用基于密钥的身份验证来建立远程连接,以实现完全的零接触解决方案。
以下是一些可以使用 SSH 连接的自动化配置管理工具:
- Ansible
- Chef
- Puppet
实现基于密钥的身份验证意味着可以在这些配置管理工具中定义远程连接,并且它们将在不暂停以手动输入密码的情况下运行。无需用户干预,这在配置管理任务在深夜或扩展事件期间运行时至关重要。
使用密钥进行身份验证的另一个好处是避免将密码嵌入到部署和配置文件中。这种有风险的做法很容易暴露管理员帐户的密码。
如果管理员工作站实际上需要连接到多个远程 SSH 服务器,该怎么办?您可以为每个服务器维护单独的密钥对,但这将非常繁琐。通过一些简单的配置文件编辑,您可以使用相同的密钥对来验证多个远程设备。这种方法甚至支持每个目标系统的不同连接选项。
在本地系统上配置基于密钥的身份验证以连接到多个目标服务器的步骤与上述步骤相同。但是,不要为每个连接生成新的密钥对。每次运行 ssh-keygen
命令都会覆盖现有的密钥对。您将使用相同的公钥和私钥进行所有连接。
该过程的前两个步骤是:
- 使用
ssh-keygen
命令在本地系统上生成密钥对。 - 使用
ssh-copy-id
命令将新的公钥复制到每个远程服务器。
在处理多服务器连接时,最重要的配置更改是编辑客户端的特定于用户的本地 SSH 配置文件。创建(或编辑)~/.ssh/config
文件。您有几种选择,包括:
- 主机名。
- 各种私钥的客户端身份文件。
- 备用端口号。
例如,您可以设置以下配置,使用名为 id_rsa
的单个私钥连接到各种远程系统:
Host server07
Hostname server07
User admin03
IdentityFile ~/.ssh/id_rsa
Host server09
Hostname server09
User admin03
IdentityFile ~/.ssh/id_rsa
最后,测试基于密钥的身份验证连接以确保它可以到达远程设备并确保设置正确。
SSH 包含各种其他选项来增强安全性并在您的环境中自定义其使用。主要的 SSH 服务器配置文件通常存储在 /etc/ssh/sshd_config
中。它包含许多条目。仔细查看注释和最佳实践。
以下是一些您可能考虑实施的标准安全配置。
- 设置 SSH 拒绝基于密码的身份验证: PasswordAuthentication no.
- 设置 SSH 拒绝跨网络直接 root 登录:PermitRootLogin no.
- 将默认 SSH 端口从 22 更改为非标准端口以控制连接。
- 设置横幅警告消息。
- 配置空闲时间以减少挂起连接。(请注意此设置与配置管理器,因为它可能难以预测它们需要连接多长时间。)
以 root(管理员)用户身份登录本地或远程 Linux 系统是一种不安全的做法。大多数系统强制您以普通用户身份登录,然后使用 sudo(超级用户执行)命令提升您的权限。使用 sudo
时,您可能会被提示输入密码。
上面提到的 PermitRootLogin no 配置是强制执行此操作的好方法。您将通过使用远程 SSH 目标上的非特权用户进行身份验证来建立连接,然后使用该框上的 sudo
提升您的权限。将此方法与基于密钥的身份验证相结合,可以更好地管理 SSH 安全性。
图2:自定义SSH服务器配置文件,以符合公司的安全策略。
请记住更新您的防火墙设置。如果 SSH 已预先安装并在您的 Linux 发行版中运行,则防火墙可能已为端口 22 打开。如果您必须添加它,请不要忘记更新防火墙规则以允许远程连接。
如果您只从单个管理员工作站或跳板机管理服务器,请将入站 SSH 连接限制为该设备的身份。这将阻止来自任何其他网络节点的 SSH 连接。
图 3:大多数发行版默认打开 22 端口。
定期审核远程 SSH 连接的日志文件,以识别任何未经授权的连接或重复的连接失败尝试。这些可能表明用户或恶意行为者试图访问远程服务器。
如果您使用 SSH 管理多个远程 Linux 服务器,请考虑使用 rsyslog 集中您的日志文件。这样做可以更轻松地查看 SSH 连接,帮助您验证只有授权连接发生。
Linux 和网络管理员依赖 SSH 来安全、便捷地访问远程系统。它是他们工具箱中必不可少的一部分。基于密码的身份验证适用于少数远程设备,但在使用大量目标服务器实现自动化时并不方便。
将 SSH 集成到更大的 CI/CD 和编排管道中,为远程连接提供了一个简单、安全的解决方案。SSH 与 Linux、macOS、Windows 和许多网络设备(路由器、交换机等)兼容,使其成为标准的管理实用程序。
从今天开始,审核您当前的 SSH 通信,然后实施基于密钥的身份验证并尽可能自动化配置。您可能会发现您的环境更加安全,更容易使用。