原文地址The Beginner’s Guide to iptables, the Linux Firewall
iptables是专为Linux系统设计的灵活度很高的防火墙工具,不管你是linux新手,还是系统管理员,iptables总有一些方面对你而言是非常有用的。
关于iptables
iptables是一个基于策略链来允许和阻止流量的命令行防火墙工具,当一个链接试图和你的系统建立链接时,iptables会在它的列表中寻找匹配的规则,如果没有相匹配的规则,那么会执行默认动作。
几乎在所有的Linux发行版中都预装了iptables,通过包管理命令,可以升级或安装它:
sudo apt-get install iptables
目前也有一些图形化的工具可以进行iptables的配置,但是如果你了解了一些iptables的相关命令后,你会发现它其实没那么难。不过在配置iptables规则时,你必须非常的小心,尤其是当你是通过SSH远程登录在服务器进行配置时,因为一条错误的规则,可能会让你无法访问这台服务器,除非亲自去机房进行规则修正。
策略链的类型
iptables的策略链包含:输入链、转发链、输出链三种。
输入链(Input)
这条策略链控制接入链接的行为。比如,当一个用户通过SSH登录你的PC或服务器时,iptables会尝试在输入规则链中寻找匹配的规则和动作。
转发链(Forward)
这条策略链用于那些目的地不是我们的输入链接。拿路由来说,数据总是都发送给它,然而它并不是数据的目的地,数据总是被转发到它的目的地。除非你需要进行一些需要转发的活动,比如路由或是网络地址转换(NAT),否则你不需要使用这个策略链。
有一个万无一失的办法可以查看,你的系统有没有使用转发策略链。
iptables -L -v
上面的截图是一个运行了好几周的服务器的运行结果,它没有对输入输出链接进行任何限制。你可以看到,输入链处理了11G的数据包,输出链处理了17G的数据包,而转发链一个数据包都没有处理,这是因为这台服务器没有进行任何转发或传递的活动。
输出链
这条策略链用于输出链接。当你想要ping howtogeek.com
时,iptables会检查它的输出链,然后根据规则来决定是否允许或阻止链接企图的发生。
注意
即使简单的pinging
外部主机,看起来似乎只用到输出链,然而在接收返回数据时,也需要用到输入链。当使用iptables来保护你的系统时,你需要注意有很多协议是需要进行双向通信的,因此输入链和输出链都要进行相应的配置。SSH协议就是一个人们经常忘记在两条策略链进行配置的协议。
策略链的默认行为
在我们深入和配置相关的规则之前,你肯定希望决定策略链的默认配置
是什么,换句话就是说,如果一个链接没有匹配的规则,那么应该进行如何处理。
要了解你的策略链对于不匹配规则的流量处理行为,可以使用iptables -L
命令。
图中,我们也使用了
grep
命令来输出更清晰的结果。在图中,我们的策略链被配置为接受所有的流量。
大多数情况下,你会希望你的系统默认接受所有流量,而且除非你先前改变了策略链的配置,否则默认配置就是接受所有流量,总之,下面的命令可以设置策略链的默认行为为接受。
iptables --policy INPUT ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT
在配置策略链接受所有流量的同时,我们也可以使用iptables阻止特定的ip或端口号的流量,同时继续接受其它流量。相关的命令我们稍后会涉及到。
如果你希望指定的流量可以通过,而其它流量都被禁止的话,你应该把策略链的默认行为设置为丢弃。这么做对于存放敏感信息的只能通过特定ip进行的服务器来说是有用的。
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP
链接相关的响应
在配置好策略链的默认行为后,我们就可以开始添加具体的规则了,以便iptables在检测到匹配规则的流量是知道该如何处理。在这篇指南中,我们会介绍3种最基本也是最通用的响应行为。
接受(Accept)
接受链接
丢弃(Drop)
丢弃相关的数据,就好像它从来没有出现过一样。这可以很好的帮助你阻止对方知道你的系统的存在。
拒绝(Reject)
不允许链接,但是会响应一个错误。在你不希望对方链接你的系统,同时告诉对方,这是防火墙阻止的结果时,这种响应是有用的。
展示这几个响应行为的不同之处的最好方式,也许就是在iptables中配置相应的规则,然后PING同一个主机,看在不同的配置下,会有什么不同的表现。
允许流量通过
丢弃流量数据
拒绝流量通过
允许和阻止特定的链接
现在你可以来配置是否允许特定的ip,ip范围,端口的数据通过的规则了,作为例子,我们会使用丢弃作为对应的动作,不过你也可以根据你策略链的默认配置,来决定是允许还是拒绝链接。
注意:在例子中,我们使用-A
参数来表明追加一条规则到策略链。iptables会从头开始匹配,直到找到匹配的规则。如果你需要在某条规则之前插入一条规则,可以使用iptables -I [chain] [number]
来指定特定的位置。
来自一个ip的链接
下面的例子展示了如何丢弃(阻止)所有来自一个ip 10.10.10.10的链接
iptables -A INPUT -s 10.10.10.10 -j DROP
来自一个ip范围的链接
下面的例子展示了如何阻止来自10.10.10.0/24这个范围所有ip的链接。我们可以使用掩码或者标准的反斜线语法指定一个ip范围。
iptables -A INPUT -s 10.10.10.0/24 -j DROP
或者
iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP
特定端口的链接
下面的例子展示了如何阻止来自10.10.10.10的ssh链接请求
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP
你可以使用其它协议名称或对应端口号来替换命令中的ssh。命令中的-p tcp
部分,可以告诉iptables对应协议的链接类型。如果你想要阻止一个使用UDP链接而不是TCP链接的协议,那么可以指定-p udp
。
下面的例子展示了如何禁止来自任何地址的ssh请求
iptables -A INPUT -p tcp --dport ssh -j DROP
链接的状态
正如我们前面提到的一样,有很多协议都是需要进行双向通信的。比如,你允许了ssh链接到你的系统,那么输入链和输出链都需要进行相应的配置。但如果你只希望输入ssh链接到你的系统,而不希望在输出链添加允许ssh的输出链接规则呢?
对于这种情况我们就需要使用链接的状态,它可以允许我们使用双向的通信,但只需要允许单方向的链接建立。仔细看下面的例子,来自10.10.10.10的ssh输入链接是被允许的,然而ssh到10.10.10.10的输出链接是不被允许的。同时系统是允许我们发回数据的,只要会话的链接已经建立,这就允许了ssh可以在两台主机之间进行双向通信。
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT
保存配置信息
如果你没有对配置信息进行保存的话,下次iptables服务重启的时候,你做出的规则修改就会丢失。因此我们需要执行相应的命令对配置进行保存。根据系统不同,对应的命令可能会有差异。
Ubuntu:
sudo /sbin/iptables-save
Red Hat / CentOS:
/sbin/service iptables save
Or
/etc/init.d/iptables save
其它命令
列出当前配置的iptables规则列表
iptables -L
如果增加-v
参数,将会在结果中展示数据包和字节信息。另外使用-n
参数,会把所有信息都用数字形式展示,换句话说主机名、协议、网络都会用数值化的形式展示。
清空当前的配置规则,可以使用如下命令
iptables -F