标题: 用iptables设置有状态防火墙

标题: 用iptables设置有状态防火墙

如果你是新手,请先看我写的《用iptables设置静太防火墙》 ,本文在此基础上写的,很多细节上的问题用它作参考。

########################

版权所有,转载请注明来自www.linuxsir.org 并写明作者

########################

在这里我必须要解释一下防火墙的状态(state)

比如,你用ssh远程访问,你的主机和远程主机会进行通信。
静态的防火墙会这样处理:
检查时入机器的数据包,发现数据是来源是22端口,当允许时入,连接之后相互通信的数据也一样,检查每个数据,发现数据来源于22端口,允许通过!

如果用有状态的防火墙如何处理呢?
当你连接远程主机成功之后,你的主机会把这个连接记录下来,当有数据从远程ssh服务器再进入你的机器时
检查自己连接状态表,发现这个数据来源于一个已经建立的连接,允许这个数据包进入。

以上两种处理,我们明显的发现static firewall比较生硬,而有状态的防火墙则显得要智能一些!

现在我们来解释一下状态
NEW:如果你的主机向远程机器发时一个连接请求,这个数据包状态是NEW.
ESTABLISHED:当联接建立之后,远程主机和你主机通信数据状态为ESTABLISHED
RELATED: 像ftp这样的服务,用21端口传送命令,而用20端口(port模式)或其他端口(PASV模式)传送数据。在已有21端口上建立好连接后发送命令,用20传送的数据,状态是RELATED

有了以上知识后,接下来时行我们的step by step 吧
首先,我们还是来设置默认规则
iptables -P INPUT DROP
这样你的机器将对所有进入你主机的数据都丢弃

如果你有一台主机只是用于个人桌面应用,那么你的主机不提供任何服务,那么,我们就禁止其他的机器向你的机器发送任何连接请求
iptables -A INPUT -m state --state NEW -j DROP

这个规则将所有发送到你的机器数据包,状态是NEW的包丢弃。这样,也就是不允许其他的机器主动发起对你机器的连接,但是你却可以主动的连接其他的机器,不过仅仅只是连接而已,连接之后的数据就是ESTABLISHED状态的了,我们再加上一条。

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
所有已经建立联接,或者与之相关的数据允许通过

好了,们们来总结一下三条语句,因为它是一个很好的个人桌面主机的防火墙。
iptables -P INPUT DROP
#iptables -A INPUT -m state --state NEW -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
我们看到,第二条被注释掉了,因为那一规则完全可以省去,让默认规则处理就行了。
是不是显得很简单呢,对于个人桌面应用来说,只用刚才那两条语句,就能让你接入internet网的主机足够安全。而且你随意访问internet,但是外部却不能主动发起对你机器的连接,真是爽啊!
当然,如是你的IE有漏洞的话,iptables还是无济于事的,这也不是iptables的工作范围。
我们可看到有状态的防火墙比静态防火墙要"智能"一些,当然规则容易设置一些。

如果你的主机是服务器,接下来的问题就简单了。这里假如我们开了www 和ftp服务。注意ftp的pasv模式,会使用动态的端口来传送数据,而并非20端口。这些对有状态的防火墙来说,轻易做到,甚至不用知道pasv模式的ftp用哪些端口,因为你的主机会认识到ftp给别人主机传送文件时,认识到这些数据是RELATED

在后面加下
iptables -A INPUT -i ppp0 -p tcp -dport 21 -j ACCEPT
iptables -A INPUT -i ppp0 -p udp -dport 21 -j ACCEPT
iptables -A INPUT -i ppp0 -p tcp -dport 80 -j ACCEPT
iptables -A INPUT -i ppp0 -p udp -dport 80 -j ACCEPT
好了,至此我们的工作就全部完成了,仿照我上一文的方法,最后给出一个脚本,有详细的注释

!/bin/bash
#define const here
Accept_Ports="80 20 21" #允许internet访问的自己服务端口

# init
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

# set default ruler here
iptables -P INPUT DROP

# Allow inner Network access
iptables -A INPUT -i !ppp0 -j ACCEPT

# set stated ruler here,this is the most important ruler
iptables -A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# set ruler so that other can access service on your server
for Port in "$Accept_Ports" ; do
iptables -A INPUT -i ppp0 -p udp --dport ${Port} -j ACCEPT
iptables -A INPUT -i ppp0 -p tpc --dport ${Port} -j ACCEPT
done

# the ruler can make you firewall betterd
iptables -A INPUT -i ppp0 -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -i ppp0 -p udp -j REJECT --reject-with icmp-port-unreachable

注:
有状态防火墙需要内核的支持,幸好,多数的发行版都支持这一特征