我有一台运行 Ubuntu 12.04 的服务器。
几次重启后,我开始注意到 iptables 规则在重启时增加了一倍。
这是我重启后得到的结果(添加了换行符):
$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-apache-overflows
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-overflows
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p udp -m udp --dport 53 -m hashlimit --hashlimit-above 20/sec --hashlimit-burst 100 --hashlimit-mode srcip --hashlimit-name DNS --hashlimit-htable-expire 1 --hashlimit-srcmask 28 -j DROP
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p udp -m udp --dport 53 -m hashlimit --hashlimit-above 20/sec --hashlimit-burst 100 --hashlimit-mode srcip --hashlimit-name DNS --hashlimit-htable-expire 1 --hashlimit-srcmask 28 -j DROP
-A fail2ban-apache-overflows -j RETURN
-A fail2ban-ssh -j RETURN
两次应用的四条规则应该从 if-pre-up.d 中加载:
$ cat /etc/network/if-pre-up.d/iptablesload
#!/bin/bash
# Flush iptables
/sbin/iptables -F
#MySQL locally
/sbin/iptables -A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
# Mysql access allowed from work
/sbin/iptables -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -p tcp -m tcp --dport 3306 -j REJECT --reject-with icmp-port-unreachable
# Rate limit on DNS requests
/sbin/iptables -A INPUT -p udp -m udp --dport 53 -m hashlimit --hashlimit-above 20/sec --hashlimit-burst 100 --hashlimit-mode srcip --hashlimit-name DNS --hashlimit-htable-expire 1 --hashlimit-srcmask 28 -j DROP
exit 0
我尝试添加这个清理脚本,以确保当服务器宕机时所有内容都会被清除:
$ cat /etc/network/if-post-down.d/iptablesunload
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t nat -F
/sbin/iptables -t nat -X
/sbin/iptables -t mangle -F
/sbin/iptables -t mangle -X
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
但这并没有什么区别。
重新应用所有内容可以清除混乱:
$ sudo /etc/network/if-post-down.d/iptablesunload; sudo /etc/network/if-pre-up.d/iptablesload; sudo service fail2ban restart; sudo iptables -S
Stopping firewall and allowing everyone...
* Restarting authentication failure monitor fail2ban [ OK ]
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-apache-overflows
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-overflows
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p udp -m udp --dport 53 -m hashlimit --hashlimit-above 20/sec --hashlimit-burst 100 --hashlimit-mode srcip --hashlimit-name DNS --hashlimit-htable-expire 1 --hashlimit-srcmask 28 -j DROP
-A fail2ban-apache-overflows -j RETURN
-A fail2ban-ssh -j RETURN
我添加了回声来iptablesload
跟踪脚本的运行时间:
echo "$PPID: `ps -ocommand= -p $PPID`" > /tmp/loading_iptables.`date +%F_%H:%M:%S.%N`
重新启动后,我现在可以验证脚本是否运行多次:
$ ls /tmp/
loading_iptables.2014-06-30_09:58:06.732185289
loading_iptables.2014-06-30_09:58:06.766291579
$ cat /tmp/*
729: run-parts /etc/network/if-pre-up.d
782: run-parts /etc/network/if-pre-up.d
这就引出了两个问题:
- 为什么脚本运行两次?
- 为什么执行之间没有
iptables -F
清理规则?
答案1
您的规则可能正在针对一个网络设备和环回设备运行。
要排除环回设备,请将其添加到脚本顶部,就在 shebang 下方,用于检查当前启动的设备不是环回“lo”:
[ "$IFACE" != "lo" ] || exit 0
或者确保规则仅针对指定设备运行(例如 eth0):
[ "$IFACE" == "eth0" ] || exit 0