设计和使用 DMZ 网络保护互联网服务器
当今防火墙工程中最有用的工具之一是 DMZ,或称非军事区,这是一个所有公开访问的服务都放置在其中的网络,以便可以更密切地监视它们,并且还可以将它们与内部网络隔离。DMZ、堡垒主机和 Linux 是一个特别好的组合。
但是,DMZ 到底是什么?设计 DMZ 是否有不止一种正确的方法?每个托管互联网服务的人都需要 DMZ 网络吗?这些是我尚未真正解决的问题,因此本月我们将从更高的层面审视 DMZ 安全性。
顺便说一句,您可能会认为您当前的无 DMZ 防火墙系统对于您的需求来说是合理的。我希望您继续阅读,无论如何:任何与不受信任的网络直接接触的主机或服务(无论是否在 DMZ 上)都需要特别小心,并且本文中讨论的许多技术和注意事项都适用于非 DMZ 和 DMZ 环境。
在我们继续之前,让我们先澄清一些定义。这些定义可能与您习惯或偏好的定义不同,但它们是我在本文中使用的定义
DMZ(非军事区):一个包含可公开访问的服务器的网络,该网络与“内部”网络本身隔离,但不一定与外部世界隔离。
内部网络:我们试图保护的网络:最终用户系统、包含私人数据的服务器以及我们不希望外部世界发起连接的所有其他系统。也称为受保护网络。
防火墙:一个将一个网络与另一个网络隔离的系统或网络。这可以是路由器、运行特殊软件(除了或代替其标准操作系统)的计算机、专用硬件设备(尽管这些设备往往是预封装的路由器或计算机),或执行数据包过滤、应用层代理和其他访问控制的任何其他设备或设备网络。在本文中,该术语通常指单个多宿主主机。
多宿主主机:任何具有多个网络接口的计算机。
堡垒主机:一个运行可公开访问的服务但本身不是防火墙的系统。堡垒主机是我们放置在 DMZ 上的主机(尽管它们可以放置在任何地方)。该术语暗示已经完成了一定程度的操作系统加固,但这(可悲的是)并非总是如此。
数据包过滤:检查数据包的 IP 标头,并根据其源 IP 地址、目标 IP 地址、源端口(服务)和目标端口(服务)的某种组合来传递或丢弃它们。不考虑应用程序数据,即,并非一定注意到故意格式错误的数据包,假设可以读取其 IP 标头。数据包过滤几乎是所有防火墙功能的一部分,但不被认为本身足以防止除最直接的攻击之外的任何攻击。大多数路由器(和许多低端防火墙)在网络安全方面仅限于数据包过滤。
代理:充当内部主机和不受信任/外部主机之间给定服务类型(FTP、HTTP 等)的所有交互的中介。这意味着,但不保证,对应用层数据进行复杂的检查(即,不仅仅是简单的数据包过滤)。一些防火墙拥有甚至围绕应用层代理构建。要代理的每个服务都必须显式支持(即,“编码在其中”);依赖应用层代理的防火墙倾向于对其默认不支持的服务使用数据包过滤或重写。
状态检测:最简单地说,这指的是跟踪三向握手(主机 1:SYN、主机 2:SYNACK、主机 1:ACK),该握手在为给定 TCP 服务启动每个会话时发生。最复杂地说,它指的是跟踪正在检查的每个会话的此信息和后续(包括应用层)状态信息。后者远不如前者常见。
这是一大堆术语,但它是有用的术语(实际上足够有用,可以理解大多数防火墙供应商的宣传)。现在我们准备深入研究 DMZ 架构。
在昂贵的商业防火墙的世界(我以此为生的世界)中,“防火墙”一词几乎总是指具有多个网络接口的单台计算机或专用硬件设备。实际上,此定义也适用于低得多的解决方案:网卡很便宜,PC 通常也很便宜。
无论如何,这与过去的日子不同,当时一台计算机通常无法跟上检查大型网络的所有传入和传出数据包所需的处理器开销。换句话说,路由器,而不是计算机,曾经是抵御网络攻击的第一道防线。
现在情况不再如此。即使是具有高容量互联网连接的组织,通常也使用多宿主防火墙(无论是商业的还是基于 OSS 的)作为保护其网络的主要工具。这要归功于摩尔定律,它以比市场提供廉价互联网带宽更快的速度为我们提供了廉价的 CPU 功率。换句话说,即使是相对较慢的 PC,现在也可以对完整的 T1 级(1.544MBps)网络流量执行复杂的检查。
因此,现在最常见的防火墙架构是图 1 中所示的架构。在此图中,我们有一个数据包过滤路由器,它充当初始但非唯一的防线。直接位于此路由器后面的是一个真正的防火墙,在本例中是一台运行 Red Hat Linux 与 IPChains 的 Sun SparcStation。从互联网或外部路由器到内部网络没有直接连接:所有进出内部网络的流量都必须通过防火墙。
顺便说一句,在我看来,所有外部路由器都应使用某种级别的数据包过滤(在 Cisco 词汇表中也称为“访问控制列表”)。即使从这种路由器向内跳的下一跳是一个昂贵和/或经过仔细配置和维护的防火墙,拥有冗余的强制执行点也永远不会有坏处。事实上,当最近的 Black Hat Briefings 上演示了几个 Check Point 漏洞时,一位 Check Point 发言人明确提到,仅仅依靠自己的防火墙是愚蠢的!
图 1 中缺少或错误的是什么?(我说这种架构很常见,但并非完美!)公共服务,如 SMTP(电子邮件)、域名服务 (DNS) 和 HTTP (WWW) 必须通过防火墙发送到内部服务器,或托管在防火墙本身上。
传递此类流量不会自动将其他内部主机暴露于攻击,但它确实放大了此类服务器被入侵的后果。从表面上看,在防火墙上托管公共服务也不一定是坏主意(有什么环境比防火墙更安全呢?),但性能问题是显而易见的:应该允许防火墙使用其所有可用资源来检查和移动数据包。(尽管有一些可能的例外,我们稍后会研究。)
那么,将公共服务放在哪里,使其不会直接或间接地暴露内部网络并过度消耗防火墙资源?当然是在 DMZ 网络中!最简单地说,DMZ 是任何公众可以访问但与内部网络隔离的网络。但是,理想情况下,DMZ 也应受到防火墙的保护。图 2 显示了我首选的防火墙/DMZ 架构。
在图 2 中,我们有一个三宿主主机作为我们的防火墙,放置方式是,提供可公开访问服务的主机位于它们自己的网络中,并具有到防火墙的专用连接,而其余公司网络面向不同的防火墙接口。如果配置正确,防火墙将在评估从互联网到 DMZ、从 DMZ 到互联网、从互联网到内部网络、从内部网络到互联网、从 DMZ 到内部网络以及从内部网络到 DMZ 的流量时使用不同的规则。
这听起来可能比内部托管或防火墙托管的服务具有更多的管理开销,但实际上,它可能要简单得多,因为 DMZ 可以被视为一个单一实体。在内部托管服务的情况下,除非所有主机都位于与内部网络的其余部分隔离的单个 IP 网络上,否则必须单独考虑每个主机。
有时会使用其他架构,图 3 说明了其中的两个架构。屏蔽子网架构完全依赖于外部和内部路由器的安全性。从外部到内部有一条直接的物理路径,该路径仅由路由器的数据包过滤规则等更复杂的东西控制。
图 3 中的右侧图示显示了我所说的“随风飘荡”DMZ 架构,其中在互联网和内部网络之间存在一个功能齐全的防火墙,但在互联网和 DMZ 之间没有,DMZ 放置在防火墙外部,仅受单个数据包过滤路由器保护。
屏蔽子网和随风飘荡架构仍然出现在防火墙教科书中(尽管名称不同),但在我看来,它们都对路由器寄予了太多的信任。这种信任是有问题的,原因有几个:首先,在某些组织中,路由器的控制权与防火墙的控制权不同,并且此人可能会坚持认为路由器具有弱管理密码、弱访问控制列表,甚至连接了调制解调器,以便路由器的供应商可以维护它;其次,路由器比配置良好的计算机更容易被黑客入侵(例如,默认情况下,它们几乎总是支持通过 Telnet 进行远程管理,这是一种高度不安全的服务);第三,数据包过滤是一种粗糙且不完整的网络流量调节手段。
即使是基于 OSS/自由软件的防火墙也可以支持 IPSEC、应用层代理、状态检测、RADIUS 身份验证以及大多数路由器上不可用的各种其他复杂控件。总而言之,路由器旨在路由,而不是保护。
Cisco PIX 怎么样?PIX 防火墙是路由器,但具有经过加固且以安全为中心的 Cisco IOS 操作系统版本。虽然它在很大程度上依赖于简单的数据包过滤,但它支持足够多的附加功能,如果配置得当,可以成为一个很好的防火墙。当我质疑路由器作为防火墙的可行性时,我指的是非加固的通用路由器。
总而言之,DMZ 架构的外观取决于防火墙架构的外观。围绕多宿主主机构建的防火墙设计适合我推荐的 DMZ 架构(参见图 2),其中 DMZ 连接到防火墙主机上的其自己的接口,因此,与互联网和内部网络隔离。
一旦您决定将 DMZ 放在哪里,您需要精确地决定将在那里驻留什么。简而言之,我的建议是将所有可公开访问的服务都放在 DMZ 中。
我经常遇到这样的组织:尽管有严格的 DMZ 策略,但仍将一项或多项关键服务传递到内部主机。通常,MS-Exchange 或其他一些并非专门为互联网强度安全而设计的应用程序会成为例外,并且尚未将其加固到可以达到的程度。
但是,以这种方式传递的一个应用程序变成了可怕的单点故障:只需该应用程序中的一个缓冲区溢出漏洞,不受欢迎的访问者就可以访问该主机可访问的所有主机。对于该主机列表来说,最好是一个简短的列表,即 DMZ 主机,而不是一个长列表(且敏感的列表),即内部网络上的所有主机。这一点怎么强调都不为过:DMZ 的真正价值在于,它使我们能够更好地管理和控制互联网连接带来的风险。
此外,管理传递服务的人员可能与管理防火墙和 DMZ 服务器的人员不同,并且可能没有那么注重安全性。如果仅出于其他原因,所有公共服务都应进入 DMZ,以便它们受到组织中最偏执的系统管理员(即防火墙管理员)的管辖。
这是否意味着公司的电子邮件、DNS 和其他关键服务器都应从内部移至 DMZ?绝对不是!相反,它们应该分为内部服务和外部服务(参见图 2)。
例如,DNS 应分为外部 DNS 和内部 DNS。传播到互联网的外部 DNS 区域信息应仅包含有关可公开访问主机的信息。有关其他非公共主机的信息应保存在单独的内部 DNS 区域列表中,这些列表无法传输到外部主机或被外部主机看到。
同样,内部电子邮件(即,从内部主机到其他内部主机的邮件)应严格由内部主机处理,所有面向互联网或源自互联网的邮件应由 DMZ 主机处理,通常称为 SMTP 网关。(有关拆分 DNS 服务器和 SMTP 网关以及如何使用 Linux 创建安全服务器的更具体信息,请参阅 2000 年 10 月的Linux Journal。)
因此,几乎任何同时具有私有和公共角色的服务都可以并且应该以这种方式拆分。虽然这看起来像是增加了大量工作,但事实并非如此,而且实际上,它是解放性的:它允许您主要基于功能或其他管理和最终用户友好的因素来构建内部服务,同时主要基于安全性和性能因素来设计您的公共 (DMZ) 服务。这也是将 Linux、OpenBSD 和其他开源软件集成到其他专有软件密集型环境中的便捷机会!
不用说,任何严格意义上是公共的服务(即,内部用户与普通公众使用的方式不同或更敏感的方式)都应仅驻留在 DMZ 中。总之:所有公共服务,包括也在内部使用的服务的公共组件,如果适用,都应拆分并托管在 DMZ 中,没有例外。
好的,所有公共服务都进入 DMZ。但是,每个服务都需要自己的主机吗?任何服务都可以托管在防火墙本身上吗?DMZ 上应该使用集线器还是交换机?
最后一个问题最容易回答:随着交换端口的价格逐年下降,交换机在任何 LAN 上都是首选的,尤其是在 DMZ 中。交换机在两个方面都优于集线器。从安全角度来看,它们更好,因为不可能嗅探或窃听未传递到自己交换机端口的流量。由于我们对 DMZ 主机的假设之一是它们比内部主机更容易受到攻击,因此这一点很重要。我们不仅需要考虑如何防止这些主机被入侵,还需要考虑如果它们被入侵可能会造成的后果——被用来嗅探 DMZ 上的其他流量是一种可能的后果。
交换机优于集线器的另一个方面当然是它们的性能。大多数时候,每个端口都有自己的带宽块,而不是与所有其他端口共享一个大块带宽。但是请注意,每个交换机都有一个背板,用于描述交换机可以处理的实际数据包量;如果一个 10 端口 100Mbps 交换机有一个 800MBps 的背板,那么它实际上无法处理 1000MBps。即便如此,低端交换机的性能也大大优于同类集线器。
尽管如此,集线器可能仍然足以满足您的 DMZ 的需求,具体取决于 DMZ 上主机的数量、您对被入侵的 DMZ 主机被用来攻击其他 DMZ 主机的担忧程度以及进出 DMZ 的流量。
其他两个问题通常可以通过非安全驱动因素(成本、预期负载、效率等)来确定,前提是所有 DMZ 主机都经过彻底的安全保护和监控。此外,管理进出 DMZ 流量的防火墙规则(数据包过滤器等)需要尽可能地偏执。
DMZ 上的每个主机都必须彻底固定似乎是常识。但可以肯定的是,人们经常遇到这样的组织:他们足够偏执(谨慎)到拥有 DMZ,但又不够偏执到正确地保护其 DMZ。好消息是,只需花费一点时间和适当的怀疑态度,您就可以显着降低任何系统被脚本小子入侵的风险。
始终运行最新稳定版本的操作系统、软件和内核,并及时更新已发布的安全补丁。
如果每个人都遵循这个简单而明显的原则,www.hackernews.com 上的“地下传闻”被黑客入侵的网页列表将会短得多。正如我们上个月在“保护 DNS”中讨论的那样,绝大多数基于 DNS 的黑客攻击都不适用于最新版本的 BIND;对于大多数其他 Linux 网络软件包,也可以安全地说相同的话。我们都知道这一点,但我们并不总是有时间贯彻执行。
您不用于任何重要用途的程序是您几乎没有理由正确维护的程序,因此是攻击者的明显目标。这甚至比旧软件更容易修复。在设置时,只需删除或重命名 /etc/rc.d/ 中相应运行级别目录中的所有不需要的链接。
例如,如果您正在配置一个不需要成为其自己的 DNS 服务器的 Web 服务器,您将输入如下内容
mv /etc/rc.d/rc2.d/S30named /etc/rc.d/rc2.d/disabled_S30named
(请注意,您的命名启动脚本可能具有不同的名称,并且可能存在于 /etc/rc.d 的不同或附加子目录中。)
虽然应禁用任何不需要的服务,但以下服务尤其值得关注
RPC 服务:Sun 的远程过程控制协议(如今几乎包含在所有 UNIX 版本中)允许您通过 rsh、rcp、rlogin、nfs 等在远程系统上执行命令。不幸的是,它不是一个非常安全的协议,尤其是在 DMZ 主机上使用时。您不应向外部世界提供这些服务——如果您需要它们的功能,请使用 ssh(安全外壳),它专门设计为 rpc 服务的替代品。禁用(重命名)/etc/rc.d 的所有子目录中出现的 nfsd 和 nfsclientd 脚本,并注释掉 /etc/inetd.conf 中与任何 r 命令对应的行。(警告:本地进程有时需要 RPC 端口映射器,也称为 rpcbind——谨慎禁用它,如果其他事情停止工作,请尝试重新启用它)。
inetd:Internet 守护程序是一种使用单个进程(即 inetd)侦听多个端口并在需要时调用代表其侦听的服务的便捷方法。然而,它的有用寿命即将结束:即使使用 TCP Wrappers(它允许您为每个 inetd 服务启用非常精细的日志记录),它也不如简单地将每个服务作为守护程序运行安全。(FTP 服务器真的没有理由不一直运行 FTPD 进程。)此外,默认情况下在 inetd.conf 中启用的大多数服务都是不必要的、不安全的或两者兼而有之。如果您必须使用 inetd,请编辑 /etc/inetd.conf 以禁用所有您不需要(或从未听说过)的服务。注意:许多 rpc 服务在 inetd.conf 中启动。
linuxconfd:虽然当前版本的 linuxconf(一种可以远程访问的系统管理工具)中没有任何已知的可利用漏洞,但 CERT 报告称,通常会扫描此服务,并且攻击者可能会使用它来识别具有其他漏洞的系统(CERT 当前活动页面 2000 年 7 月 31 日,www.cert.org/current/current_activity.html)。
sendmail:许多人认为 sendmail(在大多数 UNIX 版本中默认启用)即使在仅向自身发送电子邮件的主机上也是必要的(例如,由 crontab 守护程序发送给 root 的 Ctrl+tab 输出等管理消息)。事实并非如此:只有必须向其他主机传递邮件或从其他主机接收邮件的主机才需要 sendmail(或 postfix、qmail 等)。sendmail 通常在 /etc/rc.d/rc2.d 或 /etc/rc.d/rc3.d 中启动。
Telnet、FTP 和 POP:这三个协议有一个非常糟糕的共同特征:它们要求用户输入用户名和密码,这些用户名和密码以明文形式通过网络发送。Telnet 和 FTP 很容易被 ssh 及其文件传输实用程序 scp 替换;电子邮件可以自动转发到不同的主机,留在 DMZ 主机上并通过 ssh 会话读取,或者使用 ssh 的“本地转发”通过 POP 下载(即,通过加密的安全外壳会话管道传输)。这三种服务通常由 inetd 调用。这些守护程序通常由 inetd 启动。
某些守护程序(如 named)显式支持在“chroot 监狱”中运行(即,对于 chroot 进程,“/”实际上是无法从中导航出去的其他目录)。这是一个有价值的安全功能;如果 chroot 进程被劫持或以某种方式利用,攻击者将无法访问 chroot 监狱之外的文件。
在 Linux 上,即使没有内置 chroot 支持的进程也可以以 chroot 方式运行:只需键入 chroot chroot-jail 路径 命令字符串。例如,要以 chroot 方式运行假想命令 bubba -v plop 到 /var/bubba,您将键入
chroot /var/bubba /usr/local/bin/bubba -v plop
但是请注意,chroot 进程运行所需的任何系统文件都必须复制到 chroot 监狱的相应子目录中。如果我们的假想进程 bubba 需要解析 /etc/passwd,我们需要将 passwd 文件的副本放在 /var/bubba/etc 中。但是,该副本无需包含 chroot 进程所需的更多信息;为了进一步扩展我们的示例,如果 bubba 是一个服务器,只有匿名用户可以访问,那么 /var/bubba/etc/passwd 可能只需要一行(例如,nobody::50:50:Anonymous user::/bin/noshell)。
虽然某些守护程序只有在以 root 身份运行时才能工作(启动时调用的进程的默认 UID),但如今许多程序都可以设置为以非特权用户身份运行。例如,Postfix,Wietse Venema 的 sendmail 替代品,通常使用名为 postfix 的特殊非特权帐户运行。
这具有与 chroot 类似的效果(事实上,两者通常一起使用)。如果进程被劫持或以其他方式入侵,攻击者将获得低于 root 权限的访问权限(希望低得多)。但是,请注意确保此类非特权帐户仍然具有足够的权限来完成其工作。
默认情况下,某些 Linux 发行版具有冗长的 /etc/passwd 文件,其中包含甚至供尚未安装的软件包使用的帐户。例如,我的笔记本电脑运行 SuSE Linux,在 /etc/passwd 中有 22 个不必要的条目。注释掉或删除此类条目,尤其是包含可执行 shell 的条目,非常重要。
这是另一件我们都知道应该做但经常未能贯彻执行的事情。您无法检查不存在的日志,也无法从您不读取的日志中学习任何东西。确保您的重要服务以适当的级别进行日志记录,了解这些日志的存储位置以及它们在变大时是否/如何轮换,并养成检查当前日志以查找异常的习惯。
grep 在这里是您的朋友:仅使用 cat 往往会让人不知所措。您可以使用 shell 脚本自动执行某些日志解析操作;脚本也便于针对系统的配置文件运行 diff 以监视更改(即,通过将当前版本与缓存副本进行比较)。
如果您有多个 DMZ 主机,您可能希望考虑使用 syslogd 的功能来整合来自多个主机的日志到一个系统上。您可能没有意识到,syslog 守护程序可以配置为不仅侦听来自本地系统上其他进程的日志数据,还可以侦听来自远程主机的数据。例如,如果您有两个 DMZ 主机(bobo 和 rollo),但希望能够在单个位置查看两台计算机的日志,您可以将 bobo 的 /etc/syslogd.conf 更改为仅包含以下行
*.* @rollo
这将导致 bobo 上的 syslogd 将所有日志条目发送到 rollo 的,而不是它自己的 /var/log/messages 文件。
虽然很方便,但请注意,此技术有其自身的安全隐患:如果 rollo 被入侵,bobo 的日志也可能被篡改。此外,rollo 的攻击者可能会了解有关 bobo 的有价值信息,他们随后可以使用这些信息来攻击 bobo。这可能对您来说无关紧要,但也可能很重要,但您绝对应该考虑一下,好处是否证明了风险是合理的(特别是考虑到好处可能是您可以更有效地防止 DMZ 主机首先被入侵)。
我们将以使 DMZ 变得有价值的指南作为结尾。
当然,您需要仔细限制从外部世界到 DMZ 的流量。但同样重要的是,仔细限制从 DMZ 到内部网络的流量(以在 DMZ 主机被入侵时保护它)以及从 DMZ 到外部世界的流量(以防止被入侵的 DMZ 主机被用来攻击其他网络)。
不用说,您可能需要阻止从互联网到内部主机的所有流量。(您可能感觉需要或不需要限制从内部网络到 DMZ 的流量,具体取决于内部用户真正需要访问 DMZ 主机的类型以及您对内部用户的信任程度。)在任何情况下,如果您的防火墙可以区分合法和伪造的源 IP 地址,则您的防火墙安全策略将更有效。否则,外部用户可能有可能通过伪造内部源 IP 将数据包滑过防火墙。
默认情况下,大多数防火墙都没有启用此功能(该功能通常称为防 IP 欺骗。即使您的防火墙支持它,您也可能必须自己配置并启动它。但这非常值得付出努力。
