CentOS6下iptables与FTP共存方法(解决非标准端口问题)

Tips:如果想看解决方案而不是我的分析,请直接跳到文末~

为了服务器安全着想,iptables防火墙是肯定启用了的。我的iptables只允许了Web、SSH、FTP三个协议,并且为了避免大范围端口扫描,都是非标准端口。

许久不用FTP,今天登录FTP的时候发现没办法和服务器通信,具体表现在无法连接数据端口上。由于我使用的是PASV被动模式,服务器端口是随机的,思索一下即发现连接被iptables中断。使用service iptables stop停止iptables后,一切正常,遂断定为iptables阻止了FTP的连入。

但我又不想把1024~65535范围内所有的端口打开,那样当然不安全。Google之后了解到ip_nat_ftp这个模块可以达到我的需求。于是modprobe ip_nat_ftp然后service iptables restart重启防火墙测试,问题依旧。使用lsmod查询后发现,ip_nat_ftp模块竟然没有加载,而是nf_nat_ftp模块被加载了。

于是又Google,在Shorewall防火墙的一篇说明文章中发现如下说明:

Note: If you are running kernel 3.6.20 or later, then the module names are nf_nat_ftp and nf_conntrack_ftp…

可是这个对于我的问题没有帮助,因为很显然ip_nat_ftp也是nf_nat_ftp的别名,毕竟模块已经加载上了。于是我又去查询nf_nat_ftp的原理,了解到它是通过监听21端口的PASV指令来打开对应端口的防火墙的。这么一来问题就找到了:我使用的FTP端口根本就不是21,模块也就没法监听了。

找到问题后就好解决了。需要注意的是,CentOS6中/etc/modprobe.conf文件已经不存在了(但仍然可以使用,只是系统不再生成了,via)。我们需要再另外在/etc/modprobe.d/下建立一个文件。

解决方案如下:

rmmod nf_nat_ftp
rmmod nf_conntract_ftp #这一行和上一行是卸载已经载入的模块,执行时可能会报错,无视即可。
vim /etc/sysconfig/iptables-config
# 找到IPTABLES_MODULES="",修改为IPTABLES_MODULES="nf_nat_ftp nf_conntrack_ftp"
vim /etc/modprobe.d/ftp.conf #如果为CentOS6以下版本,可以尝试vim /etc/modprobe.conf
# 在这个文件中写上下面两行
options nf_conntrack_ftp ports=你的FTP端口号
options nf_nat_ftp ports=你的FTP端口号
# 保存退出
services iptables restart #重启防火墙,请注意先备份防火墙规则
iptables -nL
# 检查你的防火墙中是否有如下规则
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:你的FTP端口号
# 如果没有则将下面的两条规则添加到防火墙规则文件
-A INPUT -p tcp -m state --state NEW -m tcp --dport 你的FTP端口号 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

经过上面的操作后,再启动FTP客户端测试连接,此时应该可以顺利的连接上你的服务器了。