恶魔寻觅守护进程—强化 OpenSSH 配置的实用方法

作者:Phil Moses

如果您是 Linux 机器的所有者或管理员,那么您很可能不时地远程访问它,如果不是经常访问的话。无论是家中的工作站、托管服务器还是业余爱好机器,如果您正在远程访问 Linux,那么您很有可能在远程机器上使用 OpenSSH 服务器,并在本地使用某种类型的 SSH 客户端。(如果您没有这样做,您可能应该这样做。)虽然 OpenSSH 服务器和客户端在加密系统之间传输的流量方面做得非常出色,但任何监听连接的守护进程也确实是一扇等待黑客、作恶者或破解者转动的门把手。在这些情况下,不太受欢迎的人,正如标题所说,是寻觅守护进程的恶魔,这些人或团体通常居心不良,寻找监听守护进程,而这些守护进程的安全性可能取决于机器的配置。黑客可以被定义为出于相对良性的动机而侵入系统的人。破解者通常被认为是怀有恶意意图的黑客。无论前者还是后者都不欢迎在我的机器上出现。在本文中,我将扩展基本的 OpenSSH 配置,并介绍改进 SSH 守护进程安全性的方法,以便为您的机器提供更多保护。如果您的机器遭受入侵,您的机器也可能帮助将您的不快传播给其他人。互联网是我们星球上最大的不安全数据路由之一。

OpenSSH 提供了通过不安全通道进行安全通信的手段。sshd_config 文件是安全 shell 配置游戏中的统治者。sshd_config 文件包含多个选项,可以更改这些选项以帮助提高监听守护进程的安全性。尽管远程访问工具似乎应该开箱即用就很安全,但事实并非如此。在大多数情况下,OpenSSH 服务器的默认安装将为您提供相对安全的默认配置,但机器管理员可以对其进行大幅改进。

在最初规划远程访问时,建议您考虑以下三个主要事项来访问您的机器

  1. 谁将被允许访问这些机器?

  2. 将如何提供这种访问?

  3. 将从哪里允许这种访问?

我们将假设我们将使用 OpenSSH 服务器来提供远程访问。这就给我们留下了谁将被允许远程访问以及将从哪里允许访问的问题。对于某些人来说,这可能很简单;也许该机器仅支持单个用户,并且远程访问是从单个域执行的。对于另一些人来说,当多个经常出差的用户是机器的用户时,这可能是一个相当大的挑战。

谁在这次邪恶派对的邀请名单上?

Linux 机器上的首要人物是 root 用户。这是众所周知的,而且也应该众所周知的是,如果您需要对机器进行远程 root 访问,那么有许多比简单地使用 SSH 并以 root 身份登录更好的 root 访问方法。如果您考虑一下暴力破解攻击尝试的基本原理,那么很明显,最相关的将被攻击的帐户是 root 帐户。无需猜测该帐户是否存在;它就在那里。sshd_config 文件允许我们通过 PermitRootLogin 指令指定根本不允许 root 用户远程登录。

我完全相信,在处理远程使用帐户时,“一盎司的预防胜过一磅的治疗”这句谚语非常准确。sshd_config 文件中允许的两个选项 UsersAllow 和 UsersDeny,不仅仅是一盎司的预防,虽然在添加帐户时可能需要额外的步骤,但为每个添加的帐户修改 UsersAllow 提供了您可能(谢天谢地)永远不需要寻求的一磅治疗。为了扩展 UsersAllow 指令,您不仅可以指定特定的用户,还可以指定特定主机上的特定用户。因此,如果您事先确切知道谁需要登录以及从哪里登录,那么将这些指令添加到 sshd_config 文件所花费的最少时间开销可以让您安心地知道您只允许特定帐户从特定机器进行远程访问。有效用户可以从独立机器中的 /etc/passwd 文件或 NIS 或 LDAP 环境中的相应文件中检索。清单 1 是一个解析上个月安全文件以验证哪些帐户已使用 SSH 成功登录的示例。

清单 1. 解析日志以查找成功登录

cat secure* | grep Accepted | awk -F' ' '\
{print $1" "$2" "$9}' | uniq -u
Aug 30 juser
Aug 22 kuser
Aug 23 user
Aug 15 foo

...
Aug 24 13:23:19 foohost sshd[16348]: Accepted
password for phil from 127.0.0.1 port 47338 ssh2
Aug 24 13:23:25 foohost sshd[16398]: User root
not allowed because not listed in AllowUsers
监控那些恶魔并将其控制在适当的位置

密切关注寻觅守护进程的恶魔相对容易,并且应在配置文件中确认(预期的)默认设置。将 SyslogFacility 设置为 AUTH 后,您的 sshd 将(通过 syslog)记录到(路径和文件名可能因发行版而异)/var/log/messages 和 /var/log/secure。强烈建议使用 Psionic 的 logwatch 等程序来监控您的系统日志。Logwatch 将负责解析日志,您将能够解读 sshd 授权登录以及失败。无效用户和身份验证失败之间存在明显的区别。身份验证失败是指在机器上存在的帐户上发生的失败,而无效用户则正是如此。当您选择帐户名以及考虑谁将在 AllowUser 和 DenyUser 列表中时,这可能会变得相对重要。例如,您可能没有一个名为 amanda 的实际人员使用您的机器,但您正在使用 amanda 开源备份程序。如果此帐户未添加到 DenyUser 规范中,则会触发身份验证失败,而不是无效用户标志。虽然不一定需要,但我还是将活动的系统帐户添加到 DenyUsers 列表中,以确保安全。来自 sshd 扫描的最新日志条目显示,系统帐户实际上已添加到探测列表中(清单 2 和 3)。

清单 2. 由于帐户未在 sshd_config AllowUsers 中获得授权而导致的失败的日志条目

User mail not allowed because not listed in
AllowUsers
User adm not allowed because not listed in
AllowUsers

清单 3. 来自无效帐户的日志条目

Aug 28 06:04:15 foo sshd[11602]: Failed password
for illegal user a... from 10.0.0.1 port 35078 ssh2
Aug 28 06:04:17 foo sshd[11604]: Illegal user aaa
from 10.0.0.1
Aug 28 06:04:19 foo sshd[11604]: Failed password
for illegal user aaa from 10.0.0.1 port 35417 ssh2
Aug 28 06:04:21 foo sshd[11606]: Illegal user qqq
from 10.0.0.1

由于已经提到了用户名,现在适合讨论恶魔(作恶者)拥有登录所需的两个凭据之一的可能性。在托管个人帐户的 Web 服务器或电子邮件标头中,相对容易确定特定机器上的用户名。有了这个,恶魔就拥有了用户名/密码组合的一半,如果扫描器不仅仅是扫描常用帐户和密码,那么很容易将 sshd 扫描更进一步,并开始对那些已被确定存在于机器上的帐户进行暴力破解尝试。

无需重新发明协议,只需要改进当前配置。OpenSSH 为联网机器提供了一种强大的端到端加密方法。不断发布代码更新以解决可能出现的任何不安全性。最相关的版本之一是从 SSH v1 更改为 SSH v2。版本 1 和版本 2 sshd 服务器都有自己的密钥。换句话说,对于 SSH1 和 SSH2,私钥和公钥都不会混合。这些密钥彼此独立。正如密钥彼此独立一样,协议也是如此,并且可以通过配置中的 Protocol 指令来允许协议 1、协议 2 或两者都允许。SSH1 已被弃用,但在许多组织和应用程序中仍在使用。建议您检查您的 sshd_config 文件,如果您不依赖 SSH1,请禁用此协议,并且仅在您的服务器上运行协议 2。这消除了因版本 1 相关的任何不安全性而受害的任何机会。

早些时候,当您浏览密码文件以构建用户列表时,您可能注意到有一个 sshd 用户,其主目录为 /var/empty,名称列为 Privilege-separated SSH。如果此用户不存在,则以下内容尤为重要,您将需要进一步研究以特权分离模式运行 sshd。sshd 中的特权分离是一个多部分过程,需要 sshd 进程创建一个特权监视器进程,该进程创建一个具有用户特权的 sshd 进程。这个用户拥有的进程反过来又会产生 shell 进程。特权分离过程通过 chroot 运行,并限制在 /var/empty 目录中。对于那些熟悉在 chroot 环境中运行进程的人来说,这种特权分离是相同的。如果发现缓冲区溢出或类似的入侵,它可以保护监听守护进程。/var/empty 目录应由 root 拥有,为空,并且不应是世界或组可写的。如果 sshd 用户不存在,则特权分离将不起作用,并且必须禁用缺少 mmap 或匿名内存映射压缩的系统。

考虑这样一种情况,即一台机器只有少量用户通过 SSH 访问它。很可能,您拥有的机器仅由几个帐户访问,然后 su 或 sudo 用于管理目的。还要考虑经常运行的脚本,这些脚本旨在寻找正在运行 SSH 服务器的机器。尽管脚本可能会执行全系统端口扫描以加快扫描速度并识别可能的受害者,但通常只扫描特定端口(sshd 情况下的端口 22),如果发现端口打开,则会对其进行扩展。对此的逻辑替代方案,尤其是在只有少量用户登录的机器中,是在备用端口上运行 sshd。具体来说,在 sshd_config 文件中,最先出现的选项之一是端口。通过将端口从 22 更改为备用端口,您可以忽略大量扫描开放端口 22 的脚本。这是一个非常简单的配置更改,但它将大大减少暴力破解尝试(清单 4)。

清单 4. 更改端口

# The strategy used for options in the default
# sshd_config shipped with
# OpenSSH is to specify options with their
# default value where
# possible, but leave them commented.
# Uncommented options change a default value

Port 13
Protocol 2

即使是地球上打字最慢的打字员,允许他们输入密码的预期时间是多少?假设密码为八个字符,是八秒钟吗?给他们每个字符两秒钟,他们就有充足的 16 秒钟。允许他们 20 秒的网络延迟,我们刚刚超过 30 秒,这似乎是一个非常慷慨的宽限时间。但这通常会被默认的 sshd 配置所超越,尽管 LoginGraceTime 有时设置为高达 120 秒。这是服务器允许成功登录的最长时间。问问自己,如果有人敲你家的门,而你在门后,决定是否让这个人或这些人进来的最长时间是多少?与此相关的是,我们有另一个独特的登录指令,名为 MaxStartups。当对抗 SSH 扫描器时,MaxStartups 指令可能是一个非常强大的威慑。MaxStartups 指定了与 SSH 守护进程的最大并发未经验证的连接数。请注意,这意味着未经验证的连接。因此,如果一个脚本正在运行,试图暴力破解进入机器,并且该脚本能够派生进程,那么它可能会几乎同时启动多个(甚至数百个)登录尝试。一个好的经验法则是使用您的远程用户总数的三分之一,最大设置为 10。

启动更改

实施上述更改几乎没什么需要考虑的。默认配置仅仅是一个指南,管理员有责任扩展该指南并强化 sshd 配置。在进行更改之前,强烈建议您暂时在备用端口上启动 sshd,以便在您错误配置主 sshd 并丢失连接时为自己提供后门。当在 sshd 上发出重启命令时,可能会在配置文件中犯错误,这将导致守护进程无法重启(如果它首先被停止)。执行ssh -p <备用端口>将允许第二个守护进程运行,并在第一个守护进程因配置错误而失败时为您提供第二个安全连接。毕竟,我们正在远程工作,如果我们丢失了 SSH 守护进程而没有备用,则需要物理访问控制台才能进行进一步修改。即使这看起来很明显,但值得一提的是,您必须发出 SIGHUP 或重启 SSH 守护进程才能使任何更改生效。为了进一步扩展打开第二个端口的想法,可以为第二个 sshd 添加一个启动脚本,该脚本使用备用的 sshd_config 文件运行,该文件除了来自单个来源的单个用户帐户外,没有指定其他选项。这实际上允许您保证自己从(假定的)安全机器访问,如果初始守护进程被关闭。

总结追逐

对于 Linux 系统管理员来说,实际上是您或一群人与全世界对抗。您在一端,提供对您的机器的访问,而在另一端是一个由网络连接的人组成的世界,他们中的许多人希望访问您的机器。通常,用于利用 SSH 守护进程的工具是根据默认配置构建的。低垂的果实通常是目标,而您的工作是了解您的本地环境和需求,以便在它被其他人摘走之前移除低垂的果实。一台被入侵的机器不仅会在您的环境中造成混乱,还会给全球连接的其他数百万或数十亿台计算机带来风险。OpenSSH 为远程访问提供了一个出色的工具。将该工具与活动扳手进行比较是一个公平的分析。扳手和 OpenSSH 都具有广泛的功能。正如您需要调整活动扳手以充分利用它一样,调整 OpenSSH 的默认配置将最大限度地提高您的远程访问能力,同时还提供更安全的环境。

Phil Moses 的日常工作是在斯克里普斯海洋研究所物理海洋学研究部管理 Linux 系统,他的业余时间则思考如何访问世界上那些人迹罕至的偏远地区。可以通过 philmoses@cox.net 联系 Phil。

加载 Disqus 评论