我的防火墙所连接到的网络上还连着DHCP服务器。如果用上面的记录方法的话,每个DHCP包都得记录。由于DHCP传输,网络非常忙碌,因此它会让记录里有很多不必要的信息。因此,在规定记录规则前,我插入了如下规则:
iptables -A INPUT -i $IF_PUB -p udp --sport bootps -j DROP
这句使系统丢弃所有来自DHCP源端口的UDP传输。在记录前加上这条规则,可以将DHCP传输从记录范围内除去。如果还有其他传输干扰你的记录,并且与你要监听的东西毫无关联,那么就在记录规则前添加类似规则。
应用策略之前
我的脚本的下一段反映了我上面所说的哲学问题。如果不再添加规则,那么剩余的数据包就会满足过滤链的策略,因而全部被丢弃。但是我已经打开了路由器上的端口,因此即使放弃剩余数据包,也不会影响整个过程。这也是我允许ping的一部分原因。因此,我也选择做个好的TCP顺民:
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
余下的任何TCP协议的数据包都将被拒绝,发送方会收到一条TCP重置消息(RST)。这是连接到一个没有listening服务的端口时,TCP协议的正常反应。
这样之后,剩余的所有包都由策略来处理以及丢弃。我还应当添加一条规则来以类似的标准方法处理UDP:返回一个ICMP端口无法到达的消息。
拦截特殊的问题源
你也许会发现你的防火墙或其他记录显示,你的主机正被一些主机以不被允许的方式反复访问。例如,也许有个主机用你的主机不具备的请求来刺探你的网络服务器。邮件过滤可以处理很多来自某个源头的未被请求的传输。可以说,你能用NetFilter将它们都拦截下来。这样做的代价是这些源就无法正常使用你的服务了。我觉得这个代价可以忍受,毕竟这些源是试图攻击我的。
我在规则链的最顶端放置拦截规则。这样即使有对这种传输不起作用的规则也不会有什么问题了,在他们能处理之前,拦截规则过滤掉的传输会最先被丢弃。另外,拦截规则的优先级要足够高,这样它们就不会被其他能够识别传输并改道发送它们的规则所扰乱。例如,它拦截所有来自特定IP地址的传输,而比它高优先级的规则却以另一种理由接受同一个传输(比如,smtp认可)。
我的防火墙上有3套拦截规则。一个是针对协议的,一个针对源网络而最后一个是针对源主机的。我最后加的针对协议的这个规则是用来拒绝那些已知的被恶意利用的协议。例如,我完全屏蔽了IRC,因为它频繁地被用来控制僵尸网络,而且我现在也用不上IRC:
iptables -A INPUT -p tcp --dport irc -j DROP iptables -A INPUT -p udp --dport irc -j DROP iptables -A INPUT -p tcp --dport irc-serv -j DROP iptables -A INPUT -p udp --dport irc-serv -j DROP iptables -A INPUT -p tcp --dport ircs -j DROP iptables -A INPUT -p udp --dport ircs -j DROP
以上语句拒绝TCP,UDP IRC,IRC服务器以及源IRC传输。
以下是一个拦截特定IP地址的主机的规则:
iptables -A INPUT -i $IF_PUB -s 10.220.231.236 -j REJECT --reject-with icmp-host-prohibited
这条规则拒绝那些到达公网接口的、来自IP地址10.220.231.236的传输。我是通过回应说主机被封锁了来拒绝这些传输,你也可以只是丢弃这些数据包,对问题主机不做回应。
拦截网络也是类似的:
iptables -A INPUT -i $IF_PUB -s 10.67.232.0/24 -j REJECT --reject-with icmp-net-prohibited
监视NetFilter防火墙
现在防火墙配置好了,我们得考虑下怎样监视它以防止出现问题。我已经提到记录日志是个方法,但是iptables可以用来批量统计各种各样的规则:
iptables -L -v iptables -t nat -L -v
第一条命令提供(默认)过滤表里每条链中规则的详细列表。该列表提供了那些规则要点以及容量。第二条命令则提供的NAT表中的相同内容。以下是过滤表中输出的范例:
Chain INPUT (policy DROP 2707 packets, 1083K bytes) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- any any anywhere anywhere tcp dpt:irc 0 0 DROP udp -- any any anywhere anywhere udp dpt:irc 0 0 DROP tcp -- any any anywhere anywhere tcp dpt:irc-serv 0 0 DROP udp -- any any anywhere anywhere udp dpt:irc-serv 0 0 DROP tcp -- any any anywhere anywhere tcp dpt:ircs 0 0 DROP udp -- any any anywhere anywhere udp dpt:ircs 0 0 REJECT all -- eth1 any 10.67.232.0/24 anywhere reject-with icmp-net- prohibited 0 0 REJECT all -- eth1 any 10.220.231.236 anywhere reject-with icmp- host-prohibited 2169 524K ACCEPT all -- lo any anywhere anywhere 226K 38M ACCEPT all -- eth0 any 192.168.1.0/24 anywhere 224K 26M ACCEPT all -- eth1 any anywhere anywhere state RELATED,ESTABLISHED 0 0 ACCEPT icmp -- any any anywhere anywhere icmp echo-reply 0 0 ACCEPT icmp -- any any anywhere anywhere icmp destination- unreachable 0 0 ACCEPT icmp -- any any anywhere anywhere icmp time-exceeded 14647 640K ACCEPT icmp -- any any anywhere anywhere icmp echo-request limit: avg 1/sec burst 5 9 432 ACCEPT tcp -- eth1 any anywhere 10.0.0.1 tcp dpt:2202 4350 1459K DROP udp -- eth1 any anywhere anywhere udp spt:bootps 3576 1103K LOG all -- eth1 any anywhere anywhere LOG level warning prefix `INPUT '' 950 47785 REJECT tcp -- any any anywhere anywhere reject-with tcp- reset Chain FORWARD (policy DROP 7 packets, 1400 bytes) pkts bytes target prot opt in out source destination 1302K 681M ACCEPT all -- eth1 eth0 anywhere anywhere state RELATED,ESTABLISHED 1229K 253M ACCEPT all -- eth0 eth1 anywhere anywhere 411 21920 ACCEPT tcp -- eth1 any anywhere anywhere state NEW,RELATED,ESTABLISHED tcp dpt:smtp 1 48 ACCEPT tcp -- eth1 any anywhere anywhere state NEW,RELATED,ESTABLISHED tcp dpt:pop3 681 39308 ACCEPT tcp -- eth1 any anywhere anywhere state NEW,RELATED,ESTABLISHED tcp dpt:http 0 0 LOG all -- any any anywhere anywhere LOG level warning prefix `FORWARD '' Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2169 524K ACCEPT all -- any lo anywhere anywhere 246K 23M ACCEPT all -- any eth0 anywhere 192.168.1.0/24 220K 43M ACCEPT all -- any eth1 anywhere anywhere 0 0 LOG all -- any eth1 anywhere anywhere LOG level warning prefix `OUTPUT ''