下一页 上一页 目录

5. 杂项。

本节包含所有我无法归入上述结构的信息和常见问题解答。

5.1 如何组织你的防火墙规则

这个问题需要一些思考。你可以尝试组织它们以优化速度(对于最常见的包最小化规则检查的数量)或提高可管理性。

如果你有一个间歇性链接,比如 PPP 链接,你可能想在启动时将输入链中的第一条规则设置为 `-i ppp0 -j DENY',然后在你的 ip-up 脚本中加入类似这样的内容

# Re-create the `ppp-in' chain.
ipchains-restore -f < ppp-in.firewall

# Replace DENY rule with jump to ppp-handling chain.
ipchains -R input 1 -i ppp0 -j ppp-in

你的 ip-down 脚本看起来会像这样

ipchains -R input 1 -i ppp0 -j DENY

5.2 什么不应该被过滤掉

在你开始过滤掉所有你不想要的东西之前,有些事情你应该注意。

ICMP 包

ICMP 包被用于(除其他外)指示其他协议(例如 TCP 和 UDP)的失败。特别是 `destination-unreachable' 包。阻止这些包意味着你将永远不会收到 `Host unreachable' 或 `No route to host' 错误;任何连接都只会等待永远不会到来的回复。这很令人恼火,但很少是致命的。

更糟糕的问题是 ICMP 包在 MTU 发现中的作用。所有好的 TCP 实现(包括 Linux)都使用 MTU 发现来尝试找出可以到达目的地而不会被分片的最大的包(分片会降低性能,尤其是在偶尔丢失分片时)。MTU 发现的工作原理是发送设置了 "Don't Fragment" 位的包,然后在收到指示 "Fragmentation needed but DF set" 的 ICMP 包(`fragmentation-needed')时发送更小的包。这是一种 `destination-unreachable' 包,如果永远没有收到它,本地主机将不会降低 MTU,并且性能将是极差的或不存在的。

请注意,阻止所有 ICMP 重定向消息(类型 5)是很常见的;这些可以用于操纵路由(尽管好的 IP 协议栈有保护措施),因此通常被认为有点风险。

TCP 连接到 DNS(域名服务器)

如果你试图阻止出站 TCP 连接,请记住 DNS 并不总是使用 UDP;如果来自服务器的回复超过 512 字节,客户端将使用 TCP 连接(仍然连接到端口号 53)来获取数据。

这可能是一个陷阱,因为如果你不允许这样的 TCP 传输,DNS 将“大部分工作”;如果你这样做,你可能会遇到奇怪的长延迟和其他偶尔的 DNS 问题。

如果你的 DNS 查询总是指向相同的外部源(直接通过在 /etc/resolv.conf 中使用 nameserver 行,或者通过使用转发模式的缓存域名服务器),那么你只需要允许从本地 domain 端口(如果使用缓存域名服务器)或从高端口(> 1023)(如果使用 /etc/resolv.conf)到该域名服务器上 domain 端口的 TCP 连接。

FTP 噩梦

经典的包过滤问题是 FTP。FTP 有两种模式;传统的一种称为主动模式,而较新的一种称为被动模式。Web 浏览器通常默认使用被动模式,但命令行 FTP 程序通常默认使用主动模式。

在主动模式下,当远程端想要发送文件(甚至 lsdir 命令的结果)时,它会尝试打开到本地机器的 TCP 连接。这意味着你不能在不破坏主动 FTP 的情况下过滤掉这些 TCP 连接。

如果你有使用被动模式的选项,那就很好;被动模式使数据连接从客户端到服务器,即使是对于传入数据也是如此。否则,建议你只允许到 1024 以上端口的 TCP 连接,而不允许 6000 到 6010 之间的端口(6000 用于 X-Windows)。

5.3 过滤掉死亡之 Ping

Linux 机器现在对著名的死亡之 Ping 免疫,死亡之 Ping 涉及发送一个非法的大型 ICMP 包,该包会溢出接收方 TCP 协议栈中的缓冲区并导致混乱。

如果你正在保护可能易受攻击的机器,你可以简单地阻止 ICMP 分片。正常的 ICMP 包不够大,不需要分片,所以你不会破坏任何东西,除了大的 ping。我听说(未经证实)一些系统只需要超大 ICMP 包的最后一个分片来破坏它们,所以不建议只阻止第一个分片。

虽然我见过的漏洞利用程序都使用 ICMP,但没有理由 TCP 或 UDP 分片(或未知协议)不能用于此攻击,因此阻止 ICMP 分片只是一个临时的解决方案。

5.4 过滤掉 Teardrop 和 Bonk 攻击

Teardrop 和 Bonk 是两种攻击(主要针对 Microsoft Windows NT 机器),它们依赖于重叠的分片。让你的 Linux 路由器进行分片重组,或者不允许所有分片到达你的易受攻击的机器是其他选择。

5.5 过滤掉分片炸弹

据说一些不太可靠的 TCP 协议栈在处理大量包分片时存在问题,当它们没有收到所有分片时。Linux 没有这个问题。你可以过滤掉分片(这可能会破坏合法用途),或者在编译内核时将 `IP: always defragment' 设置为 `Y'(仅当你的 Linux 机器是这些包的唯一可能路由时)。

5.6 更改防火墙规则

在更改防火墙规则时,涉及到一些时序问题。如果你不小心,你可能会在更改进行到一半时让数据包通过。一种简单的方法是执行以下操作

# ipchains -I input 1 -j DENY
# ipchains -I output 1 -j DENY
# ipchains -I forward 1 -j DENY

... make changes ...

# ipchains -D input 1
# ipchains -D output 1
# ipchains -D forward 1
# 

这会在更改期间丢弃所有数据包。

如果你的更改仅限于单个链,你可能想要创建一个包含新规则的新链,然后用指向新链的规则替换(`-R')指向旧链的规则:然后你可以删除旧链。这种替换将原子性地发生。

5.7 如何设置 IP 欺骗保护?

IP 欺骗是一种技术,其中主机发送声称来自另一主机的包。由于包过滤根据此源地址做出决策,因此 IP 欺骗用于欺骗包过滤器。它也用于隐藏使用 SYN 攻击、Teardrop、死亡之 Ping 等的攻击者的身份(如果你不知道它们是什么,请不要担心)。

防止 IP 欺骗的最佳方法称为源地址验证,它由路由代码完成,而不是完全由防火墙完成。查找名为 /proc/sys/net/ipv4/conf/all/rp_filter 的文件。如果此文件存在,那么在每次启动时启用源地址验证是适合你的解决方案。为此,在你的 init 脚本中的某个位置插入以下行,在任何网络接口初始化之前

# This is the best method: turn on Source Address Verification and get
# spoof protection on all current and future interfaces.
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
  echo -n "Setting up IP spoofing protection..."
  for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
      echo 1 > $f
  done
  echo "done."
else
  echo PROBLEMS SETTING UP IP SPOOFING PROTECTION.  BE WORRIED.
  echo "CONTROL-D will exit from this shell and continue system startup."
  echo
  # Start a single user shell on the console
  /sbin/sulogin $CONSOLE
fi

如果你不能这样做,你可以手动插入规则以保护每个接口。这需要了解每个接口。2.1 内核会自动拒绝声称来自 127.* 地址的包(保留用于本地环回接口,lo)。

例如,假设我们有三个接口,eth0eth1ppp0。我们可以使用 ifconfig 来告诉我们接口的地址和网络掩码。假设 eth0 连接到网络 192.168.1.0,网络掩码为 255.255.255.0,eth1 连接到网络 10.0.0.0,网络掩码为 255.0.0.0,ppp0 连接到互联网(允许除保留的私有 IP 地址之外的任何地址),我们将插入以下规则

# ipchains -A input -i eth0 -s ! 192.168.1.0/255.255.255.0 -j DENY
# ipchains -A input -i ! eth0 -s 192.168.1.0/255.255.255.0 -j DENY
# ipchains -A input -i eth1 -s ! 10.0.0.0/255.0.0.0 -j DENY
# ipchains -A input -i ! eth1 -s 10.0.0.0/255.0.0.0 -j DENY
# 

这种方法不如源地址验证方法好,因为如果你的网络发生变化,你必须更改你的防火墙规则以保持同步。

如果你正在运行 2.0 系列内核,你可能还想保护环回接口,使用类似这样的规则

# ipchains -A input -i ! lo -s 127.0.0.0/255.0.0.0 -j DENY
#

5.8 高级项目

我编写了一个用户空间库,它包含在名为 libfw' 的源代码发行版中。它使用 IP Chains 1.3 及以上版本的功能,将数据包复制到用户空间(使用 IP_FIREWALL_NETLINK 配置选项)。

标记值可用于指定数据包的服务质量参数,或指定数据包应如何进行端口转发。我从未使用过这两者,但如果你想写关于它的内容,请联系我。

诸如状态检测(我更喜欢术语动态防火墙)之类的东西可以使用此库在用户空间中实现。其他巧妙的想法包括通过在用户空间守护进程中进行查找来按用户控制数据包。这应该很容易。

SPF:状态数据包过滤

ftp://ftp.interlinx.bc.ca/pub/spf 是 Brian Murrell 的 SPF 项目的站点,该项目在用户空间中进行连接跟踪。它为低带宽站点增加了显著的安全性。

目前文档很少,但这是 Brian 回答一些问题的邮件列表帖子

> I believe it does exactly what I want: Installing a temporary
> "backward"-rule to let packets in as a response to an
> outgoing request.

Yup, that is exactly what it does.  The more protocols it
understands, the more "backward" rules it gets right.  Right
now it has support for (from memory, please excuse any errors
or omissions) FTP (both active and passive, in and out), some
RealAudio, traceroute, ICMP and basic ICQ (inbound from the ICQ
servers, and direct TCP connections, but alas the secondary
direct TCP connections for things like file transfer, etc. are
not there yet)

> Is it a replacement for ipchains or a supplement?

It is a supplement.  Think of ipchains as the engine to allow
and prevent packets from travelling across a Linux box.  SPF is
the driver, constantly monitoring traffic and telling ipchains
how to change it's policies to reflect the changes in traffic
patterns.

Michael Hasenstein 的 ftp-data hack

SuSE 的 Michael Hasenstein 编写了一个内核补丁,该补丁向 ipchains 添加了 ftp 连接跟踪。目前可以在 http://www.suse.de/~mha/patch.ftp-data-2.gz 找到它

5.9 未来增强

防火墙和 NAT 已经在 2.4 中重新设计。计划和讨论可在 netfilter 列表(参见 http://lists.samba.org)上找到。这些增强功能应该可以解决许多突出的可用性问题(真的,防火墙和伪装不应该这么难),并允许增长以实现更灵活的防火墙。


下一页 上一页 目录