如何在Ubuntu18.04上强化OpenSSH
作者选择了 Electronic Frontier Foundation Inc 作为 Write for DOnations 计划的一部分来接受捐赠。
介绍
Linux 服务器通常通过连接到 OpenSSH 服务器使用 SSH 进行远程管理,这是 Ubuntu、Debian、CentOS、FreeBSD 和大多数其他基于 Linux/BSD 的系统中使用的默认 SSH 服务器软件。
OpenSSH 服务器是 SSH 的服务器端,也称为 SSH daemon 或 sshd
。 您可以使用 OpenSSH 客户端 - ssh
命令连接到 OpenSSH 服务器。 您可以在 SSH Essentials: Working with SSH Servers, Clients, and Keys 中了解有关 SSH 客户端-服务器模型的更多信息。 正确保护您的 OpenSSH 服务器非常重要,因为它充当您服务器的前门或入口。
在本教程中,您将通过使用不同的配置选项来强化您的 OpenSSH 服务器,以确保对服务器的远程访问尽可能安全。
先决条件
要完成本教程,您需要:
- 按照 Initial Server Setup 和 Ubuntu 18.04 设置的 Ubuntu 18.04 服务器,包括 sudo 非 root 用户。
准备就绪后,以非 root 用户身份登录到您的服务器即可开始。
第 1 步——一般硬化
在这第一步中,您将实施一些初始强化配置以提高 SSH 服务器的整体安全性。
最适合您自己的服务器的确切加固配置在很大程度上取决于您自己的威胁模型和风险阈值。 但是,您将在此步骤中使用的配置是适合大多数服务器的通用安全配置。
您使用位于 /etc/ssh/sshd_config
的标准 OpenSSH 服务器配置文件来实现 OpenSSH 的许多强化配置。 在继续本教程之前,建议对现有配置文件进行备份,以便在出现问题时可以恢复它。
使用以下命令备份文件:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
这会将文件的备份副本保存到 /etc/ssh/sshd_config.bak
。
在编辑配置文件之前,您可以查看当前设置的选项。 为此,请运行以下命令:
sudo sshd -T
这将以扩展测试模式运行 OpenSSH 服务器,这将验证完整的配置文件并打印出有效的配置值。
您现在可以使用您喜欢的文本编辑器打开配置文件以开始实施初始强化措施:
sudo nano /etc/ssh/sshd_config
注意: OpenSSH 服务器配置文件包括许多默认选项和配置。 根据您现有的服务器配置,可能已经设置了一些推荐的强化选项。
编辑配置文件时,默认情况下,某些选项可能会在行首使用单个哈希字符 (#
) 注释掉。 为了编辑这些选项,或者让注释选项被识别,您需要通过删除哈希来取消注释它们。
首先,通过设置以下选项禁用以 root 用户身份通过 SSH 登录:
sshd_config
PermitRootLogin no
这是非常有益的,因为它可以防止潜在的攻击者直接以 root 身份登录。 它还鼓励良好的操作安全实践,例如以非特权用户身份操作并仅在绝对需要时使用 sudo
来提升权限。
接下来,您可以通过配置以下内容来限制特定登录会话的最大身份验证尝试次数:
sshd_config
MaxAuthTries 3
对于大多数设置,标准值 3
是可以接受的,但您可能希望根据自己的风险阈值将其设置得更高或更低。
如果需要,您还可以设置缩短的登录宽限期,这是用户在最初连接到您的 SSH 服务器后必须完成身份验证的时间:
sshd_config
LoginGraceTime 20
配置文件以秒为单位指定此值。
将此值设置为较低的值有助于防止某些 拒绝服务攻击 ,其中多个身份验证会话长时间保持打开状态。
如果您已配置 SSH 密钥进行身份验证,而不是使用密码,请禁用 SSH 密码身份验证以防止泄露的用户密码允许攻击者登录:
sshd_config
PasswordAuthentication no
作为与密码相关的进一步强化措施,您可能还希望禁用使用空密码的身份验证。 如果用户的密码设置为空白或空值,这将阻止登录:
sshd_config
PermitEmptyPasswords no
在大多数用例中,SSH 将配置为使用公钥身份验证作为唯一使用中的身份验证方法。 但是,OpenSSH 服务器还支持许多其他的身份验证方法,其中一些是默认启用的。 如果不需要这些,您可以禁用它们以进一步减少 SSH 服务器的攻击面:
sshd_config
ChallengeResponseAuthentication no KerberosAuthentication no GSSAPIAuthentication no
如果您想了解更多关于 SSH 中可用的一些其他身份验证方法的信息,您可能希望查看这些资源:
X11 转发允许通过 SSH 连接显示远程图形应用程序,但这在实践中很少使用。 如果您的服务器不需要它,建议禁用它:
sshd_config
X11Forwarding no
OpenSSH 服务器允许连接客户端传递自定义环境变量,即设置 $PATH
或配置终端设置。 但是,与 X11 转发一样,这些并不常用,因此在大多数情况下可以禁用:
sshd_config
PermitUserEnvironment no
如果您决定配置此选项,还应确保通过在行首添加哈希 (#
) 来注释掉对 AcceptEnv
的任何引用。
接下来,如果您不会在服务器上使用这些选项,则可以禁用与隧道和转发相关的几个杂项选项:
sshd_config
AllowAgentForwarding no AllowTcpForwarding no PermitTunnel no
最后,您可以禁用默认启用的详细 SSH 横幅,因为它显示有关您的系统的各种信息,例如操作系统版本:
sshd_config
DebianBanner no
请注意,此选项很可能不会出现在配置文件中,因此您可能需要手动添加它。 完成后保存并退出文件。
现在通过在测试模式下运行 sshd
来验证新配置的语法:
sudo sshd -t
如果您的配置文件具有有效的语法,则不会有输出。 如果出现语法错误,将会有一个描述问题的输出。
对配置文件满意后,可以重新加载 sshd
以应用新设置:
sudo service sshd reload
在这一步中,您完成了对 OpenSSH 服务器配置文件的一些常规强化。 接下来,您将实施 IP 地址许可名单以进一步限制谁可以登录您的服务器。
第 2 步 — 实施 IP 地址白名单
您可以使用 IP 地址允许列表来限制有权基于每个 IP 地址登录到您的服务器的用户。 在此步骤中,您将为 OpenSSH 服务器配置 IP 许可名单。
在许多情况下,您只会从少数已知的、受信任的 IP 地址登录到您的服务器。 例如,您的家庭互联网连接、企业 VPN 设备或数据中心中的静态 跳转框 或 堡垒主机 。
通过实施 IP 地址白名单,您可以确保人们只能从预先批准的 IP 地址之一登录,从而大大降低了您的私钥和/或密码泄露时的违规风险。
注意: 请注意识别正确的 IP 地址以添加到您的许可名单中,并确保这些地址不是可能会定期更改的浮动或动态地址,例如消费者互联网服务提供商经常看到的情况。
您可以使用 w
命令识别当前连接到服务器的 IP 地址:
w
这将输出类似于以下内容:
Output 14:11:48 up 2 days, 12:25, 1 user, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT your_username pts/0 203.0.113.1 12:24 1.00s 0.20s 0.00s w
在列表中找到您的用户帐户并记下连接的 IP 地址。 这里我们使用203.0.113.1
的示例IP
为了开始实施您的 IP 地址许可名单,请在您喜欢的文本编辑器中打开 OpenSSH 服务器配置文件:
sudo nano /etc/ssh/sshd_config
您可以使用 AllowUsers
配置指令实现 IP 地址允许列表,该指令根据用户名和/或 IP 地址限制用户身份验证。
您自己的系统设置和要求将确定最合适的特定配置。 以下示例将帮助您确定最合适的示例:
- 将所有用户限制为特定 IP 地址:
AllowUsers *@203.0.113.1
- 使用 Classless Inter-Domain Routing (CIDR) notation 将所有用户限制在特定 IP 地址范围内:
AllowUsers *@203.0.113.0/24
- 将所有用户限制在特定的 IP 地址范围内(使用通配符):
AllowUsers *@203.0.113.*
- 将所有用户限制为多个特定 IP 地址和范围:
AllowUsers *@203.0.113.1 *@203.0.113.2 *@192.0.2.0/24 *@172.16.*.1
- 禁止除来自特定 IP 地址的命名用户之外的所有用户:
AllowUsers sammy@203.0.113.1 alex@203.0.113.2
- 将特定用户限制为特定 IP 地址,同时继续允许所有其他用户不受限制地登录:
Match User ashley AllowUsers ashley@203.0.113.1
警告: 在 OpenSSH 配置文件中,Match
块下的所有配置将仅适用于符合条件的连接,而不管缩进或换行。 这意味着您必须小心并确保旨在全局应用的配置不会意外放入 Match
块中。 建议将所有 Match
块放在配置文件的底部/末尾,以帮助避免这种情况。
完成配置后,将其添加到 OpenSSH 服务器配置文件的底部:
sshd_config
AllowUsers *@203.0.113.1
保存并关闭文件,然后继续测试您的配置语法:
sudo sshd -t
如果没有报告错误,您可以重新加载 OpenSSH 服务器以应用您的配置:
sudo service sshd reload
在此步骤中,您在 OpenSSH 服务器上实施了 IP 地址许可名单。 接下来,您将限制用户的 shell 以限制他们被允许使用的命令。
第 3 步 — 限制用户的 shell
在此步骤中,您将了解用于限制 SSH 用户的 shell 的各种选项。
除了提供远程 shell 访问之外,SSH 还非常适合传输文件和其他数据,例如通过 SFTP。 但是,当用户只需要能够执行文件传输时,您可能并不总是希望向他们授予完整的 shell 访问权限。
OpenSSH 服务器中有多种配置可用于限制特定用户的 shell 环境。 例如,在本教程中,我们将使用这些来创建仅限 SFTP 的用户。
首先,您可以使用 /usr/sbin/nologin
shell 禁用某些用户帐户的交互式登录,同时仍允许非交互式会话运行,例如文件传输、隧道等。
要使用 nologin
shell 创建新用户,请使用以下命令:
sudo adduser --shell /usr/sbin/nologin alex
或者,您可以将现有用户的 shell 更改为 nologin
:
sudo usermod --shell /usr/sbin/nologin sammy
如果您随后尝试以这些用户之一的身份进行交互登录,该请求将被拒绝:
sudo su alex
这将输出类似于以下消息的内容:
OutputThis account is currently not available.
尽管交互式登录出现拒绝消息,但仍将允许其他操作,例如文件传输。
接下来,您应该将 nologin
shell 的使用与一些额外的配置选项结合起来,以进一步限制相关的用户帐户。
首先再次在您喜欢的文本编辑器中打开 OpenSSH 服务器配置文件:
sudo nano /etc/ssh/sshd_config
您可以一起实施两个配置选项来创建严格限制的仅限 SFTP 的用户帐户:ForceCommand internal-sftp
和 ChrootDirectory
。
OpenSSH 服务器中的 ForceCommand
选项强制用户在登录时执行特定命令。 这对于某些机器对机器通信或强制启动特定程序可能很有用。
但是,在这种情况下,internal-sftp
命令特别有用。 这是 OpenSSH 服务器的一个特殊功能,它启动一个基本的就地 SFTP 守护程序,不需要任何支持系统文件或配置。
理想情况下,这应该与 ChrootDirectory
选项结合使用,该选项将覆盖/更改特定用户的感知根目录,本质上将它们限制在系统上的特定目录中。
为此,将以下配置部分添加到您的 OpenSSH 服务器配置文件中:
sshd_config
Match User alex ForceCommand internal-sftp ChrootDirectory /home/alex/
警告: 如步骤 2 中所述,在 OpenSSH 配置文件中,Match
块下的所有配置将仅适用于符合条件的连接,而不管缩进或换行。 这意味着您必须小心并确保旨在全局应用的配置不会意外放入 Match
块中。 建议将所有 Match
块放在配置文件的底部/末尾,以帮助避免这种情况。
保存并关闭您的配置文件,然后再次测试您的配置:
sudo sshd -t
如果没有错误,您可以应用您的配置:
sudo service sshd reload
这为 alex
用户创建了一个健壮的配置,其中禁用了交互式登录,并且所有 SFTP 活动都限制在用户的主目录中。 从用户的角度来看,系统的根目录,即/
,是他们的主目录,他们将无法向上遍历文件系统访问其他区域。
您已经为用户实现了 nologin
shell,然后创建了一个配置来限制对特定目录的 SFTP 访问。
第 4 步 — 高级硬化
在这最后一步中,您将实施各种额外的强化措施,以尽可能安全地访问您的 SSH 服务器。
OpenSSH 服务器的一个鲜为人知的特性是能够对每个密钥施加限制,即仅适用于 .ssh/authorized_keys
文件中存在的特定公钥的限制。 这对于控制机器对机器会话的访问以及为非 sudo 用户提供控制他们自己用户帐户的限制的能力特别有用。
您也可以在系统或用户级别应用大多数这些限制,但是在密钥级别实现它们仍然是有利的,以提供 深度防御 和额外的故障保护意外的系统范围配置错误的事件。
注意: 如果您使用 SSH 公钥认证,您只能实施这些额外的安全配置。 如果您只使用密码身份验证,或者有更复杂的设置,例如 SSH 证书颁发机构,那么很遗憾,这些将无法使用。
首先在您喜欢的文本编辑器中打开 .ssh/authorized_keys
文件:
nano ~/.ssh/authorized_keys
注意: 由于这些配置适用于每个密钥,因此您需要在每个单独的 authorized_keys
文件中编辑每个单独的密钥,您希望它们适用于所有用户你的系统。 通常您只需要编辑一个密钥/文件,但如果您有一个复杂的多用户系统,这值得考虑。
打开 authorized_keys
文件后,您会看到每一行都包含一个 SSH 公钥,它很可能以 ssh-rsa AAAB...
之类的开头。 可以将其他配置选项添加到该行的开头,这些选项仅适用于针对该特定公钥的成功身份验证。
可以使用以下限制选项:
no-agent-forwarding
:禁用 SSH 代理转发。no-port-forwarding
:禁用 SSH 端口转发。no-pty
:禁用分配tty的能力(即 启动一个外壳)。no-user-rc
:阻止执行~/.ssh/rc
文件。no-X11-forwarding
:禁用 X11 显示转发。
您可以应用这些来禁用特定密钥的特定 SSH 功能。 例如,要禁用密钥的代理转发和 X11 转发,您将使用以下配置:
~/.ssh/authorized_keys
no-agent-forwarding,no-X11-forwarding ssh-rsa AAAB...
默认情况下,这些配置使用“默认允许,异常阻止”方法工作; 但是,也可以使用“默认阻止,例外允许”,这通常更适合确保安全性。
您可以使用 restrict
选项来执行此操作,该选项将隐式拒绝特定密钥的所有 SSH 功能,要求仅在绝对需要时才显式重新启用它们。 您可以使用本教程前面描述的相同配置选项重新启用功能,但不使用 no-
前缀。
例如,要禁用特定密钥的所有 SSH 功能,除了 X11 显示转发,您可以使用以下配置:
~/.ssh/authorized_keys
restrict,X11-forwarding ssh-rsa AAAB...
您可能还希望考虑使用 command
选项,它与步骤 3 中描述的 ForceCommand
选项非常相似。 如果您已经在使用 ForceCommand
,这不会提供直接的好处,但是将它放在适当的位置是很好的纵深防御,以防万一您的主要 OpenSSH 服务器配置文件被覆盖,编辑,等等。
例如,要强制用户针对特定密钥进行身份验证以在登录时执行特定命令,您可以添加以下配置:
~/.ssh/authorized_keys
command="top" ssh-rsa AAAB...
警告: command
配置选项纯粹作为一种纵深防御方法,不应仅仅依赖于限制 SSH 用户的活动,因为有潜在的方法可以根据您的环境覆盖或绕过它。 相反,您应该将配置与本文中描述的其他控件结合使用。
最后,为了最好地使用您在步骤 3 中创建的仅限 SFTP 用户的每键限制,您可以使用以下配置:
~/.ssh/authorized_keys
restrict,command="false" ssh-rsa AAAB...
restrict
选项将禁用所有交互式访问,并且 command="false"
选项充当第二道防线,以防 ForceCommand
选项或 nologin
shell失败了。
保存并关闭文件以应用配置。 这将对所有新登录立即生效,因此您无需手动重新加载 OpenSSH。
在这最后一步中,您通过使用 .ssh/authorized_keys
文件中的自定义选项为 OpenSSH 服务器实施了一些额外的高级强化措施。
结论
在本文中,您查看了 OpenSSH 服务器配置并实施了各种强化措施来帮助保护您的服务器。
这将通过禁用未使用的功能并锁定特定用户的访问来减少服务器的整体攻击面。