简介
Iptables是Linux平台下通用的包过滤防火墙,可以完成封包过滤、封包重定向和网络地址转换(NAT)等功能。Iptables本身是对内核netfilter模块的封装,便于用户态程序操作防火墙。
四表五链
四表指的是:filter、nat、mangle、raw,其中filter表负责过滤功能,也就是防火墙配置;nat表,也就是network address translation,网络地址转换;mangle表负责拆解报文,做出修改(如TTL,Qos配置等信息)并重新封装;raw表,负责关闭nat表上启用的连接追踪机制。
五链指的是:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
表与链之间的关系,我们可以简单理解为表是一个一个面,而链则是穿越这些面将面连接。在表与链中,真正起到作用的则是规则。我们在表中可以修改TCP/IP包头的不同位置,在链中执行为包被路由转换的不同阶段。规则是具体的行为逻辑。
并不是所有的链都贯穿了上述四表,某些表中只能包含特定的某些链,下面简单作个列表归纳:
链 | 表 |
PREROUTING | raw,mangle,nat |
INPUT | mangle,filter,nat |
FORWARD | mangle,filter |
OUTPUT | raw,mangle,filter,nat |
POSTROUTING | mangle,nat |
关于规则,具体的动作包括:ACCEPT(接受)、REJECT(拒绝但会回复被拒绝的原因)、DROP(直接丢弃无响应)、REDIRECT(端口重定向)、MASQUERADE(源地址动态伪装)、LOG(记录日志而后向下匹配规则)、DNAT(目的IP转换)、SNAT(源IP转换)等。以下是规则匹配中的一些常用参数表:
参数 | 用途 |
-i | 指定入站的network interface |
-o | 指定出站的network interface |
-p | 指定匹配的协议,如tcp/udp/icmp |
-s | 指定源IP |
-d | 指定目标IP |
数据包经过防火墙时的数据流向可以参考下图:

如果数据包需要经过上层处理:流量->PREROUTING->INPUT->Application->OUTPUT->POSTROUTING;如果数据不需要经过上层处理,单纯转发:流量->PREROUTING->FORWARD->POSTROUTING.
列出规则
Iptables命令配置参数中遵守“表->链->规则“。如果我们需要查看所有的iptables配置,如下所示:
[email protected]:~# iptables --list -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[email protected]:~#
列出某个表上的规则:iptables -t +表名 -L,表名在缺省情况下默认为filter表
trout_x86:/ # iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
bw_INPUT all -- anywhere anywhere
fw_INPUT all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
oem_fwd all -- anywhere anywhere
fw_FORWARD all -- anywhere anywhere
bw_FORWARD all -- anywhere anywhere
tetherctrl_FORWARD all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
oem_out all -- anywhere anywhere
fw_OUTPUT all -- anywhere anywhere
st_OUTPUT all -- anywhere anywhere
bw_OUTPUT all -- anywhere anywhere
列出某个表上某个链的所有规则:iptables -t +表名 -L +链名
trout_x86:/ # iptables -t filter -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
bw_INPUT all -- anywhere anywhere
fw_INPUT all -- anywhere anywhere
trout_x86:/ # iptables -t filter -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
oem_out all -- anywhere anywhere
fw_OUTPUT all -- anywhere anywhere
st_OUTPUT all -- anywhere anywhere
bw_OUTPUT all -- anywhere anywhere
trout_x86:/ #
同时我们可以使用-v参数查看完整信息:
trout_x86:/ # iptables -t filter -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
oem_out all -- anywhere anywhere
fw_OUTPUT all -- anywhere anywhere
st_OUTPUT all -- anywhere anywhere
bw_OUTPUT all -- anywhere anywhere
trout_x86:/ # iptables -t filter -vL OUTPUT
Chain OUTPUT (policy ACCEPT 33733 packets, 6488K bytes)
pkts bytes target prot opt in out source destination
33749 6490K oem_out all -- any any anywhere anywhere
33749 6490K fw_OUTPUT all -- any any anywhere anywhere
33749 6490K st_OUTPUT all -- any any anywhere anywhere
33749 6490K bw_OUTPUT all -- any any anywhere anywhere
trout_x86:/ #
每一列的内容:
pkts:对应规则匹配到的报文的个数
bytes:对应匹配到的报文包的大小总和
target:规则对应的target,往往表示规则对应的动作
prot:表示规则对应的协议,是否仅针对某些协议应用此规则
opt:表示规则对应的选项
in:表示数据包由哪个网卡流入
out:表示数据包从哪个网卡流出
source:表示规则对应的源地址,可以是IP也可以一个网段
destination:表示规则对应的目标地址,可以是IP也可以是一个网段
在这些列的最上方,Chain OUTPUT意味着这是属于OUTPUT链的规则,policy drop意味着默认的规则为ACCEPT.
添加规则
上面的内容为查看iptables的规则,实际上是通过-L来列出。接下来我们讲讲如何添加规则。这里添加规则分为两种类型:insert与append。其中insert可以指定规则顺序,未指定的情况下将会将规则至于链开头;而append则是在链末尾进行追加。由于规则判断是自上而下进行的,所以链头的规则具有更高的优先级,这一点需要注意。
示例如下:
iptables -t filter -I INPUT -s 192.168.1.146 -j DROP
在这个示例中,-t用于指定哪个表,-t filter表明用于指定filter表,-I用于insert插入,-I INPUT表明在INPUT链中进行插入,-s表明适用于该规则的源地址,-j表示该规则具体的动作,一般常用的动作有ACCEPT,REJECT,DROP等。
在此处未指定位置顺序,所以是在INPUT链头添加规则。下面我们看一个追加规则的例子:
iptables -t filter -A INPUT -s 192.168.1.146 -j ACCEPT
在这个示例中,-A INPUT表示在INPUT链中append添加,需要说明的是,-A添加的规则是在链的尾部,而-I添加的规则是在链的首部,而规则的顺序是很重要的,对同一个目标制定好的规则,规则靠前满足就会优先处理,这可能会导致后续的规则无法生效。
如何确定规则的顺序呢,在列出规则时使用–line参数即可,如下图所示:
trout_x86:/ # iptables -t filter -vL OUTPUT
Chain OUTPUT (policy ACCEPT 33733 packets, 6488K bytes)
pkts bytes target prot opt in out source destination
33749 6490K oem_out all -- any any anywhere anywhere
33749 6490K fw_OUTPUT all -- any any anywhere anywhere
33749 6490K st_OUTPUT all -- any any anywhere anywhere
33749 6490K bw_OUTPUT all -- any any anywhere anywhere
trout_x86:/ # iptables -t filter --line -vL OUTPUT
Chain OUTPUT (policy ACCEPT 34237 packets, 6623K bytes)
num pkts bytes target prot opt in out source destination
1 34253 6625K oem_out all -- any any anywhere anywhere
2 34253 6625K fw_OUTPUT all -- any any anywhere anywhere
3 34253 6625K st_OUTPUT all -- any any anywhere anywhere
4 34253 6625K bw_OUTPUT all -- any any anywhere anywhere
trout_x86:/ #
如果我们想要指定插入的规则序号,可以使用如下示例来进行添加:
iptables -t filter -I INPUT 2 -s 192.168.1.146 -j ACCEPT
该示例表示插入规则且序号为2。
删除规则
有些时候我们可能会需要删除某些规则,删除规则一般可以有两种方式,一是通过序号来进行删除,二是直接删除对应的动作,如下所示:
iptables -t filter -D INPUT 2
表明删除filter表INPUT链的第二条规则。
iptables -t filter -D INPUT -s 192.168.1.146 -j ACCEPT
表明删除filter表中INPUT链对应的规则。
除了上述两种方式,iptables还提供了直接清除链中所有规则的方式,如下所示:
iptables -t filter -F INPUT
表明删除filter表中INPUT链上所有的规则。
修改规则
一般情况下不建议修改规则,比较推荐的是删除规则后重新添加对应的规则,但如果我们不得不修改规则时,iptables也提供了相应的能力。这里我们使用-R选项来修改。
使用示例:
iptables -t filter -R INPUT 1 -s 192.168.1.110 -j REJECT
在该示例中,-R选项表示指定要修改的链(Replace),1代表INPUT链的第一条规则,-s指定源地址,-j REJECT表明修改为REJECT。
除了修改某个具体的规则,我们可能还会修改某些链的默认规则,关于链的默认规则我们已经在上面提到过,这里讲如何修改默认规则:
iptables -t filter -P FORWARD DROP
在该示例中,我们将filter表中的FORWARD链默认规则改为DROP。
拓展使用
iptables提供了一些额外的拓展来帮助我们更好的制定规则,通过这些拓展我们可以更好地来制定规则。
确认已经loaded的拓展,我们可以使用如下命令:
[email protected]:/home/FranzKafka# cat /proc/net/ip_tables_matches
time
comment
limit
addrtype
conntrack
conntrack
conntrack
recent
recent
ttl
addrtype
udplite
udp
tcp
icmp
iprange模块:可以指定连续的IP地址,启用该模块后使用–src-range和—dst-range来指定,如下所示:
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.1-192.168.1.146 -j DROP
iptables -t filter -I INPUT -m iprange --dst-range 192.168.1.1-192.168.1.146 -j DROP
string模块:使用string扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件
time模块:可以根据时间段来匹配报文,如果报文到达的时间在指定的时间范围内,则符合匹配条件,可用参数包括–timestart和—timestop,–weekdays,–monthdays
iptables -t filter -I INPUT -p tcp --sport 443 -m time --timestart 09:00:00 -j DROP
iptables -t filter -I OUTPUT -p tcp -d taobao.com --dport 80 -m time --timestart 00:00 --timestop 10:00 --weekdays 1,2,3,4,5 -j DROP
connlimit模块:可以限制IP的连接数量
iptables -t filter -I INPUT -m connlimit –connlimit-above 3 -j REJECT
该示例限制单IP连接数超过3则REJECT拒绝连接。
limit模块:limit模块可以用于限制速率
查看某个拓展模块的帮助,可以使用如下命令:iptables -m 模块名 –help
如我们需要查看time模块的使用帮助,如下所示:
[email protected]:/home/FranzKafka# iptables -m time --help
iptables v1.8.4
time match options:
--datestart time Start and stop time, to be given in ISO 8601
--datestop time (YYYY[-MM[-DD[Thh[:mm[:ss]]]]])
--timestart time Start and stop daytime (hh:mm[:ss])
--timestop time (between 00:00:00 and 23:59:59)
[!] --monthdays value List of days on which to match, separated by comma
(Possible days: 1 to 31; defaults to all)
[!] --weekdays value List of weekdays on which to match, sep. by comma
(Possible days: Mon,Tue,Wed,Thu,Fri,Sat,Sun or 1 to 7
Defaults to all weekdays.)
--kerneltz Work with the kernel timezone instead of UTC
自定义链
除了默认的四表五链,我们也可以增加自己的链,也就是自定义的链。一般来讲我们可以不用增加自己的链,在默认的五链中进行规则的添加即可。但有些时候为了规则的集中管理,我们不方便在默认的链中进行操作,此时就可以使用自定义链,对自定义链进行管理。
创建自定义链:
iptables -t filter -N OWN_CHAIN //表明在filter表创建名为OWN_CHAIN的链,-N代表new
这里需要说明的是,创建自定义创建后需要在默认的链中进行引用才能使规则生效。
引用自定义链:
iptables -t filter -I INPUT -p tcp -j OWN_CHAIN //在INPUT链中引用OWN_CHAIN链
重命名自定义链:
iptables -E OWN_CHAIN OWN_CHAIN1 //将OWN_CHAIN重命名为OWN_CHAIN1
删除自定义链:
iptables -X OWN_CHAIN
清除自定义链:
iptables -t filter -F OWN_CHAIN