最近把网站的服务器从apache切换到nginx,切换的一个目的是解决dashboard开启非常慢的问题。但是等我切换完之后点dashboard仍旧很慢,我的第一反应是dashboard打开异常慢的原因并不在应用服务器。联系到我之前在服务器上aptitude install less没成功,我突然明白dashboard打开慢和aptitude install失败的原因有可能是同一个,就是iptables禁止了访问外部的HTTP/HTTPS/DNS请求。
为了验证这个问题,我把iptables中的规则通过iptables -F清理掉并用iptables -L -n -v确认之后再打开dashboard,发现打开比以前快多了。知道问题所在之后,接下来就是修正iptables的规则,因为考虑到安全,服务器还是需要iptables的。
就个人经验,通过ssh修改iptables因为有可能把自己ban掉所以用非ssh比如vnc或者在物理机边上修改更好,如果实在没条件的话,可以考虑《Linux Firewall 3rd》中提到的一种方法:服务器运行定时清除iptables的任务。个人采用的就是定时任务的方法,因为最近VPS的VNC没法用。
个人只用过简单的定时任务:学习网站备份用的是在 /etc/cron.daily/ 中放置脚本的方式。本次依样画葫芦看了下,cron开头的文件夹最短的间隔是一小时,也就是 /etc/cron.hourly/ 。理论上可以在这个文件夹中放置脚本,执行间隔是一小时。不过我还是希望间隔更短些,所以找了别的文件,就是/etc/crontab。经过一番尝试,我在最后添加了清除iptables规则的定时任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# /etc/crontab: system-wide crontab # Unlike any other crontab you don’t have to run the `crontab’ # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run–parts —report /etc/cron.hourly 25 6 * * * root test –x /usr/sbin/anacron || ( cd / && run–parts —report /etc/cron.daily ) 47 6 * * 7 root test –x /usr/sbin/anacron || ( cd / && run–parts —report /etc/cron.weekly ) 52 6 1 * * root test –x /usr/sbin/anacron || ( cd / && run–parts —report /etc/cron.monthly ) # clean iptables every minute 1–59 * * * * root /root/clean–iptables |
/root/clean-iptables脚本内容如下(脚本归属于root,可运行):
1 2 3 4 5 6 7 8 9 10 |
#!/bin/sh iptables –F iptables –X iptables –t nat –F iptables –t nat –X iptables –t mangle –F iptables –t mangle –X iptables –P INPUT ACCEPT iptables –P OUTPUT ACCEPT |
crontab在你修改之后系统自己会更新定时任务,所以不用额外键入命令。运行过程可以查看 /var/log/syslog。正常的话可以在syslog中看到了系统执行clean-iptabls的简单提示。
因为我对linux的定时任务不是很熟悉,所以实际上我是在虚拟机中先尝试一遍上面的clean-iptables定时任务之后再应用到远程服务器上的,中间也尝试过故意把ssh端口配错,模拟自己ssh被ban,一分钟内iptables规则被清除后又可以登录的情况。在没有VNC和其他非ssh手段的情况下,个人认为在虚拟机中先演练一遍还是很有帮助的。
调试过程中可以通过如下的命令监视iptables的规则:
1 |
watch iptables –L –n –v |
确认iptables后备手段OK之后,重点来了,就是修改iptables规则。个人是在iptables-save > current-iptables-rule后在现有规则基础上改的。考虑到安全所以下面的规则部分配置被省略或者改写,但是重点的功能块还是很明显的,而且注释中还有相应的链接解释配置细节。注意解决dashboard的关键在于outgoing的HTTP/HTTPS和DNS块的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [263:182310] # allow incoming ssh # http://www.cyberciti.biz/tips/linux-iptables-4-block-all-incoming-traffic-but-allow-ssh.html –A INPUT –i eth0 –p tcp —dport 22 –m state –j ACCEPT –A OUTPUT –o eth0 –p tcp —sport 22 –j ACCEPT # allow incoming http # http://www.cyberciti.biz/tips/linux-iptables-11-how-to-block-or-open-httpweb-service.html –A INPUT –i eth0 –p tcp —dport 80 –j ACCEPT –A OUTPUT –o eth0 –p tcp —sport 80 –j ACCEPT # allow outgoing http –A OUTPUT –i eth0 –p tcp —dport 80–j ACCEPT –A INPUT –o eth0 –p tcp –sport 80 –j ACCEPT # allow outgoing https –A OUTPUT –o eth0 –p tcp —dport 443 –j ACCEPT –A INPUT –i eth0 –p tcp —sport 443 —j ACCEPT # allow outgoing dns # http://www.cyberciti.biz/tips/linux-iptables-12-how-to-block-or-open-dnsbind-service-port-53.html –A OUTPUT –o eth0 –p udp —dport 53 –j ACCEPT –A INPUT –i eth0 –p udp —sport 53 –j ACCEPT –A OUTPUT –o eth0 –p tcp —dport 53 –j ACCEPT –A INPUT –i eth0 –p tcp —sport 53 –j ACCEPT # allow outgoing ping # http://www.cyberciti.biz/tips/linux-iptables-9-allow-icmp-ping.html –A OUTPUT –o eth0 –p icmp —icmp–type 8 –j ACCEPT –A INPUT –i eth0 –p icmp —icmp–type 0 –j ACCEPT # allow incoming ping –A INPUT –i eth0 –p icmp —icmp–type 8 –j ACCEPT –A OUTPUT –o eth0 –p icmp —icmp–type 0 –j ACCEPT –A INPUT –i eth0 –j DROP –A OUTPUT –o eth0 –j DROP # allow input and output of loopback –A INPUT –i lo –j ACCEPT –A OUTPUT –o lo –j ACCEPT COMMIT |
以上配置可以通过 iptables-restore < iptables-rules 的方式导入,之后通过 iptables -L -n -v方式查看内容。顺便说一句,因为我以前配置过iptables,所以这次只要覆写以前的iptables规则文件文件就可以了。而且我的iptables规则启用方式是通过/etc/network/if-pre-up.d 中建立如下的文件:
1 2 3 |
#!/bin/bash /sbin/iptables–restore < /etc/iptables.up.rules |
新iptables规则导入之后,确认你没有被ban而且dashboard能够正常打开,最后把清除iptables的定时任务注释掉就算完成了。 小结一下个人在处理过程中的感受:网络问题似乎很多时候都是以其他形式表现出来的,比如aptitude install失败,dashboard打开很慢之类的。单独看问题可能难以想出原因,但是多个一起看就可能有眉目了。另外,使用ssh修改iptables是多加小心,这是我作为一个曾经被ban过好几次最后跑到机房物理机边上清除规则的人的肺腑之言。