一、相关概念
1.1、链(chain)
iptables包含以下五种内置链:
- PREROUTING:数据包刚到达本机,未经过路由之前;
- INPUT:数据包经过路由进入本机;
- FORWARD:数据包转发;
- OUTPUT:数据包从本机发出,未经过路由之前;
- POSTROUTING:数据经过路由离开本机。
1.2、表(table)
iptables包含四种表:
- raw表:关闭nat表上启用的连接追踪功能;
- mangle表:拆解报文,作出修改,并重新封装;
- nat表:网络地址转换,修改源IP地址或目的IP地址,也可以对端口进行修改;
- filter表:过滤数据包。
表处理的优先级:raw表 --> mangle表 --> nat表 --> filter表
1.3、表链关系
raw表对应的链:PREROUTING、OUTPUT;
mangle表对应的链:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING;
nat表对应的链:PREROUTING、OUTPUT、POSTROUTING,CentOS7以上系统还包括INPUT;
filter表对应的链:INPUT、FORWARD、OUTPUT
1.4、路由功能
路由功能发生的时刻:
- 数据包到达本机后,判断目标主机是哪里?
- 数据包离开本机时,判断应该由哪个接口(网卡)送往下一站。
1.5、报文流向
数据包流向大致可以分为三类:
- 数据包流入本机:PREROUTING --> INPUT
- 数据包由本机流出:OUTPUT --> POSTROUTING
- 数据包转发:PREROUTING --> FORWARD --> POSTROUTING
二、iptables使用
2.1、iptables命令用法
iptables命令语法格式:
iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
- -t table:raw、mangle、nat、filter。默认值为filter;
- chain:内置链包括PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING;
- COMMAND:
链管理相关:
-N:自定义一条新的规则链;
-X:删除自定义的规则链,指定链名则删除指定链,不指定则删除所有;
-P:设置默认策略。对filter表中的链,策略有:ACCEPT(接收),DROP(丢弃),REJECT(拒绝)。DROP和REJECT的区别在于REJECT有特定的数据返回给对方,而DROP则直接丢弃数据包;
-E:重命名自定义链。引用计数不为0的链不能被重命名,也不能被删除;
规则管理相关:
-A:在链的尾部追加一条规则;
-I:插入新的规则到指定位置,省略时表示插入到第一条;
-D:删除指定序号的规则;或者直接删除指定规则本身;
-R:修改指定序号的已有规则;
-F:清空指定链上的所有规则;
-Z:重置规则上的计数器(本规则匹配到的报文个数和报文的字节数);
-L:查看指定链上的规则;
-n:查看规则时,以数字格式显示地址和端口号,即避免域名解析;
–line-numbers:查看规则时,显示每条规则的序号;
-v,-vv,-vvv:查看规则时,显示每条规则的详细信息(计数器等);
-x:查看规则时,显示计数器结果的精确值,不进行单位转换。 - 匹配条件:
基本匹配条件:无需加载任何模块,由iptables/netfilter自行提供。
扩展匹配条件:需要先通过-m加载模块。 - 处理动作:-j targetname [per-target-options],常用的有ACCEPT、DROP、REJECT。
2.2、添加规则时需要考虑哪些
- 1)要实现哪种功能:判断添加到哪个表上;
- 2)报文流经的路径:判断添加到哪个链上。一般来讲,数据包越早处理越好;
- 3)链上的规则策略,即检查的次序,iptables默认从第一条规则开始,逐条匹配:
– 同类规则(访问同一应用),匹配范围小的放上面;
– 不同类规则(访问不同应用),匹配频率较大的放上面;
– 将可由一条规则描述的多个规则合并为一条; - 4)设置默认策略。
2.3、如何避免把自己挡在外面
刚开始接触iptables,遇到最多的情况就是,编写一条规则,结果把自己挡在防火墙外面了。如果使用的是本地虚拟机,可以直接从虚拟机登录,清空规则或者给自己放行。
如果是远程服务器,可以编写shell脚本,通过循环语句定时清空规则,避免发生尴尬时不好挽回。
三、iptables实践
3.1、基本匹配条件
3.1.1、基于源IP地址和目的IP地址的规则
例如,仅允许IP地址是192.168.18.1的主机访问本主机(IP地址192.168.18.130),其它主机的数据包全部丢弃:
# iptables -t filter -A INPUT -s 192.168.18.1 -d 192.168.18.130 -j ACCEPT
# iptables -t filter -A INPUT -j DROP #危险~
- -s, --source address/mask:检查报文中的源IP地址是否符合条件;
- -d, --destination address/mask:检查报文中的目的IP地址是否符合条件;
如果只有这两条规则,会有个问题,当使用远程工具Xshell或其它工具通过SSH连接该主机时,会等待较长时间。还有个更直观的现象,就是查看规则时,通过“-n”跳过域名解析,和不使用“-n”,返回结果的时间完全不同,尝试执行下面两条命令来查看规则:
# iptables -t filter -L INPUT
# iptables -t filter -L INPUT -n
3.1.2、基于协议的规则
例如,将所有主机发往本机(IP地址192.168.18.130)的ICMP协议数据包全部丢弃:
# iptables -t filter -F INPUT #用于清空规则
# iptables -t filter -A INPUT -d 192.168.18.130 -p icmp -j DROP
- -p, --protocol protocol:指定协议类型tcp,udp,udplite,icmp,icmpv6,esp,ah,sctp,mh或者关键字"all";
尝试使用以下命令,将处理动作由“DROP”改为“REJECT”,在其它主机上执行ping
命令观察两个处理动作的区别:
# iptables -t filter -R INPUT 1 -d 192.168.18.130 -p icmp -j REJECT
3.1.3、基于网络接口的规则
例如,将经过本机(IP地址192.168.18.130) ens33接口的ICMP协议类型的数据包全部丢弃:
# iptables -t filter -F INPUT #用于清空规则
# iptables -t filter -A INPUT -i ens33 -p icmp -j DROP
- -i, --in-interface name:数据流入方向,只能应用于INPUT、FORWARD、PREROUTING链;
- -o, --out-interface name:数据流出方向,只能应用于OUTPUT、FORWARD、POSTROUTING链。
3.2、隐式扩展匹配
隐式扩展不必手动加载扩展模块,因为它们是对协议的扩展。所以,当使用-p
指明了协议,就表示已经指明了要扩展的模块。
3.2.1、基于TCP/UDP源端口和目的端口的规则
首先添加以下规则:
# iptables -t filter -F INPUT #用于清空规则
# iptables -t filter -A INPUT -s 192.168.18.1 -d 192.168.18.130 -j ACCEPT
# iptables -t filter -A INPUT -j DROP
在3.1.1节,说明过这两条规则带来的域名解析问题,由于DNS使用基于TCP/UDP的53端口,编写规则放行源端口是53的数据包:
# iptables -t filter -I INPUT 1 -p tcp --sport 53 -j ACCEPT
# iptables -t filter -I INPUT 1 -p udp --sport 53 -j ACCEPT
- –source-port,–sport port[:port]:匹配数据包中的源端口(或范围);
- –destination-port,–dport port[:port]:匹配数据包中的目的端口(或范围)。
3.2.2、基于TCP flags的规则
例如,允许本地转发哪种类型的数据包:
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST SYN
- –tcp-flags mask comp
– mask:指必须要检查的标志位,以逗号分隔的列表。例如:SYN,ACK,FIN,RST;
– comp:指mask指定的标志位中必须为1的标志位,其余的必须为0; - –syn:用于匹配TCP连接的第一次握手,相当于“–tcp-flags SYN,ACK,FIN,RST SYN”。
3.2.3、基于ICMP协议的规则
需要注意的是,ICMP协议包含两部分内容,一个是用于发送请求的“echo-requst”,类型“type”为“8”;一个是用于返回响应的“echo-reply”,类型“type”为“0”。
例如,禁止其它主ping
本机(IP地址192.168.18.130),但是本机可以ping
其它主机:
# iptables -t filter -A INPUT -d 192.168.18.130 -p icmp --icmp-type 8 -j DROP
3.3、显式扩展匹配
显式扩展:必须显示地指明使用的扩展模块进行的扩展。
3.3.1、multiport扩展
multiport扩展,允许在一条匹配规则中,以离散方式定义多个端口,但最多指定15个端口。
例如,允许其它主机访问本机(IP地址192.168.18.130)的80和443端口:
# iptables -A INPUT -d 192.168.18.130 -p tcp -m multiport --dports 80,443 -j ACCEPT
- –source-ports,–sports port[,port|,port:port]…:指定多个源端口;
- –destination-ports,–dports port[,port|,port:port]…:指定多个目的端口;
- –ports port[,port|,port:port]…指定多个端口,匹配源端口、目的端口。
3.3.2、iprange扩展
iprange扩展,允许在一条匹配规则中指明多个IP地址。
例如,仅允许IP地址为192.168.18.1至192.168.18.100的主机访问本机(IP地址192.168.18.130)的22端口:
# iptables -A INPUT -d 192.168.18.130 -p tcp --dport 22 -m iprange --src-range 192.168.18.1-192.168.18.100 -j ACCEPT
# iptables -A INPUT -j DROP #危险~
- –src-range from-to:源ip地址范围;
- –dst-range from-to:目的ip地址范围。
3.3.3、string扩展
string扩展,可以对数据包中的应用层数据做字符串模式匹配检测。
例如,允许访问网站主页文件“index.html”:
# iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string 'GET /index.html' -j ACCEPT
- –algo {bm|kmp}:字符串匹配检测算法。两种算法的性能差别不大;
- –string pattern:要匹配的字符串;
- –hex-string pattern:十六进制字符串。
3.3.4、time扩展
time扩展,将数据包到达的时间与指定的时间范围进行匹配。
例如,在每周六、周日的14点到23点禁止通过SSH登录本机(IP地址192.168.18.130):
# iptables -t filter -A INPUT -d 192.168.18.130 -p tcp --dport 22 -m time --timestart 14:00:00 --timestop 23:00:00 --weekdays Sat,Sun --kerneltz -j DROP
- –datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]];
- –datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]];
- –timestart hh:mm[:ss];
- –timestop hh:mm[:ss];
- –monthdays day[,day…];
- –weekdays day[,day…];
- –kerneltz:用系统时区代替默认的UTC时区。
3.3.5、connlimit扩展
connlimit扩展,允许根据客户端IP地址做并发连接数限制。
例如,允许单个主机同一时间访问本机(IP地址192.168.18.130)22端口的连接数不超过2个:
# iptables -A INPUT -d 192.168.18.130 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP
- –connlimit-upto n:连接数量小于等于n;
- –connlimit-above n:连接数量大于n。
3.3.6、limit扩展
limit扩展,允许根据收发数据包的速率做限制。
例如,每分钟本机(IP地址192.168.18.130)最多仅接收3个ICMP协议请求数据包,多余的数据包拒绝:
# iptables -A INPUT -d 192.168.18.130 -p icmp --icmp-type 8 -m limit --limit 3/minute --limit-burst 5 -j ACCEPT
# iptables -A INPUT -d 192.168.18.130 -p icmp --icmp-type 8 -j REJECT
- –limit rate[/second|/minute|/hour|/day]:接收数据包的速率;
- –limit-burst number:要匹配的最大初始数据包数。例子中值为5,即刚开始可以接收5个,超过限制的数据包被拒绝。
3.3.7、state扩展
state扩展,根据连接追踪机制检查连接的状态,作出相应的处理动作。
连接追踪(conntrack)机制,追踪本机上的请求和响应之间的关系。状态包括以下几种:
- NEW:新发出的请求。起初,连接追踪模板中不存在此连接的相关信息条目,因此将其识别为第一次发出的请求;
- ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前,所进行的通信状态;
- RELARED:相关联的连接。比如FTP协议中的命令连接和数据连接之间的关系;
- INVALID:无效的连接;
- UNTRACKED:未进行追踪的连接。
例如,通过state扩展限制其它主机仅能访问本机(IP地址192.168.18.130)的TCP协议22和80端口:
# iptables -F #用于清空规则
# iptables -A INPUT -d 192.168.18.130 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 192.168.18.130 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT
# iptables -P INPUT DROP #设置INPUT链的默认策略为DROP
# iptables -P OUTPUT DROP #设置OUTPUT链的默认策略为DROP
# iptables -P FORWARD DROP #设置FORWARD链的默认策略为DROP
调整连接追踪功能所能容纳的最大连接数:/proc/sys/net/nf_contrack_max
已经追踪到的并记录下来的连接:cat /proc/net/nf_conntrack
不同协议的连接追踪时长:ls /proc/sys/net/netfilter/