B. 常见问题与解答
B.1. 模块装载问题
装载模块时,你可能会遇到几个问题,比如,有错误提示说明没有你指定名字的那种模块:
insmod: iptable_filter: no module by
that name found
这个提示是无关紧要的,因为那些模块很有可能已经被静态地编译进内核了。当你遇到这个信息时,这是你应该首先想到的。至于是否真的如我们所想,最简 单的测试方就是敲一个用到那个模块功能的命令试试。对于上面的情况,可能是filter表没有装入,从而就没有相应的功能,当然不能使用filter表 了。为了检查 filter表是否装入,可以用下面的命令来试试:
iptables -t filter -L
这个命令会输出filter表里所有的链,或者是运行失败,给出错误提示信息。如果一切正常,输出结果类似下面的情况,当然,这还要看你是否已经在filter表里加入了规则(译者注:在这个例子里,表是空的)。
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
如果你确实没有装载filter表,得到的就是如下信息:
iptables
v1.2.5: can't initialize iptables table `filter': Table /
does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
这个问题就有些严重了,从此提示中我们能得到两个信息:第一,我们确实没有把相应的功能编译进内核里;第二,在模块一般应在的目录中没有找到这个模块。这意味着问题是,你或者忘记了装载想用的模块,或者没有用depmod -a命令更新模块数据库,或者没有把相应的功能编译进内核(不论是静态的还是作为模块)。当然还可能是其他原因,但这些是主要的,不管怎样,大部分原因是很容易解决的。比如,第一个问题可以简单地通过在内核源码目录里运行make modules_install 命令来解决,这当然是有前提的,就是源码已经编译(compile)而且模块已经构建(build)。第二个问题的解决办法也很简单,只要运行一下depmod -a命令,之后再看看能否正常工作即可。第三个问题有点超出我们的范围了,而且这个问题或多或少会让你感到发晕。更多的信息可以在Linux文档计划里找到。
在运行iptables时,你还可能得到另外一个错误信息:
iptables: No chain/target/match by that name
这说明你要用的链或target、或match不存在,原因有很多,但最普遍的是你拼错了名字。当你想使用一个不可用的模块时也会产生这种错误。模 块之所以不可用,可能是因为你没有装载正确的模块,或者内核里不包含那个模块,或者是iptables自动装载模块时失败了。通常,你不止应该考虑上面提 到的所有解决办法,还要考虑规则中target的拼写错误,或者其他的原因。
B.2. 未设置SYN的NEW状态包
iptables有个“特点”没有被很好地给以说明,所以很多人(当然,也包括我)都忽视了它。这个“特点”就是:如果你使用状态NEW,那么未设置SYN的包也会通过防火墙。之所以有这个特点,是因为在某些情况下,我们想把那样的包看作某个(比如是和另一个防火墙有关的)已处于ESTABLISHED状态的连接的一部分。这个特点使拥有两个或更多的防火墙协同工作成为可能,而且可使数据在服务器间无丢失的传输,如辅助防火墙可以接受子网的防火墙的操作。但它也会导致这样的事情:状态 NEW会允许几乎所有的TCP连接进入,而不管是否有3次握手。为了处理这个问题,我们需要在防火墙的 INPUT链、OUTPUT链和FORWARD链加入如下规则(译者注:此规则作者称为“NEW not SYN rules”,下一小节还会提到):
$IPTABLES -A
INPUT -p tcp ! --syn -m state --state NEW -j LOG /
--log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
警告,在Netfilter/iptables项目中,这个特点所拥有的行为缺少文档说明,更明确的说,在你的防火墙上,它是一个很不安全的因素。 |
注意,这个规则用于microsoft的TCP/IP(微软实现的TCP/IP就是不行,至少现在不行)产生的包时还是有些问题。如果包是由microsoft的产品生成的,且被标为状态NEW,那么就会被此规则记录然后丢弃。看起来规则工作很正常啊,是吧。但问题就出在这儿了,因为连接无法中断了。这个问题出现在关闭连接时,在最后一个包即FIN/ACK包发出后,Netfilter的 状态机制就会关闭连接、删除连接跟踪表里的相应记录。但就在这时,Microsoft那不完善的程序会发送另外一个包,这个包就是那种未设置SYN且被认 为是NEW状态的包,因此它就会被上面的规则匹配。换句话说,就是对这个规则不需要过于关注,如果你很在意它,就在规则里加入选项--log-headers吧。这样,你就可以把包头记录下来,从而可以更好地了解相应的包。
对于这个规则,还有一些已知的问题。比如,某个连接(比如是从LAN发出的)已经连接到防火墙,而且有个脚本要在启动PPP时激活。当你启动PPP 连接时,刚才提到的那个连接可能就会被干掉(be killed)。当然,这只会在特定的情况下才能发生,就是你把conntrack和nat作为模块运行,并且每次运行那个脚本时这两个模块都要被装入和 卸载。如果你在防火墙之外的机子上运行telnet,而且又通过这个telnet连接运行脚本rc.firewall.txt,也会导致上面的问题。为了能简单地表达这个问题,你先准备一个telnet连接,或其他的流连接,再运行连接跟踪模块,然后装入上面的规则,最后,试着用telnet client或daemon发 送一些数据。效果应该出来了,连接跟踪代码会认为这个连接是非法的,因为在此之前,它没有看到任何方向有包发出,更为严重的是现在连接上有了未设置SYN 的包,因为刚才由telnet client或daemon发出的包肯定不是这个连接的第一个包。因此,上面的规则就起作用了,也就是说,这个包会被记录下来,然后被无情地扔掉,从而连 接就会中断。
B.3. NEW状态的SYN/ACK包
某些,TCP欺骗攻击所用的技术叫做序列号预测(Sequence Number Prediction)。在这类攻击中,攻击者利用另一台机子的IP访问攻击对象(译者注:这就是为什么叫欺骗的原因了,攻击者是想假冒另一台被攻击对象 信任的机子,以达到欺骗攻击对象的目的),然后再试着预测攻击对象使用什么序列号。
我们来看看典型的使用序列号预测技术的欺骗是如何实现的,参与者:攻击者[A](attacker)试图假装另一台机子[O](other host)向受害者[V](victim)发送数据。
-
[A]以[O]的IP为源地址向[V]发SYN。
-
[V]向[O]回应SYN/ACK。
-
现在,若[O]以RST回应这个未知的SYN/ACK,攻击就失败了,但如果[O]已经没有这个能力了呢?比如它早已被另外的攻击(如SYN flood)降服,或者被关闭,或者它的RST包被防火墙拒绝。
-
如果[O]没能破坏这条连接,而且[A]猜对了序列号,那它就能以[O]的身份和[V]交谈了。
只要我们没能在第三步以RST回应那个未知的SYN/ACK包,[V]就会被攻击,而且我们还会被连累(译者注:因为我们本身也被攻击了,而且还可 能会成为攻击者的替罪羊被起诉,呜呜,好惨)。所以,为安全起见,我们应该以正确的方式向[V]发送一个RST包。如果我们使用类似“NEW not SYN rules”(译者注:在上一小节中)的规则,SYN/ACK包就可以被丢弃了。因此,我们在bad_tcp_packets链中加入了如下规则:
iptables -A
bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK /
-m state --state NEW -j REJECT --reject-with tcp-reset
这样,你想成为上面那个[O]的机会就很少了(译者注:作者好幽默啊,我们可不想成为被别人利用的对象),而且这条规则在绝大部分情况下是安全的, 不会有什么副作用,但多个防火墙要协同工作的情况要除外。那种情况下,防火墙之间会经常传递、接受包或流,有了这条规则,有些连接可能会被阻塞,即使是合 法的连接。这条规则的存在还产生了另外一问题,就是有几个portscan(端口扫描器)会看到我们的防火墙,但好在仅此而已。
B.4. 使用私有IP地址的ISP
我的一位朋友告诉我说有些事我完全忘记了,从那时起,我就把这一节加上了。你刚上网时连接的网络是 ISP提供的,但某些愚蠢的ISP在那个网络里使用的是私有地址,而那是IANA专 门分配给局域网使用的。Swedish Internet Service Provider和电话垄断企业Telia就是这样做的,例如在DNS服务器上,他们使用的IP地址段就是10.x.x.x。我们最容易遇到的问题是,在 这个脚本里,为了防止被欺骗,不允许从10.x.x.x发出的连接来访问我们。不幸的是,对于上面的例子,为了DNS能正常地被访问,我们不得不把规则的 放宽松一些。也就是说,我们或者在刚才提到的那条防止欺骗的规则上面增加一条规则(如下),或者是把那条规则注释掉:
/usr/local/sbin/iptables -t nat -I PREROUTING -i
eth1 -s /
10.0.0.1/32 -j ACCEPT
我愿意对这些ISP再多费些唇舌。这些IP地址不是为了让你象这样愚蠢的使用而分配给你的,至少我知道不是这样的。对于一个大集团的站点或者是我们自己的家庭网络来说,这样用是很合适的,但你不能只因为你们的一些原因就强迫我们把自己公示于天下。
B.5. 放行DHCP数据
一旦你了解DHCP是如何工作的,就会知道这其实是一个很简单的任务。但你必须小心处理到底让谁进入、不让谁进入。首先,我们要明白DHCP是工作 在UDP协议之上的,所以,UDP协议是我们期望的第一个条件。其次,我们应该检查是从那个接口接收和发送请求的。例如,如果我们设置了DHCP使用接口 eth0,那就要阻塞 eth1上的DHCP请求。为了让规则再详细些,我们只需打开(allow)DHCP实际使用的UDP端口,一般都是67和 68。这两个端口是标准定义,我们就用它们来匹配被允许的包。现在,规则应该是这个样子的:
$IPTABLES -I INPUT -i $LAN_IFACE -p udp --dport 67:68 --sport /
67:68 -j ACCEPT
注意,现在我们能够接受所有来自和发往UDP端口67、68的数据,好像不太安全,但这并不是多大的问题,因为这条规则只允许从67或68端口连接 的主机才能访问。当然,此规则还可以更严谨一些,但也应该足够接受所有的DHCP请求和更新,而不至于需要在防火墙上开一个大洞。如果你很在意现在的规则 是否很宽松,你当然可以写一个限制条件更紧的。
B.6. 关于mIRC DCC的问题
mIRC使用一个特殊的设定,它可以使mIRC连接穿过防火墙,也可以使DCC连接能在防火墙不了解它的情况下正常工作。如果此选项和 iptables还有ip_conntrack_irc模块与ip_nat_irc模块一起使用,那mIRC就不能工作了。问题在于mIRC会自动对包进 行NAT操作,这样当包到达防火墙后,防火墙就完全不知道该对包做什么了,也不知道该怎么做。如果是防火墙来处理,它只是简单地用自己的IP去询问IRC 服务器,然后用那个地址发送DCC请求。mIRC不希望防火墙自作聪明地以这种方式代替自己来处理这个包。
打开“I am behind a firewall”(我在防火墙后)这个配置选项并且使用ip_conntrack_irc和 ip_nat_irc模块,会导致Netfilter建立包含“Forged DCC send packet”的记录。
最简单的解决办法是不要选中mIRC的那个选项而让iptables来做这些工作。意思就是要明确地告诉mIRC,它不是在防火墙后面的。