Paranoid Penguin - 使用 Zorp 进行应用程序代理,第一部分
乍一看,有状态数据包过滤似乎已经征服了防火墙世界,无论是在市场份额还是思想份额方面。基于有状态数据包过滤的产品列表很长,其中包括专有行业领导者 Check Point Firewall-1 和 Linux 出色的 Netfilter 内核代码。
但是应用层代理呢?专业的防火墙工程师长期以来一直坚持认为,没有什么比应用程序感知代理更能阻止最广泛的网络攻击了。的确,作为这样的人,我一直对看到应用层代理日益边缘化感到沮丧。在某些圈子里,它们甚至被认为已经过时,而我认为这些理由根本不足以证明失去一个强大的安全工具是合理的。营销至少和其他任何原因一样重要。
显然,我的观点并非孤立。基本日志记录工具 Syslog-NG 的创建者 Balazs Scheidler 创建了 Zorp,这是一款非常出色的开源代理防火墙产品。本月,我将解释为什么 Zorp 帮助我重拾了对应用层代理防火墙的信心,以及这对任何负责保护高度敏感网络的人意味着什么。
此时,你们中的一些人可能会问:“什么是应用层代理和有状态检测?我为什么要关心哪个更好?” 我可以解释一下。如果您是一位经验丰富的防火墙老手,请随意跳到下一节。
当然,防火墙是一台计算机或嵌入式硬件设备,它将不同的网络彼此隔离,并 регулирует 允许哪些流量在它们之间传递。确定哪些网络节点可以发送哪种类型的网络数据包以及发送到哪里的指令称为防火墙规则,或统称为防火墙策略。
这些规则使防火墙与普通路由器不同。必须对路由器进行编程,使其知道如何将数据包从一个网络移动到另一个网络,但不一定知道是否允许它们以任何给定的方式移动。另一方面,防火墙会进行区分。
对数据包进行分类的一种非常简单的方法是根据数据包的互联网协议 (IP) 标头中的互联网信息。IP 标头包含基本信息,最重要的是协议类型、源地址和目标地址,以及(如果适用)源端口和目标端口。端口实际上是数据包中下一个标头,即 UDP 标头或 TCP 标头的一部分。仅查看此基本信息的防火墙称为简单数据包过滤器。由于简单数据包过滤器不会深入检查每个数据包,因此它们往往非常快。
但是,数据包的 IP 标头加上其 TCP 或 UDP 端口号并没有告诉我们该数据包与其他数据包的关系。例如,如果我们检查 HTTP 数据包的 IP 标头,我们知道它是一个 TCP 数据包(感谢 IP 字段),它来自哪里和去往哪里(源 IP 地址和目标 IP 地址字段)以及什么类型的应用程序发送了它(来自目标端口,TCP 80)。表 1 显示了一个简单的 HTTP 数据包过滤规则示例。
但是,这种级别的检查遗漏了一些关于 HTTP 连接的关键信息:数据包是否正在建立新的 HTTP 会话,是否是正在进行的会话的一部分,或者是否只是一个随机的、可能具有敌意的、与任何事物都不相关的数据包。遗漏这些信息是因为关键的会话相关信息(例如 TCP 标志、TCP 序列号和应用程序级命令)都比数据包过滤器挖掘得更深入。这就是有状态数据包过滤的用武之地。
有状态数据包过滤器与简单数据包过滤器一样,首先检查每个数据包的源 IP 地址和目标 IP 地址,以及源端口和目标端口。但它也会更深入地挖掘数据包的 UDP 或 TCP 标头,以确定数据包是否正在发起新的连接。如果是,防火墙会在状态表中为新连接创建一个条目。如果不是,有状态数据包过滤器会根据状态表检查数据包,以查看它是否属于现有连接。有状态数据包过滤器将阻止伪装成现有连接一部分但实际上并非如此的数据包。实际上,UDP 是无连接的,但一个好的有状态防火墙可以推测,在 UDP 53 上向给定服务器发出的出站 DNS 查询之后,应该跟随来自该服务器 UDP 端口 53 的入站响应。与简单数据包过滤相比,有状态数据包过滤有两个主要优点。
首先,防火墙规则可以更简单。防火墙规则无需描述每个双向事务(例如 HTTP)的两个方向,而只需要处理每个允许事务的启动。属于已建立的、允许的连接的后续数据包可以由防火墙的状态表处理,而无需显式规则。在表 2 中,我们看到只需要一条规则即可允许与表 1 中需要两条规则相同的 HTTP 事务。
有状态数据包过滤的第二个主要优点是我们不必做一些令人厌恶的事情,例如允许来自互联网的所有入站 TCP 和 UDP 数据包进入我们的内部网络,如果它们的目标端口高于 1024。如果您没有更好的方法将数据包与允许的事务相关联,则有时必须这样做。换句话说,有状态数据包过滤比简单数据包过滤提供更好的安全性。
“酷”,您说,“有状态数据包过滤器更高效、更安全”,这是真的。但是,即使是有状态数据包过滤器也没有考虑到的事情呢?例如,格式可能错误的 HTTP 命令或有意重叠的 IP 片段呢?是否可能有一种防火墙可以完整检查每个数据包,或者具有其他方法来传播尽可能少的异常数据包?
确实有,它被称为应用层代理或应用层网关。数据包过滤器(无论是简单的还是有状态的)检查所有数据包并传递允许的数据包,而应用层代理将每个尝试的连接分成两个,将自身插入到每个事务的中间,作为平等的参与者。对于每个事务中的客户端或发起者,防火墙充当服务器。对于预期的目的地或服务器,防火墙充当客户端。
图 1 和图 2 说明了这种差异。在图 1 中,我们看到有状态数据包过滤器传递或阻止事务,但最终它是一个观察者,因为它或多或少完整地传递允许的数据包,除非例如它执行网络地址转换 (NAT)。相比之下,在图 2 中,我们看到防火墙终止了每个允许的到自身的连接,并为每个允许的连接的所需实际端点发起了一个新的、代理的连接。
代理分为两种类型:透明代理和非透明代理。在透明代理连接中,双方都不知道连接正在被代理;客户端系统像没有防火墙一样寻址其数据包,并使用其真实的目标 IP 地址。相比之下,在非透明代理连接中,客户端必须将其数据包寻址到防火墙,而不是其真实的目标地址。因为在这种情况下,客户端必须以某种方式告诉防火墙在哪里代理连接,所以非透明代理需要客户端运行支持代理的应用程序。尽管大多数 Web 浏览器和 FTP 客户端都可以配置为使用非透明代理,但透明代理比非透明代理更容易被最终用户接受。现代应用层代理(例如 Zorp)是透明的。
无论是否透明,代理都有几个重要的后果。首先,低级异常(例如 IP 标头中的奇怪标志)通常不会被防火墙传播。防火墙以它(而不是客户端系统)认为可接受的方式发起辅助连接。其次,由于防火墙正在完整地重新创建客户端连接,而不仅仅是传播或简单地重写单个数据包,因此防火墙非常适合在应用层检查连接。但这并非必然;例如,如果防火墙是 SOCKS 防火墙而不是真正的应用层代理,它可能只是将客户端连接数据包的数据有效负载复制到新的代理数据包中。但是,如果防火墙像 Zorp 一样具有应用程序感知能力,则防火墙不仅会检查,还会对所有客户端数据包的数据有效负载做出决策。
让我们看一个例子:假设您的公共 Web 服务器容易受到缓冲区溢出漏洞的攻击,该漏洞涉及格式错误的 HTTP GET 命令,其中包含一个异常长的 URL。您的应用层代理防火墙最初接受来自客户端的连接,但在检查长 URL 后,会关闭与客户端的连接并发送错误消息,并向服务器发送重置,而永远不会转发攻击有效负载,即长 URL。
第三个后果不是正面的:根据定义,代理比数据包过滤更消耗资源,而应用程序感知代理尤其如此。然而,对应用层代理的这种打击通常被夸大了。例如,Zorp 可以在仅配备 128MB RAM 的 700MHz Celeron 系统上代理 88Mbps 的 HTTP 流量,几乎是 T-3 WAN 连接容量的两倍。根据 Zorp Professional v2 产品说明(可在 www.balabit.com 获取),Zorp 在配备 512MB RAM 和 SCSI RAID 硬盘驱动器的双处理器 Pentium 系统上可以处理大约 480Mbps。
总而言之,应用层代理通过将自身插入到它们允许的每个网络事务的中间,从头开始重新创建所有数据包,并根据它们对这些应用程序应该如何工作的知识,而不仅仅是根据它们的容器数据包应该是什么样子,对要传播的应用层命令和数据做出智能决策,从而提供卓越的保护。应用层代理的主要缺点是性能,但主要由于摩尔定律,这种缺点已通过快速但不一定昂贵的硬件得到充分缓解。
为了充分披露,我应该提及许多人在应用层代理中看到的另一个缺点,即更高的复杂性。理所当然的是,由于应用层代理比数据包过滤器更复杂,因此配置它们应该需要更高的复杂性,就像您需要更多知识才能操作 Mosler 保险箱而不是操作典型的公交车站储物柜一样。配置运行 Zorp 或 Secure Computing Sidewinder 的防火墙比配置运行 Check Point Firewall-1 或 Linux Netfilter/iptables 的防火墙要付出更多的工作。
但是,更好的安全性不值得付出一点额外的努力吗?就像信息安全中的其他一切一样,这取决于您自己选择权衡。也许额外的工作对您来说是值得的,也许不是。无论哪种方式,我希望本专栏让您感到高兴,因为您首先有了选择权。本文的其余部分(至少还有一篇后续文章)将精确地解释配置和使用 Zorp 所涉及的内容。
构成 Zorp 的代理守护程序与标准 Netfilter 和 Balabit 提供的 TPROXY 内核模块同时在 Linux 内核之上运行。从理论上讲,这使得 Zorp 与发行版无关,并且它被设计为可以在满足某些要求的任何 Linux 发行版上干净地编译(见下文)。但是,Zorp 是在 Debian Linux 上开发的,并且绝大多数 Zorp 文档都假设您也在运行 Debian。事实上,Zorp GPL 是一个官方的 Debian 软件包(在撰写本文时,在 Debian 的 testing 和 unstable 版本中)。
Zorp 有三个版本:Zorp GPL,免费的 GPL 版本;Zorp Unofficial,Zorp GPL 的前沿或 Beta 版本;以及 Zorp Professional(或简称为 Zorp Pro),这是一款基于 Zorp GPL 但功能更多的商业产品。如果您购买 Zorp Pro,您将获得一张可启动 CD-ROM,其中不仅安装了 Zorp Pro,还安装了 ZorpOS,这是一个为 Zorp 优化的精简版 Debian 发行版。使用 Zorp Pro,裸机 Zorp 安装只需不到 15 分钟,当然,不包括后续配置。任何在尝试安装满足自己需求的足够 Debian 时,都经历过漫长的 dselect 会话的人都会体会到这一点的美妙之处。
Zorp Pro 还包括新的 Zorp Management Server (ZMS),它允许您从中央管理主机管理多个 Zorp 防火墙。主机反过来可以使用 ZMC(Debian Linux 和 Windows 版本中都提供的 GUI 客户端)远程操作。ZMS 在功能上等同于 Check Point Firewall-1 的管理模块,这可以说是 Check Point 征服企业防火墙世界的最大原因。ZMS 有潜力使 Zorp 对有很多防火墙需要管理的站点非常有吸引力。
ZMS/ZMC 仍然有点粗糙——Balabit 预计不会在 2004 年 3 月发布 Zorp Pro 该部分的消费者可安装版本(尽管在撰写本文时,付费客户正在成功使用它)。即使您不使用 ZMS/ZMC,Zorp Pro 的流畅安装和广泛的功能(包括 Zorp GPL 中不支持的几个应用程序代理)也使 Zorp Professional 物有所值。
与 Zorp Pro 不同,Zorp GPL 和 Zorp Unofficial 需要一个可以正常工作的 Linux 安装,其中包括以下内容:glib 2.0、Python 2.1、libcap 1.10 和 openssl 0.9.6g。它还需要一个使用 IP、防火墙和透明代理支持编译的 Linux 2.2 内核,或者一个使用 iptables、iptables 连接跟踪、iptables NAT 和使用 Balabit 的 TPROXY 内核补丁 (www.balabit.com/products/oss/tproxy) 编译的 Linux 2.4 内核,iptables 透明代理。所有这些功能都应编译为模块。
一旦您的操作系统准备就绪,您可以从二进制 deb 软件包安装 Zorp GPL,也可以从源代码编译 Zorp GPL(可在 www.balabit.com/downloads 获取)。编译 Zorp GPL 比典型的 ./configure make make install 例程要复杂一些;有关详细说明,请参阅 www.balabit.com/products/zorp_gpl/tutorial 上的 Zorp GPL 教程。
下次,我将描述如何设置 Zorp GPL 以保护典型的互联网—DMZ—可信网络拓扑。
Mick Bauer,CISSP,是Linux Journal的安全编辑,也是明尼苏达州明尼阿波利斯的 IS 安全顾问。他是Building Secure Servers With Linux(O'Reilly & Associates,2002 年)的作者。