iptables调整以及解决wordpress的dashboard打开异常慢的问题


最近把网站的服务器从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规则的定时任务。

# /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,可运行):

#!/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的规则:

watch iptables -L -n -v

确认iptables后备手段OK之后,重点来了,就是修改iptables规则。个人是在iptables-save > current-iptables-rule后在现有规则基础上改的。考虑到安全所以下面的规则部分配置被省略或者改写,但是重点的功能块还是很明显的,而且注释中还有相应的链接解释配置细节。注意解决dashboard的关键在于outgoing的HTTP/HTTPS和DNS块的配置。

*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 中建立如下的文件:

#!/bin/bash

/sbin/iptables-restore < /etc/iptables.up.rules

新iptables规则导入之后,确认你没有被ban而且dashboard能够正常打开,最后把清除iptables的定时任务注释掉就算完成了。

小结一下个人在处理过程中的感受:网络问题似乎很多时候都是以其他形式表现出来的,比如aptitude install失败,dashboard打开很慢之类的。单独看问题可能难以想出原因,但是多个一起看就可能有眉目了。另外,使用ssh修改iptables是多加小心,这是我作为一个曾经被ban过好几次最后跑到机房物理机边上清除规则的人的肺腑之言。