使用防火墙设计安全网络
防火墙可以是您最好的朋友;它也可能引起许多无法预见的问题。您应该在何时考虑在网络中部署防火墙?如果您确定需要防火墙,应该将其放置在网络的哪个位置?通常,防火墙策略源于非技术性的董事会会议,仅仅基于主席“我认为我们需要一个防火墙来保护我们的网络”的评论。一个组织需要思考安装防火墙的原因——它旨在防御什么,以及应该如何执行其工作?本文旨在阐明一些需要考虑的问题。
虽然这个问题似乎很容易回答,但事实并非如此。安全专家表示,防火墙是一台专用机器,用于检查每个通过的网络数据包,并根据系统管理员设置的规则丢弃或拒绝某些数据包。然而,今天我们也遇到了运行 Web 服务器的防火墙(Firewall-1 以及各种 NT 和 Unix 机器)和运行防火墙应用程序的 Web 服务器。现在,将任何过滤网络数据包的东西称为防火墙已成为普遍做法。因此,“防火墙”一词通常指的是过滤数据包的功能,或执行该功能的软件——较少指运行该应用程序的硬件。
完全没有必要购买专门的防火墙硬件甚至软件。一台 Linux 服务器——运行在 400 美元的 386 PC 上——提供的保护与大多数商业防火墙一样多,但具有更大的灵活性和更简单的配置。
几年前,我参加了一个荷兰 Unix 用户组 (NLUUG) 会议。其中一个主题是“使用防火墙保护您的网络”。在听取了几位演讲者的发言后,我没有找到任何论点可以证明防火墙的必要性。我仍然认为这基本上是正确的。一个良好的网络不需要防火墙来过滤掉无意义的数据;所有机器都应该能够处理坏数据。然而,理论和实践是两回事。
除非您对网络拥有令人难以置信的严格控制,否则您的用户很可能会在其工作站上安装各种各样的软件,并以您可能没有预料到的方式使用该软件。此外,常见的操作系统中不断发现新的安全漏洞,并且很难确保每台机器都拥有最新版本,并且修复了所有错误。
由于这两个原因,集中控制的防火墙是一道有价值的防线。是的,您应该控制用户安装的软件。是的,您应该确保他们工作站上的安全控制尽可能保持最新。但由于您不能一直依赖这种情况,因此防火墙始终是一个需要考虑的因素,并且几乎总是现实。
几个月前,互联网安全界出现了一次小危机——臭名昭著的“死亡之 Ping”。在 BSD 套接字代码的某个地方,缺少对某些分段网络数据包大小的检查。结果是,在重新组装分段数据包后,数据包最终可能比允许的最大数据包大小大几个字节。由于代码假定这种情况永远不会发生,因此内部变量没有设置得比此最大值更大。结果是一个非常糟糕的缓冲区溢出,导致生成任意代码,通常会导致机器崩溃。这个错误影响了广泛的社区,因为它存在于 BSD 套接字代码中。由于此代码经常被用作新软件(和固件)的基础,因此各种各样的系统都容易受到此错误的影响。易受“死亡之 Ping”攻击的所有操作系统的列表可以在 Mike Bremford 的页面上找到,网址为 http://prospect.epresence.com/ping/。许多操作系统以外的设备也容易受到此问题的影响——以太网交换机、路由器、调制解调器、打印机、集线器和防火墙也是如此。机器越繁忙,缓冲区溢出就越致命。
这个错误如此危险的第二个原因是它非常容易被滥用。Microsoft Windows 操作系统包含 ICMP ping 程序的实现,该程序错误地计算了数据包的大小。您可以告诉它使用的最大数据包是 65527,这确实是允许的最大 IP 数据包。但是此实现创建了一个 65527 字节的数据段,然后在上面放置了一个 IP 标头。显然,您最终会得到一个大于 65535 的数据包。因此,您所要做的就是键入
ping -l 65527 victim.com
一旦这种方法为人所知,世界各地的服务器都崩溃了,因为人们愉快地 ping 了全球。
从 Mike 页面上的列表中可以看出,并非所有已知的易受攻击设备都有补丁程序可用。即使有,系统管理人员也至少需要几天时间才能修复所有设备。在这种情况下,防火墙具有非常有效的作用。如果发现这种程度的安全问题,您可以在网络的接入点禁用它。如果您当时有一个防火墙,则很可能您已过滤掉所有 ICMP 数据包,直到您确认您的数据库服务器没有漏洞为止。即使这些机器中没有一台应该存在漏洞,但事实是,很多机器都存在漏洞。
我们从这次经验中得出的结论是,防火墙提供的响应速度和能力可能是一种非常宝贵的工具。
以下是您应该提出的基本问题
我们需要保护什么?
我们需要防范谁?
我们将防火墙放置在网络中的什么位置?
我们如何配置防火墙?
我们如何监控正在发生的事情?
要正确回答这些问题,至关重要的是您要绘制整个网络的地图。您不需要绘制网络中每个设备的地图,因为这无论如何都会经常变化。尝试绘制单独的子网、路由器、集线器和物理位置(楼层、办公室、教室)。包括您希望最安全地保护的网络的重要部分。
大多数防火墙用于保护整个局域网 (LAN)。在这种情况下,Internet 路由器通常充当防火墙。正确配置的 Internet 路由器会过滤掉本地使用的 IP 号码(例如 10.*、127.*、192.x.y.*)以防止 IP 欺骗。它还应过滤掉来自外部的所有数据包,这些数据包的 IP 号码通常只能来自内部。此类别中的任何数据包都只能是试图欺骗您的机器,应立即拒绝访问。接下来,过滤掉所有不具有您注册的 IP 号码类别的传出 IP 流量。这不仅是为了防止发送虚假数据包(或防止您的人员欺骗 Internet),也是为了您自身的安全。特别是,Windows 产品往往会忽略 RFC。有一天,我发现一台 Windows 95 机器通过给本地打印机分配 IP 号码 6.6.6.6 来共享它。如果您的 Internet 路由器不过滤掉这些数据包,您可能会将打印的文档路由到 Internet 上。
防火墙的另一个常见用途是保护单台机器。如果您想使用防火墙保护单台机器,则必须确保它不依赖防火墙外部的任何东西;否则,您的防火墙除了给人一种虚假的安全感之外,没有任何作用。如果受保护的服务器正在使用来自未受保护的 PC 的数据,则有人可以伪造 PC 上的信息,从而对服务器的数据造成潜在的严重损害。获得 PC 访问权限的人员也可以通过冒充受信任的 PC 用户来访问服务器。如果机器依赖于其他机器,您需要将防火墙放置在更上游的位置,以便它也可以保护这些机器。NFS 是您不希望在此设置中允许通过防火墙的应用程序的一个很好的例子。这种类型的防火墙易于配置。阻止敏感服务器上未使用的所有协议,仅转发具有服务器 IP 的数据包,并且不要忘记防止从外部欺骗服务器的 IP 号码。
用于设置典型防火墙规则以保护单台机器或小型子网的脚本如清单 1. 典型防火墙规则脚本所示。
显然,实际网络不像上述示例那样简单。大多数网络都有各种多宿主机器,这些机器是不同子网的一部分。像学校这样的大型组织存在一个问题,即很多人都可以物理访问以太网。保护这些网络部分区域的最佳方法是在物理上独立的电缆上使用子网。例如,为系统管理办公室提供单独的子网将是一个很好的策略,因为系统管理员通常需要使用特权帐户。
通常,您希望保护的网络只执行一些有限的任务。在典型的管理网络中,人们希望使用 Web、电子邮件、POP,并且通常希望使用 telnet 连接到管理数据库服务器(隐藏在 Windows 应用程序中)。网络地址转换最适合这些网络。它可以确保管理网络中的各个机器不可访问(除非网络地址转换主机本身被入侵,如果它不运行任何服务,则几乎不可能),同时保留连接到 Internet 的所有基本功能。这还有一个额外的优势。通常,对数据库服务器的访问通过 TCP 包装器进行保护,该包装器仅允许一组特定的主机访问数据库。对于添加到网络的每台新客户端机器,都必须在相应的 /etc/hosts.* 文件中添加条目。使用网络地址转换,此条目不是必需的,因为新机器将被网络地址转换,并且数据库服务器已经知道网络地址转换主机的 IP 号码。
如果您无法在物理上隔离管理网络,则可能需要考虑使用某种形式的加密。Kerberos 通常用于这些情况,但您也可以使用 ssh-PPP 隧道(ssh 是一种密钥对加密算法)。借助 ssh,您可以轻松地在您的网络地址转换主机和数据库服务器之间创建虚拟专用(加密)网络。这应该可以消除学生在网络上启动恶意 Linux 机器带来的任何窃听风险。
对于复杂网络,重要的是要知道威胁来自哪里。威胁通常来自内部而不是外部,外部由 Internet 路由器/防火墙机器保护。此外,不要忘记保护自己免受调制解调器池的侵害——IP 欺骗也可能从那里发生。
配置防火墙基本上有两种方法。第一种也是最安全的设置是“拒绝一切,除非我们明确允许”。缺点是您会遇到很多用户想知道为什么某些东西不起作用。您可能会在防火墙保护一个非常小的子网(仅包含服务器且不包含客户端)的设置中考虑这种方法。用于设置此类防火墙的脚本如清单 2. “拒绝一切...”防火墙所示。这种类型的防火墙需要相当多的关于某些协议如何工作的知识。除非您有适当的文档和足够的时间投入,否则不要尝试它。
第二种也是更简单的设置是“允许一切,除非我们明确拒绝”。这种设置使您的网络相当开放,但控制一些危险或不需要的协议。例如,一些 ISP 使用此功能来阻止所有“CU-SeeMe”流量,因为这种类型的流量可能会阻塞他们的整个网络。设置此类防火墙的脚本如清单 3. “允许一切...”防火墙所示。
正如您可能在之前的两个示例中注意到的那样,所有拒绝规则都设置了选项 -o,以指示 Linux 内核使用 syslog 工具显式记录所有被拒绝的数据包。如果您拒绝数据包而不记录它们,那么有一天您将花费数小时进行错误查找,然后才意识到问题是数据包过滤器。根据您配置 syslog 守护程序 (/etc/syslog.conf) 的方式,这些消息将显示在 /var/log/messages 文件或 /var/log/syslog 文件中。您应该定期检查防火墙机器上的这些日志文件。确保有足够的磁盘空间来记录甚至是用消息淹没您的攻击。如果可能,请为您的日志文件使用单独的分区。
以下是我们 syslog 中的一些日志条目,用于演示一些常见问题。这些日志条目来自我们的 Livingston 路由器以及我们的 Linux 机器。
Jan 2 15:17:57 unreachable.xtdnet.nl 15 deny: UDP from 130.244.101.74.137 to 194.229.18.53.137
这可能是我们的防火墙规则最常遇到的情况。端口 137 是 NetBios 名称服务端口,Microsoft Windows 机器使用该端口查找本地网络中的名称。但是,糟糕的实现和错误的配置通常会导致 Windows 机器向另一台机器发出 NetBios 请求。这些请求可能是由用户的 telnet、FTP 甚至 WWW 请求生成的。您可能希望启用不带 -o 标志的拒绝规则,以便您的日志文件不会充满这些非常常见的错误。我们的一位客户的根分区完全被 netbios 日志填满,导致其真正的日志记录停止运行,几乎导致服务器崩溃。
Jan 2 17:12:34 unreachable.xtdnet.nl 2 deny: TCP from 10.0.3.1.61007 to 194.229.18.29.80 seq 1471CB0, ack 0x0, win 8192, SYN此消息是由配置错误的主机引起的。10.*.*.* 范围内的 IP 号码保留用于局域网。我们发现此主机是 Internet 上配置错误的网络地址转换主机,它使用了来自本地网络地址转换网络的 IP 号码,而不是其真正的 Internet IP 号码。此错误配置通过许多其他路由器传播,然后才被我们的防火墙捕获。大型骨干 ISP 不会过滤掉虚假数据包,从而导致几乎从 Internet 上的任何位置到任何其他位置都容易进行 IP 欺骗。不要相信您的 ISP 会过滤掉任何东西;自己做。
Jan 20 06:57:33 unreachable.xtdnet.nl 14 deny: UDP from xx.yy.zz.aa.904 to 194.229.18.27.1112我们的防火墙证明了它在这次攻击中的价值。有人试图询问我们的 RPC 守护程序(udp 端口 111)我们正在运行哪些守护程序。即使攻击者仍然可以通过执行全面的端口扫描来找到大多数 RPC 服务,最好还是不要如此容易地向他们提供信息。几乎永远不需要与 Internet 上的服务器交换 RPC 服务。端口扫描很容易被发现,因为它们会在您的日志文件中留下所有过滤器规则的大量出现痕迹。
Jan 3 22:16:55 unreachable.xtdnet.nl 44 deny: TCP from xx.yy.zz.aa.17231 to 194.229.18.27.23 seq 7A3731D0, ack 0x0, win 49152, SYN这是另一个真正的防火墙命中。在我们收到几次上述针对我们的 RPC 服务器的攻击后,我们禁用了此主机。由于此特定站点的邮局局长没有回应,我们阻止了该主机对所有端口的访问。
Feb 4 09:10:17 polly.xtdnet.nl kernel: IP fw-in deny eth1 UDP 0.0.0.0:68 255.255.255.255:67 L=328 S=0x00 I=4 F=0x0000 T=60端口 68 是 bootp (DHCP)。某台机器正在广播并请求 bootp 服务器。这可能是 Win95 计算机,甚至是需要 IP 号码来支持 SNMP 的智能 HUB。(这让我们困惑了好几个月。)
Jan 27 09:47:00 masq.xtdnet.nl kernel: IP fw-in deny eth1 TCP 10.0.4.6:1992 204.162.96.21:80 L=48 S=0x00 I=2993 F=0x0040 T=255这台机器没有将网络地址转换主机定义为路由器,因此它试图变得聪明——但它仍然没有找到正确的网关。
Jan 28 12:23:50 masq.xtdnet.nl kernel: IP fw-in deny eth0 TCP 194.229.18.2:3128 194.229.18.36:2049 L=44 S=0x00 I=23859 F=0x0000 T=63为了理解发生了什么,我们需要深入研究 TCP/IP 的内部工作原理。所有连接都由源 IP、源端口、目标 IP 和目标端口的唯一组合标识。但是,为了找到众所周知的服务(例如 telnet、WWW 或缓存),通常的做法是使用特定端口。为了唯一标识与此类众所周知的服务的连接,会在本地机器上分配一个随机但唯一的端口。如果这台机器现在与另一台机器上的众所周知的服务建立连接,则保证具有可区分的 TCP/IP 连接。端口号低于 1024 的端口通常不分配为随机端口,因为它们经常被使用或保留用于众所周知的服务。
现在,让我们回顾一下日志条目。计算机 194.229.18.36 想要与端口 3128(缓存服务器)上的机器 194.229.18.2 建立连接。它首先向操作系统请求一个唯一的随机端口,并被分配了端口 2049。然后,它启动了与缓存服务器(194.229.18.2 端口 3128)的连接。缓存服务器通过将应答数据包发送回 194.229.18.36 端口 2049 来响应。但是 194.229.18.36 也使用防火墙规则,其规则之一是阻止所有尝试连接到 NFS 服务的尝试,与许多其他众所周知的服务不同,NFS 服务不位于 1024 以下的端口上,而是在端口 2049 上。因此,缓存服务器的响应被过滤掉了。您可以解决根据连接是否源自您的站点来区分连接的此问题。您可以通过 TCP 标头中是否设置了 SYN 或 ACK 标志来确定原点。
/sbin/ipfwadm -I -i deny -S 0.0.0.0/0 \ -D 0.0.0.0/0 2049 -P tcp -y -Weth0 -o
Jan 2 11:22:58 unreachable.xtdnet.nl 38 deny: TCP from 193.78.240.90.8080 to 194.229.18.2.1642 seq F72DA7C6, ack 0xED8FDEA1, win 31744, SYN ACK
这里也发生了类似的情况。端口 1642 由某台机器分配为随机唯一端口,但防火墙决定端口 1642 不良。Livingston Portmaster 软件使用此端口在 Unix 主机及其路由器/防火墙之间进行通信,这就是我们过滤掉这些端口的原因。
通常,尽量避免阻止高端口,如果您确实阻止了高端口,则仅对需要保护的机器阻止该端口。例如,仅为您的路由器和终端服务器阻止端口 1642,但为 Unix 服务器保持打开状态。然后,如果路由器/防火墙收到发往内部机器上端口 1642 的数据包,即使路由器本身的端口 1642 被阻止,它也会将其传递给该内部机器。
一个小的缺点是我们向潜在的黑客泄露了一些信息。他们可以检查您的所有 IP 号码,以查看哪些是路由器、防火墙或与路由器或防火墙通信的 Unix 主机;但是,他们通常也可以通过其他方式找到相同的信息。例如,traceroute 命令会产生大量关于哪些机器用于数据包传输的信息,因此这些机器要么是路由器,要么是防火墙,要么两者兼而有之。您也可以使用前面示例中提到的 -y 选项。并非所有硬件路由器/防火墙都提供这些选项。
大多数对您的防火墙的攻击都是简单的探测。这类似于一个人尝试您的门把手以查看门是否已锁。上述防火墙规则应保护您免受这些攻击,而不会出现太多问题。
如果有人试图了解更多信息,而不仅仅是您的门是否已锁怎么办?如果有人似乎对您真正感兴趣怎么办?这种情况的第一个迹象将是来自少量主机或网络的防火墙命中次数突然增加。您的第一步应该是联系这些系统的系统管理员。如果您在这个阶段真的感到偏执,请不要发送电子邮件给邮局局长,也不要相信他们网站上的技术支持电话号码。在纸质电话簿中查找公司的总机号码,或拨打接线员寻求帮助。一旦您与公司取得联系,请告诉他们正在发生的事情,并向他们提供尽可能多的信息。如果您可以信任站点的管理,这通常可以保证攻击会停止。
只有极少数情况下,这种方法会失败——要么是因为公司的管理员与攻击串通,要么是因为攻击来自一个大型提供商,该提供商允许其用户访问 Unix shell。对于这些提供商而言,仅从防火墙日志的时间戳来追踪滥用者是不可能的,因为当时会有数十人登录。
到目前为止,这种情况只发生在我们身上一次。我们怀疑管理部门本身对我们站点的探测和黑客攻击企图负责。我们决定暂时让黑客穿过我们的防火墙,以便我们可以收集更多关于他们正在做什么的信息。
我们使用了两种工具来收集信息。首先,我们将正常的 Internet 超级服务器 (inetd) 替换为 xinetd。此版本的 inetd 具有记录大量有价值信息的选项。其次,我们需要运行特殊版本的 nologin 程序,以确保连接保持足够长的时间,以便我们发出 ident 探测。
/* nologin.c */ main() { printf("You have no login on this machine.\n"); sleep(60); }
我们在 /etc/xinetd.conf 中启用了要探测的服务。例如,要设置远程登录 shell rsh
service shell { socket_type = stream protocol = tcp wait = no user = nobody server = /bin/nologin }我们为所有服务启用了 ident 查找和远程主机日志记录
defaults { log_type = FILE /var/log/xinetd.log log_on_success = HOST USERID log_on_failure = HOST RECORD USERID ATTEMPT instances = 10 }最后,我们准备好在主机上为这些伪服务打开防火墙。
请注意,所描述的日志记录级别非常高——您的日志文件将非常大。但不要试图禁用真实服务的日志记录。例如,我们记录了一些看似无害的 finger 请求,随后在几个场合中来自另一台机器的探测。负责探测的机器非常不提供信息。但是,这位黑客犯了一个错误,即首先使用他的普通机器执行 finger 命令,以查看是否有任何系统管理员登录,然后他才从安全系统开始探测。他的常规机器正在运行 ident 守护程序,因此我们的日志记录了他的用户名。
正如“死亡之 Ping”示例所见,防火墙可以成为救命稻草。此外,我们已经看到,一旦您了解 TCP/IP 协议的工作原理,配置防火墙就相当容易。
最近访问我们的一位客户时,我简要地看了一下他们的两个防火墙。两个防火墙的正常运行时间均为 108 天。自从安装 Alan Cox 的 ping 补丁 Linux 内核版本 2.0.23 以来,它们就一直在运行。一个防火墙,保护主 Internet 服务器,记录了四次尝试发送超大 ping 数据包的尝试。它还阻止了一些试图使用非法 IP 号码的学生的访问(无论是错误还是故意的,尚不清楚)。它还记录了各种配置错误的机器发送虚假 IP 流量的情况。保护其主 Internet 服务器(也处理完整的 Usenet 新闻源)的防火墙已路由了近 1 TB 的 IP 流量。他们的防火墙已被证明是他们网络安全的一个非常稳定且有价值的补充,在网络安全方面,他们必须担心不信任内部机器以及外部机器,并且整个综合大楼内以太网电缆的完全控制无法得到保证。
