Iptables是运行在用户空间的应用级(Ring3)防火墙软件,通过调用Linux内核的Netfilter模块,进行网络数据包的流动、转送以及修改。iptables是状态防火墙,可以对会话的状态进行跟踪,这点相较于无状态防火墙要方便许多。
Netfilter是由Rusty Russell提出的Linux 2.4.x内核防火墙框架,目前支持的内核包括2.4、2.6及3.0。iptables所设置的规则最终是存放在内核内存中的Xtables(Netfilter的配置表)。Iptables和ip6_tables、arp_tables等Netfilter的项目都是建构在Xtables的架构下。
表是包含了不同默认链的组合,每个表都和数据包的处理有关,iptables共内置了5个表,即filter,nat,mangle,raw,security分别实现数据包过滤、动态网络地址转换,(Network Address Translation,NAT),数据包修改,数据包状态跟踪,以及实现强制访问控制MAC(Mandatory Access Control )和自主访问控制DAC(Discretionary Access Control )等。
链是决定数据包是否可以通过的决定因素,每个数据包从进入系统,到离开系统,都至少要通过2条链。
链是Netfilter中的挂载点(Hook Point)在iptables中的体现,共包括5条链,分别为PREROUTING(数据包进入路由表之前),INPUT(通过路由表后目的地为本机),FORWARD(通过路由表后,目的地不为本机),OUTPUT(由本机产生,向外转发),POSTROUTING(发送到网卡接口之前),对应Netfilter中5个挂载点:
NF_INET_PRE_ROUTING,NF_INET_LOCAL_IN,NF_INET_FORWARD,NF_INET_LOCAL_OUT,NF_INET_POST_ROUTING
注:挂载点(Hook Point),可以理解为回调函数点,数据包到达这些位置的时候,会主动调用对应的函数,使其在数据包路由的时候可以改变它们的路径以及内容。
规则在链里面决定对数据包的处理动作,存储在内核空间的Xtables中。在这里,可以定义对数据包的具体处理(target)。当数据包穿过一条链的时候,每条规则会依序检查它(包括源目地址,协议等参数),如果没有规则与其相匹配,则数据包会被传递到下一条规则去尝试匹配,当匹配上之后,会按照target中规定的动作对数据包进行梳理。
我们经常使用xshell等交互式工具进行端口转发和地址转换,iptables中的地址转换功能对大部分人来说用到不算很多,但是却很有用。以此例来展示iptables的使用。
- 1台centos7主机作为web主机
ip=192.168.0.10,hostname=webserver
- 1台Ubuntu 16.04作为iptables所在主机,iptables版本为iptables 1.6.0
ip=192.168.0.5,hostname= IptablesTest
- 1台Ubuntu 16.04作为client(192.168.0.20)
ip=192.168.0.20,hostname=client
模仿反向代理的场景,webserver的http流量不能被其他机器直接访问,需要通过IptablesTest作为中转才能到达。
- 首先在webserver将所有的入流量全部DROP,这样所有的流量都无法进入该机器
iptables -P INPUT DROP
- 在webserver上放行IptablesTest的流量以及宿主机(192.168.0.4)的流量
iptables -I INPUT -s 192.168.0.4 -j ACCEPT
iptables -I INPUT -s 192.168.0.5 -j ACCEPT
- webserver上的iptables配置完成后的filter表如下:
- 由于Linux默认将路由功能关闭,因此需要在IptablesTest机器上打开Linux路由转发开关功能,具体方法如下:
编辑/etc/sysctl.conf,并加入如下语句
如果仅希望临时生效,下次开机失效,可以执行如下语句:
echo "1" > /proc/sys/net/ipv4/ip_forward
如果需要永久生效的话,需要修改sysctl.conf:
net.ipv4.ip_forward = 1
执行sysctl -p 立即生效
注:这点很重要,也很容易被忽略
- 在IptablesTest机器上将所有访问该机器80端口的TCP流量全部做DNAT转换,将目的地址转换为webserver的地址;并将webserver返回的流量使用SNAT转回给client,这里也可以使用路由反向做回的方向实现。
iptables -t nat -A PREROUTING -d 192.168.0.5/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.10:80
iptables -t nat -A POSTROUTING -d 192.168.0.10/32 -p tcp -j SNAT --to 192.168.0.5
- IptablesTest上iptables配置完成后的filter表如下:
- 我们发现直接访问webserver地址,发现并不通,而访问IptablesTest的80端口,发现可以打开http服务。说明访问webserver的流量被IptablesTest进行了转换和代理。
清空自定义链、清空规则、清空规则计数器
iptables -X
iptables -F
iptables -Z
清除NAT表规则
iptables -F -t nat
NAT表的显示
iptables -t nat -nL
首先允许所有的包,然后再禁止有危险的包通过放火墙。
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
首先禁止所有的包,然后根据需要的服务允许特定的包通过防火墙。
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -L
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACEPT
iptables -A OUTPUT -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A FORWARD -0 eth1 -j ACCEPT
注意:由于本地进程不会经过FORWARD链,因此回环接口lo只在INPUT和OUTPUT两个链上作用。
iptables -N custom
iptables -A custom -s 0/0 -d 0/0 -p icmp -j DROP
iptables -A INPUT -s 0/0 -d 0/0 -j custom
匹配指定协议。
iptables -A INPUT -p tcp
匹配指定协议之外的所有协议。
iptables -A INPUT -p !tcp
指定匹配的主机。
iptables -A INPUT -s 192.168.0.18
指定匹配的网络。
iptables -A INPUT -s 192.168.2.0/24
匹配指定主机之外的地址。
iptables -A FORWARD ! -s 192.168.0.19
匹配指定网络之外的网络。
iptables -A FORWARD ! -s 192.168.3.0/24
指定单一的网络接口匹配。
iptables -A INPUT -i eth0
iptables -A FORWARD -o eth0
指定同类型的网络接口匹配。
iptables -A FORWARD -o ppp+
指定单一端口匹配。
iptables -A INPUT -p tcp --sport www
iptables -A INPUT -p udp --dport 53
匹配指定端口之外的端口。
iptables -A INPUT -p tcp --dport !22
匹配端口范围。
iptables -A INPUT -p tcp --sport 22:80
匹配ICMP端口和ICMP类型。
iptables -A INPUT -p icmp --icmp-type 8
指定ip碎片。
- 每个网络接口都有一个MTU(最大传输单元),这个参数定义了可以通过的数据包的最大尺寸。如果一个数据包大于这个参数值时,系统会将其划分成更小的数据包(称为ip碎片)来传输,而接受方则对这些ip碎片再进行重组以还原整个包。这样会导致一个问题:当系统将大数据包划分成ip碎片传输时,第一个碎片含有完整的包头信息(IP+TCP、UDP和ICMP),但是后续的碎片只有包头的部分信息(如源地址、目的地址)。因此,检查后面的ip碎片的头部(像有TCP、UDP和ICMP一样)是不可能的。假如有这样的一条规则:
iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.2.100 –dport 80 -j ACCEPT
- 并且这时的FORWARD的policy为DROP时,系统只会让第一个ip碎片通过,而余下的碎片因为包头信息不完整而无法通过。可以通过—fragment/-f 选项来指定第二个及以后的ip碎片解决上述问题。
iptables -A FORWARD -f -s 192.168.1.0/24 -d 192.168.2.100 -j ACCEPT
注意现在有许多进行ip碎片的实例,如DoS,因此允许ip碎片通过是有安全隐患的,对于这一点可以采用iptables的匹配扩展来进行限制。
匹配多个源端口。
iptables -A INPUT -p tcp -m multiport --sport 22,53,80,110
匹配多个目的端口。
iptables -A INPUT -p tcp -m multiport --dpoort 22,53,80
匹配多端口(无论是源端口还是目的端口)
iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
使用 –tcp-flags 选项可以根据tcp包的标志位进行过滤。
iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
iptables -A FROWARD -p tcp --tcp-flags ALL SYN,ACK
上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。
iptables -A FORWARD -p tcp --syn
选项—syn相当于”–tcp-flags SYN,RST,ACK SYN”的简写。
指定单位时间内允许通过的数据包个数,单位时间可以是/second、/minute、/hour、/day或使用第一个子母。
iptables -A INPUT -m limit --limit 300/hour
指定触发事件的阀值。
iptables -A INPUT -m limit --limit-burst 10
用来比对一次同时涌入的封包是否超过10个,超过此上限的包将直接丢弃。
同时指定速率限制和触发阀值。
iptables -A INPUT -p icmp -m limit –-limit 3/m --limit-burst 3
表示每分钟允许的最大包数量为限制速率(本例为3)加上当前的触发阀值burst数。任何情况下,都可保证3个数据包通过,触发阀值burst相当于允许额外的包数量。
基于状态的匹配扩展(连接跟踪)
每个网络连接包括以下信息:源地址、目标地址、源端口、目的端口,称为套接字对(socket pairs);协议类型、连接状态(TCP协议)和超时时间等。防火墙把这些信息称为状态(stateful)。状态包过滤防火墙能在内存中维护一个跟踪状态的表,比简单包过滤防火墙具有更大的安全性,命令格式如下:
iptables -m state –-state [!]state [,state,state,state]
其中,state表是一个逗号分割的列表,用来指定连接状态,4种:
NEW: 该包想要开始一个新的连接(重新连接或连接重定向)
RELATED:该包是属于某个已经建立的连接所建立的新连接。举例:
FTP的数据传输连接和控制连接之间就是RELATED关系。
ESTABLISHED:该包属于某个已经建立的连接。
INVALID:该包不匹配于任何连接,通常这些包被DROP。
例如:
(1)在INPUT链添加一条规则,匹配已经建立的连接或由已经建立的连接所建立的新连接。即匹配所有的TCP回应包。
iptables -A INPUT -m state --state RELATED,ESTABLISHED
(2)在INPUT链链添加一条规则,匹配所有从非eth0接口来的连接请求包。
iptables -A INPUT -m state -–state NEW -i !eth0
又如,对于ftp连接可以使用下面的连接跟踪:
(3)被动(Passive)ftp连接模式。
iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state –-state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m
state -–state ESTABLISHED,RELATED -j ACCEPT
(4)主动(Active)ftp连接模式
iptables -A INNPUT -p tcp --sport 20 -m state –-state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp –dport 20 -m state --state ESTABLISHED -j ACCEPT
https://zh.wikipedia.org/wiki/Iptables
http://www.cnblogs.com/LittleHann/p/3708222.html
https://blog.csdn.net/sealyao/article/details/5934268
https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html
http://zh.wikipedia.org/wiki/Netfilter
http://www.netfilter.org/projects/iptables/
http://linux.vbird.org/linux_server/0250simple_firewall.php
http://www.vpser.net/security/linux-iptables.html
http://blog.51cto.com/xjsunjie/1902993
http://blog.51cto.com/qujunorz/1884459