1. 什么是iptables?
iptables是Linux环境下一款重要的网络管理工具,可以配置管理ip数据包过滤规则, 从而实现防火墙、NAT(Network Address Translation)等功能。
2. iptables 命令
iptables配置的包过滤规则定义在rule中,rule又被定义在chain中,而chain又定义在table中。所有的iptables命令都是围绕rule和chain的“增删改查”。
命令格式如下:
iptables -t TableName -Command ChainName RuleSpec [option]
TableName用来指定该命令作用于哪个table;Command指定命令类型,是添加,删除,还是修改;ChainName指定rule所在chain;RuleSpec指定规则内容,rule没有名字,但是有编号。
常见的Command有:
-A,--append:在指定chain中追加一条rule
-D,--delete:在指定chain中删除一条rule
-I,--insert:在指定chain中插入一条rule
-R,--replace:在指定chain中替换一条rule
-L,--list:显示指定chain或所有chain中的rule
-S,--list-rules:显示指定chain或所有chain中的rule。与“- L”的区别是,“-S“的显示格式类似iptables-save的结果。
-F,--flush:删除指定chain中rule
-Z,--zero:重置数据包和字节计数
-N,--new-chain:新建一个自定义chain
-X,--delete-chain:删除一个自定义chain
-P,--policy:设置内置chain的target,只能是ACCEPT或DROP
-E,--rename-chain:重命名一个自定义chain
RuleSpec中常见的参数:
-j,--jump: 指定数据包匹配后的动作
-g,--goto:指定自定义chain去继续处理匹配到的数据包。它和“-j“的区别是在完成指定chain的规则处理后,不会再继续当前chain的规则处理。
-c,--set-counters:设置数据包和字节计数的初始值
-s: 指定数据包源地址
-d: 指定数据包目的地址
-p: 指定网络协议,比如tcp,udp,icmp
Options:
-v,--verbose:输出详细信息,比如数据包和字节计数
-n,--numeric: 以数字形式打印ip和port,不显示对应的hostname
-x,--exact:打印数据包和字节计数的精确值
-w,--wait:等待xtable lock的时间(秒)
2.1 table的种类
filter:默认table,包含的的内置chain有,INPUT,OUTPUT和FORWARD。以iptables命令生效的机器为例,INPUT针对目的地址是本机地址的数据包;OUTPUT则针对从本机发出的数据包;而FORWARD是针对经过本机转发的数据包。
nat:与网络地址转换相关的table,包含PREROUTING、OUTPUT和POSTROUTING这三个内置chain。以iptables命令生效的机器为例,PREROUTING配置本机接收的数据包在被转发前要执行的修改规则;OUTPUT配置本机产生的数据包在被转发前要执行的修改规则;POSTROUTING则配置被修改的数据包在即将被转发时要执行的修改规则。
除了Filter和Nat table外,还有Mangle和Raw table。
2.2 Rule中的动作(target)
在每个iptable规则中,都会有target,它的值可以是用户自定义的chain,也可以是ACCEPT、DROP、QUEUE、RETURN和LOG中的任意一个。实际上,iptables在处理数据包时,会根据chain中定义的规则一条一条的进行匹配。当数据包与当前规则中定义的条件匹配时,就执行target指定的动作或是自定义chain的规则;否则,就尝试匹配下一条规则。
动作ACCEPT是允许数据包进入;DROP是丢弃数据包;QUEUE是将数据包发送给用户空间的进程;RETURN是从当前chain返回并从上一个chain中的下一个rule开始匹配;LOG则用来记录匹配的数据包。
2.3 命令示例
1)在filter table中自定义一个chain
iptables -t filter -N userchain1
2)显示fitler table中所有的配置
iptables -t filter -S
3)在filter table中删除一个rule
iptables -t filter -D userchain1 2
4)记录规则匹配
iptables -t filter -A INPUT -p icmp --icmp-type echo-request -j LOG --log-level info --log-prefix "ping-req "
iptables -t filter -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
默认的iptables log被保存在/var/log/kern.log中。如果给一条规则只配置target为log,那么匹配的数据包在被记录后就会删除。利用这个特性可以测试规则的匹配条件。上面例子中,第一条规则实现log功能,第二条规则接收数据。
3. 使用示例
3.1 访问控制
本机只开放ssh端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP
3.2 NAT
1)将访问本机IP地址192.168.1.2、端口80的tcp数据包转发到10.10.10.10,端口80.
iptables -t nat -A PREROUTING -p tcp -d 192.168.1.2 --dport 80 -j DNAT --to-destination 10.10.10.10:80
iptables -t nat -A POSTROUTING -p tcp -d 10.10.10.10 --dport 80 -j SNAT --to-source 192.168.1.2
此处还需要将/proc/sys/net/ipv4/ip_forward 设置为“1”
2)将来自网段192.168.0.0/16的数据包通过SNAT发送
iptables -t nat -s 192.168.0.0/16 -o eth0 -j MASQUERADE
此处,MASQUERADE的作用是从eth0上自动获取ip地址进行SNAT。这对于ip地址是通过DHCP或是PPP方式获得时非常有用。
4. 自定义chain处理的先后顺序
写到这里,可能会有人问不同table中的内置的chain在处理数据包时,有没有先后顺序?实际上,iptables的内置chain在处理数据包时有先后顺序。从下图可以看出,PREROUTING chain会被优先处理。在第一次路由判断时,iptables 根据数据包的目的地址是否为本机地址决定下一步时进入INPUT还是FORWARD。所以,在nat table的PREROUTING中修改数据包目的地址为非本机地址后,数据包就不会受到filter table中的INPUT、OUTPUT规则的影响,只要保证filter FORWARD的policy是ACCEPT即可。