作者选择了 Electronic Frontier Foundation Inc作为 Write for Donations计划的一部分接受捐款。
介绍
Linux 服务器通常通过连接到 OpenSSH服务器进行远程管理,这是 Ubuntu、Debian、CentOS、FreeBSD 和大多数其他基于 Linux/BSD 的系统中使用的默认 SSH 服务器软件。
OpenSSH服务器是SSH的服务器侧面,也被称为SSH DAEMON或sshd
。您可以使用OpenSSH客户端连接到OpenSSH服务器,即ssh
命令。您可以了解更多关于SSH客户端服务器模型的信息,请参阅 SSH Essentials: Working with SSH Servers, Clients, and Keys。
在本教程中,您将通过使用不同的配置选项来硬化您的OpenSSH服务器,以确保远程访问您的服务器尽可能安全。
前提条件
要完成本教程,您将需要:
一个 Ubuntu 18.04 服务器是按照 Ubuntu 18.04 初始服务器设置设置的,包括一个 sudo 非 root 用户。
一旦你已经准备好了,登录你的服务器作为你的非根用户开始。
第1步:哈登将军
在这个第一步中,您将实施一些初始硬化配置,以提高您的SSH服务器的整体安全性。
最适合您自己的服务器的精确硬化配置取决于您自己的威胁模型和风险门槛(https://owasp.org/www-community/Application_Threat_Modeling)。
许多硬化配置的OpenSSH你实施使用标准的OpenSSH服务器配置文件,它位于 /etc/ssh/sshd_config
. 继续这个教程之前,建议你备份你的现有配置文件,这样你可以恢复它在不太可能的情况下,有什么不对劲。
使用以下命令备份文件:
1sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
这将保存文件的备份副本到 /etc/ssh/sshd_config.bak
。
在编辑配置文件之前,您可以查看当前设置的选项。
1sudo sshd -T
这将以扩展测试模式运行OpenSSH服务器,这将验证完整的配置文件并打印有效的配置值。
现在,您可以使用您最喜欢的文本编辑器打开配置文件,开始实施最初的硬化措施:
1sudo nano /etc/ssh/sshd_config
<$>[注] 注: OpenSSH 服务器配置文件包含许多默认选项和配置。
编辑配置文件时,某些选项可能默认使用一个单个哈希字符(#
)进行评论,以便编辑这些选项,或识别评论的选项,您需要通过删除哈希删除评论。
首先,通过设置以下选项来禁用通过 SSH 作为 root 用户的登录:
1[label sshd_config]
2PermitRootLogin no
这是非常有益的,因为它将防止潜在的攻击者直接登录作为根,它还鼓励良好的操作安全实践,例如作为非特权用户运作,并使用sudo
仅在绝对需要时升级特权。
接下来,您可以通过配置以下方式来限制特定登录会话的最大身份验证尝试次数:
1[label sshd_config]
2MaxAuthTries 3
对于大多数设置,标准值为3
是可接受的,但您可能希望根据自己的风险门槛设置更高或更低。
如果需要,您还可以设置一个缩短的登录恩典期,即用户在最初连接到 SSH 服务器后完成身份验证所需的时间:
1[label sshd_config]
2LoginGraceTime 20
配置文件在秒钟内指定此值。
将此值设置为更低的值有助于防止某些 服务拒绝攻击,其中多个身份验证会话被保持开放长时间。
如果您已配置 SSH 密钥用于身份验证,而不是使用密码,请禁用 SSH 密码身份验证以防止泄露的用户密码允许攻击者登录:
1[label sshd_config]
2PasswordAuthentication no
作为与密码相关的进一步硬化措施,您可能还希望禁用用空密码的身份验证,从而防止登录,如果用户的密码设置为空值或空值:
1[label sshd_config]
2PermitEmptyPasswords no
在大多数用例中,SSH 将以公钥身份验证为唯一使用的身份验证方法进行配置,但是,OpenSSH 服务器还支持许多其他身份验证方法,其中一些是默认启用的。
1[label sshd_config]
2ChallengeResponseAuthentication no
3KerberosAuthentication no
4GSSAPIAuthentication no
如果您想了解有关 SSH 内一些额外的身份验证方法的更多信息,您可以查看以下资源:
X11 转发允许通过 SSH 连接显示远程图形应用程序,但这在实践中很少使用。
1[label sshd_config]
2X11Forwarding no
OpenSSH服务器允许连接客户端通过自定义环境变量,即设置$PATH
或配置终端设置,但是,像X11转发一样,这些不常用,所以在大多数情况下可以禁用:
1[label sshd_config]
2PermitUserEnvironment no
如果您决定配置此选项,您还应该通过在行开始时添加一个哈希(#')来评论任何对
AcceptEnv`的引用。
接下来,您可以禁用几个与隧道和转发相关的不同选项,如果您不想在您的服务器上使用这些选项:
1[label sshd_config]
2AllowAgentForwarding no
3AllowTcpForwarding no
4PermitTunnel no
最后,您可以禁用默认启用的无语音SSH标签,因为它会显示有关您的系统的各种信息,例如操作系统版本:
1[label sshd_config]
2DebianBanner no
请注意,此选项很可能会不在配置文件中,因此您可能需要手动添加它。
现在通过在测试模式中运行sshd
来验证新配置的语法:
1sudo sshd -t
如果您的配置文件具有有效的语法,则不会有输出;如果出现语法错误,则会有描述问题的输出。
一旦您对配置文件满意,您可以重新加载sshd
以应用新的设置:
1sudo service sshd reload
在此步骤中,您完成了对 OpenSSH 服务器配置文件的一些一般硬化,接下来,您将实施一个 IP 地址允许列表,以进一步限制谁可以登录您的服务器。
步骤 2 – 实施 IP 地址授权列表
您可以使用 IP 地址允许列表来限制被授权登录您的服务器的用户,以每个 IP 地址为基础. 在此步骤中,您将为您的 OpenSSH 服务器配置 IP 允许列表。
在许多情况下,您只会从少数已知、可信的IP地址登录到您的服务器,例如,您的家庭互联网连接、企业VPN设备或数据中心中的静态(Jump box)(https://en.wikipedia.org/wiki/Jump_server)或(bastion host)(https://en.wikipedia.org/wiki/Bastion_host)。
通过实施 IP 地址允许列表,您可以确保人们只能从预先批准的 IP 地址中登录,从而大大减少在您的私钥和/或密码泄露的情况下遭到破坏的风险。
<$>[注] **注:**请注意确定正确的IP地址,以添加到您的允许列表,并确保这些不是保留的或动态地址,可能会定期变化,例如经常见到消费者互联网服务提供商
您可以通过使用w
命令来识别您目前连接到服务器的 IP 地址:
1w
这将产生类似于以下的东西:
1[secondary_label Output]
2 14:11:48 up 2 days, 12:25, 1 user, load average: 0.00, 0.00, 0.00
3 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
4your_username pts/0 203.0.113.1 12:24 1.00s 0.20s 0.00s w
在列表中查找您的用户帐户,并记住连接的 IP 地址. 在这里,我们使用203.0.113.1
的示例 IP。
要开始实施您的 IP 地址允许列表,请在您最喜欢的文本编辑器中打开 OpenSSH 服务器配置文件:
1sudo nano /etc/ssh/sshd_config
您可以使用允许用户
配置指令实现 IP 地址允许列表,该指令限制基于用户名和/或 IP 地址的用户身份验证。
您自己的系统设置和要求将确定哪个特定配置最合适,以下示例将帮助您确定最合适的配置:
- 限制所有用户到特定 IP 地址:
1AllowUsers *@203.0.113.1
- 将所有用户限制在特定 IP 地址范围内,使用 Classless Inter-Domain Routing (CIDR) 标注:
1AllowUsers *@203.0.113.0/24
- 限制所有用户到特定 IP 地址范围(使用 wildcards):
1AllowUsers *@203.0.113.*
- 限制所有用户使用多个特定 IP 地址和范围:
1AllowUsers *@203.0.113.1 *@203.0.113.2 *@192.0.2.0/24 *@172.16.*.1
- 禁用特定 IP 地址以外的所有用户:
1AllowUsers [email protected] [email protected]
限制特定用户到特定IP地址,同时继续允许所有其他用户无限制地登录:
1Match User ashley
2 AllowUsers [email protected]
<$>[警告]
**警告:**在OpenSSH配置文件中,在一个匹配
块下的所有配置只适用于符合标准的连接,而不论是插入或线路断裂,这意味着您必须小心,并确保旨在全球应用的配置不会意外放入一个匹配
块中。
一旦您完成了配置,请将其添加到您的OpenSSH服务器配置文件的底部:
1[label sshd_config]
2AllowUsers *@203.0.113.1
保存和关闭文件,然后继续测试配置语法:
1sudo sshd -t
如果没有报告错误,您可以重新加载OpenSSH服务器来应用您的配置:
1sudo service sshd reload
在此步骤中,您在您的 OpenSSH 服务器上实现了 IP 地址允许列表,接下来,您将限制用户的壳,以限制他们被允许使用的命令。
步骤 3 – 限制用户的壳
在此步骤中,您将查看限制 SSH 用户壳的各种选项。
除了提供远程 shell 访问之外,SSH 还适用于传输文件和其他数据,例如通过 SFTP. 但是,当用户只需要能够执行文件传输时,您可能并不总是希望向用户提供完整的 shell 访问权限。
在OpenSSH服务器中,您可以使用多种配置来限制特定用户的壳环境,例如,在本教程中,我们将使用这些配置来创建SFTP-only用户。
首先,您可以使用 /usr/sbin/nologin
壳来禁用某些用户帐户的交互式登录,同时允许非交互式会话(如文件传输、隧道等)发挥作用。
若要使用nologin
壳创建新用户,请使用以下命令:
1sudo adduser --shell /usr/sbin/nologin alex
或者,您可以将现有用户的壳更改为nologin
:
1sudo usermod --shell /usr/sbin/nologin sammy
如果您尝试互动地登录作为这些用户之一,请求将被拒绝:
1sudo su alex
这将产生类似于以下消息的东西:
1[secondary_label Output]
2This account is currently not available.
尽管在交互式登录上出现拒绝消息,但仍然允许其他操作,如文件转移。
接下来,您应该将nologin
壳的使用与一些额外的配置选项相结合,以进一步限制相关的用户帐户。
首先,在您最喜欢的文本编辑器中重新打开 OpenSSH 服务器配置文件:
1sudo nano /etc/ssh/sshd_config
有两种配置选项可以一起实现,以创建一个严格限制的SFTP仅的用户帐户:ForceCommand internal-sftp和ChrootDirectory。
OpenSSH服务器中的ForceCommand
选项强迫用户在登录时执行特定命令,这可能对某些机器到机器的通信有用,或者强制启动某个程序。
然而,在这种情况下,内部-sftp
命令特别有用,这是OpenSSH服务器的一个特殊功能,它启动了一个基本的现场SFTP示范,不需要任何支持系统文件或配置。
理想情况下,这应该与ChrootDirectory
选项相结合,该选项将对特定用户的感知根目录进行翻译/更改,基本上将其限制在系统上的特定目录上。
为此,将以下配置部分添加到您的 OpenSSH 服务器配置文件中:
1[label sshd_config]
2Match User alex
3 ForceCommand internal-sftp
4 ChrootDirectory /home/alex/
<$>[警告]
**警告:**正如步骤2中所指出的那样,在OpenSSH配置文件中,一个匹配
块下的所有配置只适用于符合标准的连接,而不论是间隔或线路断裂,这意味着你必须小心,并确保旨在全球应用的配置不会意外地放入一个匹配
块中。
保存并关闭配置文件,然后再次测试配置:
1sudo sshd -t
如果没有错误,您可以应用您的配置:
1sudo service sshd reload
这为alex
用户创建了一个强大的配置,在那里交互式登录被禁用,所有的SFTP活动都被限制在用户的主目录中。
您已经为用户实现了nologin
壳,然后创建了一个配置来限制 SFTP 访问到特定目录。
步骤4:先进硬化
在这个最后一步中,您将实施各种额外的硬化措施,以便尽可能安全地访问您的SSH服务器。
OpenSSH服务器的一个不太熟悉的特征是能够对每个密钥实施限制,即仅适用于.ssh/authorized_keys 文件中存在的特定公共密钥的限制,这对于控制机器对机器会话的访问特别有用,以及为非 sudo 用户提供控制他们自己的用户帐户的限制的能力。
您也可以在系统或用户层面应用大多数这些限制,但在密钥层面也可实现这些限制,以提供 [防御深度](https://en.wikipedia.org/wiki/Defense_in_depth_(computing)和额外的故障安全性,以便在系统范围内发生意外的配置错误。
<$>[注] 注: 如果您只使用密码身份验证,或者您有一个更复杂的设置,如SSH证书授权,不幸的是它们将无法使用
首先,在您最喜欢的文本编辑器中打开您的.ssh/authorized_keys 文件:
1nano ~/.ssh/authorized_keys
<$>[注]
**注:**由于这些配置适用于每一个密钥的基础上,你需要编辑每个单独的autorized_keys
文件中的每个单独的密钥,你希望它们适用于你的系统上的所有用户。
一旦你打开了authorized_keys
文件,你会看到每个行都包含一个SSH公共密钥,这很可能会从ssh-rsa AAAB...
开始。
以下限制选项可用:
无代理转发:禁用SSH代理转发
*无端转发:禁用SSH端口转发
*无代理转发:禁用分配tty功能(即启动壳)。
*无用户rc:防止执行 ~/.ssh/rc
文件
*无X11转发:禁用X11转发显示
例如,要禁用代理转发和X11转发的密钥,你会使用以下配置:
1[label ~/.ssh/authorized_keys]
2no-agent-forwarding,no-X11-forwarding ssh-rsa AAAB...
默认情况下,这些配置使用默认允许,例外封锁
方法工作;但是,也可以使用默认封锁,例外允许
,这通常是安全保障的优先选择。
您可以通过使用限制
选项来做到这一点,该选项将暗示地拒绝特定密钥的所有SSH功能,要求它们只在绝对需要时被明确重新启用。
例如,要禁用特定密钥的所有 SSH 功能,除了 X11 显示转发,您可以使用以下配置:
1[label ~/.ssh/authorized_keys]
2restrict,X11-forwarding ssh-rsa AAAB...
您可能还想考虑使用命令
选项,这与步骤 3 中描述的ForceCommand
选项非常相似,如果您已经使用了ForceCommand
,这不会带来直接的好处,但在不太可能的情况下,您的主要OpenSSH服务器配置文件被重写,编辑等情况下,它是良好的防御深度。
例如,要强迫用户在登录时对特定密钥进行身份验证,您可以添加以下配置:
1[label ~/.ssh/authorized_keys]
2command="top" ssh-rsa AAAB...
<$>[警告]
警告:命令
配置选项纯粹是防御的深度方法,不应该仅依赖于限制SSH用户的活动,因为根据您的环境可能有方法来过度或绕过它。
最后,为了更好地利用您在步骤 3 中创建的 SFTP 用户的每键限制,您可以使用以下配置:
1[label ~/.ssh/authorized_keys]
2restrict,command="false" ssh-rsa AAAB...
限制
选项将禁用所有交互式访问,并且在ForceCommand
选项或nologin
壳失败的情况下,command="false
选项作为第二道防线。
保存并关闭文件以应用配置. 这将立即适用于所有新登录,因此您不需要手动重新加载OpenSSH。
在这个最后一步中,您通过在您的 .ssh/authorized_keys
文件中使用自定义选项来为 OpenSSH 服务器实施了一些额外的先进硬化措施。
结论
在本文中,您审查了您的OpenSSH服务器配置,并实施了各种硬化措施,以帮助保护您的服务器。
这将通过禁用未使用的功能和锁定特定用户的访问来减少您的服务器的整体攻击表面。
您可能希望查看 手动页面为 OpenSSH 服务器和相关的 配置文件,以确定您想要做的任何潜在的进一步调整。