Paranoid Penguin:Linux 安全的风险方法
自从我四年前开始撰写这个专栏以来,Linux 软件漏洞和威胁的本质并没有发生太大变化。缓冲区溢出、错误的配置(包括文件权限)和不充分的输入验证仍然是 Linux 漏洞的主要部分。如果同样的漏洞不断出现,那么整个补丁竞赛是徒劳的吗?或者,我们是否可以采取更广泛的方法来应对 Linux 安全?
本月,我将从基于风险的角度讨论 Linux 安全,并说明如何通过使用基于风险的方法,我们不仅可以缓解我们已知的 Linux 漏洞,还可以缓解那些尚未被发现或公开的漏洞。
您可能想知道,我所说的基于风险的方法是什么意思?难道所有的信息安全不都是关于风险的吗?的确如此,但这个术语实际上是基于风险管理的方法的简称。
处理给定的信息安全风险只有几种方法。我们可以通过不进行任何使我们暴露于该风险的事情来避免它。我们可以通过解决其根本原因来消除它(实际上,这很少在我们控制范围内)。我们可以缓解它——也就是说,做一些在某种程度上减轻风险影响的事情。或者,我们可以接受它。
一种思想流派,现在谢天谢地已经过时了,认为安全是一个二元方程:事物要么是安全的,要么是愚蠢的,如果一个人判断给定的活动或工具是不安全的,那么这个人根本不应该做那件事或使用那个工具。换句话说,在这种思想流派中,风险规避是首选的安全方法。
然而,正如我们大多数人现在承认的那样,绝对安全是不存在的。软件选择、软件/系统配置或网络拓扑的任何神奇组合都无法使我们免受安全漏洞的侵害。任何组合,也就是说,你实际上可以用它做任何工作。在网络计算中,一定数量的风险是不可避免的。
基于风险管理的安全方法承认需要在风险规避、风险缓解和风险接受之间寻求平衡,方法是根据风险发生的可能性和潜在影响对风险进行优先排序。那些既有可能发生又难以从中恢复的风险被标记为最需要缓解或避免的重要风险。那些不太可能发生或恢复成本极低的风险成为风险接受的合理候选者。顺便说一句,当我谈论风险发生的成本或影响时,我不仅指货币成本,还指时间、声誉和生产力的损失。
图 1 显示了风险的可能性、成本和可接受性之间的一般关系。定义可接受风险和不可接受风险区域的曲线的具体形状将因组织而异。例如,金融机构往往比大学网络有更大的红色区域。

图 1. 风险阈值
因此,采取基于风险的安全方法就是承认并非所有风险都是相同的,因此,您必须选择您的战斗。然而,为了有效地做到这一点,您需要在识别和评估特定事业中的风险时具有创造性和诚实性。否认风险存在比承认和接受该风险并在最坏的情况发生时制定恢复计划要危险得多。
这引出了基于风险的方法的另一个重要方面:风险接受不应意味着自满。任何无法避免或缓解的风险至少必须在业务持续性和恢复计划中加以考虑。此外,极少的信息安全风险是无法以某种方式缓解的;许多类型的风险无法消除,但仍然可以控制或减弱。
好的,那么 Linux 安全最好用基于风险的观点来处理。那是什么样的呢?第一步是考虑您的 Linux 系统中已知和潜在的漏洞。大多数 Linux 应用程序和系统漏洞都属于以下类别之一
缓冲区溢出漏洞(不充分的边界检查)。
糟糕的输入验证。
不适当的文件权限。
不适当的系统权限(可避免使用 root)。
马虎的配置。
不安全地使用临时文件。
可预测或已知的默认密码。
管理后门(测试或调试帐户)。
此列表中的第一个漏洞,缓冲区溢出,可以说是最可怕的。缓冲区溢出经常直接导致远程 root 权限泄露。与缓冲区溢出条件一样,许多这些漏洞是编程错误(例如不安全地使用临时文件和管理后门)的直接结果。其他漏洞通常是用户自己造成的,例如可预测的密码或马虎的配置。
然而,除非有人试图利用它,否则任何漏洞实际上都不构成威胁。换句话说,威胁等于漏洞加上攻击者。
第二步是考虑可能利用这些漏洞的方式。虽然 Linux 漏洞多年来变化不大,但试图利用这些漏洞的行为者已经发生了变化。他们变得更加有效和愚蠢。可怕的真相是,漏洞利用代码和脚本的易于获得使得技术不熟练的攻击者越来越容易进行日益复杂的攻击。
例如,传统上,进行缓冲区溢出攻击需要相当大的编程技能——除了能够确定溢出数据最终将出现在内存中的位置之外,攻击者还必须编写或获取漏洞利用代码,或以特定于目标系统架构(如 i386 或 SPARC)的汇编代码编写的 shellcode。Shellcode 是被溢出并执行的代码,从而在目标系统上产生一个 shell,理想情况下具有 root 权限。
在过去,识别偏移量和编写工作 shellcode 的难度大大缩小了潜在的缓冲区溢出攻击者的范围。然而,现在,如果您想利用一个众所周知的缓冲区溢出漏洞,您所需要做的就是执行正确类型的 Google 搜索以获得漏洞利用工具,每个工具都配备了适用于各种目标系统的 shellcode。
编写漏洞利用脚本并在互联网上发布的人已经是一个很大的问题。但他们并不是威胁方程中唯一的行动者;如果您是那种喜欢武装脚本小子的人,那么将漏洞利用完全自动化并将其打包成蠕虫或病毒只是稍微多做一点工作。
当然,病毒无法自行传播;它们总是嵌入在其他东西中,例如,电子邮件附件或可执行文件。蠕虫会自行传播,因此更加可怕——它们本质上是长了翅膀的病毒。事实上,如果您在蠕虫攻击期间观看您的日志文件,您将很难将其与人类进行的攻击区分开来。蠕虫有点像攻击机器人。
因此,攻击者可以是人类或软件。好消息是,由于他们利用的漏洞类型完全相同,因此防御措施对于每种类型都是相同的。坏消息是,攻击脚本、蠕虫和病毒呈指数级缩短了从漏洞被发现和公开到您的系统可能被攻击者探测到该漏洞的时间。
现在,让我们开始将这些威胁与防御措施相匹配。这就是基于风险的方法变得真正重要的地方。
如果您采取绝对主义的安全观,防御很简单。您选择软件不是基于功能、可支持性和安全性的最佳组合,而是完全基于安全性。由于安全性是您的主要软件标准,因此您所需要做的就是保持修补程序,一切都会好起来的。
您可能还会将防火墙配置为不信任来自外部的任何内容,并信任来自内部的所有内容,因为,当然,所有外部人员都可疑,而所有内部人员都值得信赖。事实上,在这种观点中,软件补丁和防火墙规则非常重要,以至于实际上没有其他事情重要。
的确,软件补丁和防火墙很重要。但是,如果我们花时间思考它们旨在解决的真正风险,那么我们依赖补丁的程度以及我们使用防火墙的方式就会有所不同。
考虑一下我在图 2 中概述的场景。防火墙保护 DMZ 网络免受外部世界的侵害,并保护内部网络免受外部世界和 DMZ 的侵害。
图 2 中虚线所示的防火墙规则可能如下所示
允许所有内部主机通过任何端口/协议访问互联网。
允许所有 DMZ 主机通过任何端口/协议访问互联网。
允许所有互联网主机通过 TCP 端口 80 (HTTP) 访问 DMZ。
允许 DMZ Web 服务器通过 TCP 端口 1433 和 2000–65514 访问内部主机。
从表面上看,这似乎足够合理。内部用户需要在互联网上做各种各样的事情,因此限制这种访问很麻烦。DMZ 需要为其日志执行 DNS 查询,那么为什么不也给它出站互联网访问权限呢?并且 DMZ Web 服务器需要访问内部网络上的后端应用程序,该应用程序涉及 TCP 1433 上的数据库查询以及一些未被记录的有限范围内随机分配的高端口。因此,最简单的事情是打开所有高于 1999 的 TCP 端口。
但是,让我们考虑三个合理的风险
基于互联网的攻击者入侵 Web 服务器并使用它来攻击互联网上的其他系统。
蠕虫通过 RPC 漏洞感染内部系统,并且受感染的系统开始扫描互联网上的大片区域以寻找其他易受攻击的系统。
蠕虫感染内部系统并在 TCP 6666 上启动后门监听器。攻击者入侵 Web 服务器,扫描防火墙,检测到众所周知的蠕虫的监听器并连接到内部系统。
在第一个风险情景中,我们面临明显的法律风险。如果我们的 Web 服务器被入侵,并且我们的防火墙未配置为限制其对外部世界的访问,如果 Web 服务器被用于攻击其他系统,我们可能要承担责任。将 Web 服务器的出站访问仅限于必要的服务和目的地可以减轻这种风险。实际上,典型的 DMZ Web 服务器应该很少需要(如果有的话)与外部世界的数据流——它的工作是响应来自互联网的 HTTP 查询,而不是发起自己的互联网事务。
在第二个情景中,我们面临类似的风险,尽管网络性能的影响可能大于法律影响(所有这些扫描流量都可能阻塞我们的互联网上行链路)。同样,更严格的出站访问防火墙策略可以轻松地减轻这种风险。
第三个情景可能看起来比其他情景更离奇——内部发生蠕虫感染和 DMZ 中发生 Web 服务器入侵同时发生的可能性有多大?实际上,它们不必同时发生。如果蠕虫在 TCP 6666 上设置其后门监听器,然后进入休眠状态,则可能在一段时间内未被检测到。换句话说,如果受感染的系统没有及时消毒,则 Web 服务器的入侵不需要与蠕虫感染发生在同一天,甚至在同一个月。与其他两个情景一样,更严格的防火墙策略可以减轻这种风险,并最大限度地减少内部蠕虫感染被外部人员利用的可能性。
除了可以通过更严格的规则来缓解之外,这三个风险还有另一个重要的共同点。您无需准确预测其中任何一个来缓解它们。相反,只需思考“如果我的入站防火墙规则未能阻止某些蠕虫或病毒进入,并且尝试了意外类型的出站访问会发生什么?”就足够了。
我再怎么强调也不为过,重要的是不要只关注攻击预防,这正是入站防火墙规则所做的。同样重要的是思考如果您的预防措施失败可能会发生什么。在信息安全领域,悲观主义是建设性的,而不是失败主义的。
我也希望现在已经清楚,我的观点不是防火墙规则是解决您所有 Linux 风险的答案。重点是,有效的防火墙规则取决于您不仅要考虑已知的威胁,还要考虑潜在的威胁。
因此,如果防火墙不是万能药,我们还必须做什么?在本专栏的前面,我将马虎的配置确定为漏洞的主要类别;其另一面是,仔细的配置是一种强大的防御措施。
假设我在我的 DMZ 中有一个 SMTP 网关,它处理互联网和我的内部网络之间传递的所有电子邮件。进一步假设我组织的技术人员在 Sendmail 方面有很多经验,但很少有时间和意愿学习使用 Postfix,而我作为常驻的安全老顽固,认为 Postfix 更安全。管理层决定网关将运行 Sendmail。一切都完了吗?
不必如此。首先,正如我之前在本专栏中说过的那样,Sendmail 在过去几年的安全记录实际上一直相当不错。但即使这种情况在一夜之间发生变化,并且坏人发现了 Sendmail 中的三个新的缓冲区溢出漏洞,但没有立即向公众公开,我们的 Sendmail 网关也不一定会厄运临头——这要归功于 Sendmail 开发人员的建设性悲观主义。
Sendmail 有许多重要的安全功能,其中两个功能对于应对潜在的缓冲区溢出漏洞特别有帮助。Sendmail 可以配置为在 chroot jail 中运行,这限制了它可以查看的底层文件系统的部分,并且可以配置为以非特权用户和组身份运行,这最大限度地减少了 Sendmail 漏洞直接导致 root 访问的可能性。由于 Sendmail 监听特权端口 TCP 25,因此它必须在部分时间作为 root 运行,因此在实践中,Sendmail 会选择性地将自身降级为非特权用户/组——这是一种部分缓解措施,而不是完全缓解措施。
可 chroot 且以非特权用户/组身份运行是当今大多数设计良好的网络应用程序共有的两个重要安全功能。正如良好的防火墙策略旨在兼顾预防和遏制一样,良好的应用程序配置也考虑了应用程序被滥用或劫持的可能性。因此,衡量应用程序安全性的真正标准不仅在于它在 CERT 咨询中被提及的次数,还必须包括应用程序本身支持的缓解功能。
Mick Bauer,CISSP,是 Linux Journal 的安全编辑,也是明尼苏达州明尼阿波利斯的 IS 安全顾问。他是 Building Secure Servers With Linux(O'Reilly & Associates,2002 年)的作者。