基本匹配条件
取反操作只针对单个IP,与同时指定多个IP的操作不能同时使用。
当一条规则中有多个匹配条件时,这多个匹配条件之间,默认存在“与”的关系。即报文必须同时满足这些条件,才算被规则匹配。
0.0.0.0/0表示所有IP。
ssh协议的传输层属于tcp协议类型。
1.源IP地址
-s匹配报文的源地址,可以同时指定多个源IP,逗号分隔,或指定一个网段。
# 示例如下
iptables -t filter -I INPUT -s 192.168.1.111,192.168.1.118 -j DROP
iptables -t filter -I INPUT -s 192.168.1.0/24 -j ACCEPT
iptables -t filter -I INPUT ! -s 192.168.1.0/24 -j ACCEPT
2.目标IP地址
-d匹配报文的目标地址,可以同时指定多个目标IP,逗号分隔,或指定一个网段。
# 示例如下
iptables -t filter -I OUTPUT -d 192.168.1.111,192.168.1.118 -j DROP
iptables -t filter -I INPUT -d 192.168.1.0/24 -j ACCEPT
iptables -t filter -I INPUT ! -d 192.168.1.0/24 -j ACCEPT
3.协议类型
-p用于匹配报文的协议类型,可以匹配的协议类型tcp、udp、udplite、icmp、esp、ah、sctp等(centos7中还支持icmpv6、mh)。
# 示例如下
iptables -t filter -I INPUT -p tcp -s 192.168.1.146 -j ACCEPT
iptables -t filter -I INPUT ! -p udp -s 192.168.1.146 -j ACCEPT
4.网卡接口
-i用于匹配报文是从哪个网卡接口流入本机,只适用于匹配报文流入的网卡,所以只能用于PREROUTING链,INPUT链,FORWARD链,所以在“数据发出流向”经过的OUTPUT链与POSTROUTING链中不能使用此选项。
# 示例如下
iptables -t filter -I INPUT -p icmp -i eth4 -j DROP
iptables -t filter -I INPUT -p icmp ! -i eth4 -j DROP
-o用于匹配报文将要从哪个网卡接口流出本机,只适用于匹配报文流出的网卡,所以只能用于FORWARD链,OUTPUT链,POSTROUTING链,在“数据发入流向”经过的INPUT链与PREROUTING链中不能使用此选项。
FORWARD链属于“中立国”,能同时使用-i选项和-o选项。
# 示例如下
iptables -t filter -I OUTPUT -p icmp -o eth4 -j DROP
iptables -t filter -I OUTPUT -p icmp ! -o eth4 -j DROP
扩展匹配条件
使用扩展匹配条件,需要依赖一些扩展模块,在使用之前需要使用-m参数指定相应的扩展模块。
当使用-p选项指定了报文的协议时,如果没有使用-m指定对应的扩展模块名称时使用了扩展匹配条件,iptables默认会调用与-p选项对应的协议名称相同的模块。
1.tcp扩展模块
常用的扩展匹配条件如下:
1.1--sport
用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围。
# 示例如下
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22:25 -j ACCEPT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp ! --sport 22 -j ACCEPT
1.2--dport
用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围。
# 示例如下
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 80: -j REJECT
1.3--tcp-flags
--tcp-flags即tcp头中的标志位,用于匹配报文的tcp头的标志位,判断指定的标志位的值是否为1,然后根据标志位的实际情况实现控制功能。
tcp头的结构如下:
在tcp协议建立连接的过程中,需要先进行三次握手,三次握手是依靠tcp头中的标志位进行的。
”SYN,ACK,FIN,RST,URG,PSH SYN”这串字符就是用于配置要匹配的标志位,可以把这串字符拆成两部分去理解,第一部分为”SYN,ACK,FIN,RST,URG,PSH”,第二部分为”SYN”。
第一部分表示:需要匹配报文tcp头中的哪些标志位,即需要匹配报文tcp头中的6个标志位,这6个标志位分别为”SYN、ACK、FIN、RST、URG、PSH”,可以把这一部分理解成需要匹配的标志位列表。
第二部分表示:第一部分的标志位列表中,哪些标志位必须为1,上例中第二部分为SYN,则表示第一部分需要匹配的标志位列表中,SYN标志位的值必须为1,其他标志位必须为0。
所以,上例中的”SYN,ACK,FIN,RST,URG,PSH SYN”表示,需要匹配报文tcp头中的”SYN、ACK、FIN、RST、URG、PSH”这些标志位,其中SYN标志位必须为1,其他的5个标志位必须为0,正是tcp三次握手时第一次握手时的情况。
可以用ALL表示“SYN、ACK、FIN、RST、URG、PSH”
# 示例如下
# 第一次握手
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
# 第二次握手
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT
# 可以用ALL表示“SYN、ACK、FIN、RST、URG、PSH”
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECT
1.4--syn
即”匹配第一次握手“,用于匹配tcp新建连接的请求报文,相当于使用”--tcp-flags SYN,RST,ACK,FIN SYN”
# 示例如下
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --syn -j REJECT
2.multiport扩展模块
multiport扩展只能用于tcp协议与udp协议,即配合-p tcp或者-p udp使用。
常用的扩展匹配条件如下:
-p tcp -m multiport –sports 用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用“逗号”隔开
-p udp -m multiport –dports 用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用“逗号”隔开
# 示例如下
iptables -t filter -I OUTPUT -d 192.168.1.146 -p udp -m multiport --sports 137,138 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport ! --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 80:88 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80:88 -j REJECT
3.iprange模块
如果需要指定一段连续的IP地址范围,匹配报文的源地址或目标地址,则可以用iprange模块。
常用的扩展匹配条件如下:
--src-range:指定连续的源地址范围
--dst-range:指定连续的目标地址范围
# 示例如下
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
iptables -t filter -I OUTPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROP
iptables -t filter -I INPUT -m iprange ! --src-range 192.168.1.127-192.168.1.146 -j DROP
4.string模块
指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件。
常用的扩展匹配条件如下:
--algo:指定对应的匹配算法,可用算法为bm、kmp,此选项为必需选项。
--string:指定需要匹配的字符串
# 示例如下
iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT
iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT
5.time模块
根据时间段匹配报文,如果报文到达的时间在指定的范围以内,则符合匹配条件。
多个条件之间默认存在“与”的关系。
--monthdays与--weekdays可以用"!"取反,其他选项不能取反。
常用的扩展匹配条件如下:
--timestart:用于指定时间范围的开始时间,不可取反
--timestop:用于指定时间范围的结束时间,不可取反
--weekdays:用于指定”星期几”,可取反
--monthdays:用于指定”几号”,可取反
--datestart:用于指定日期范围的开始日期,不可取反
--datestop:用于指定日期范围的结束时间,不可取反
# 示例如下
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time ! --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 5 --monthdays 22,23,24,25,26,27,28 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2017-12-24 --datestop 2017-12-27 -j REJECT
6.connlimit 模块
限制每个IP地址同时连接到server端的连接数量。
当不指定IP时,默认限制的就是“每个客户端IP”,即对单IP的并发连接数限制。
可以用"!"对条件取反。
常用的扩展匹配条件如下:
--connlimit-above:单独使用此选项时,表示限制每个IP的连接数量,即上限数量。
--connlimit-mask:此选项不能单独使用,在使用--connlimit-above选项时,配合此选项,可以针对”某类IP段内的一定数量的IP”进行连接数量的限制。
若--connlimit-mask 24即表示某个C类网段,mask为掩码的意思,转为十进制即为255.255.255.0
# 示例如下
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
# 掩码为255.255.255.0这个段最多包含254个IP的C为网络,最多只能有20个ssh客户端连接到当前服务器,如果1个IP占了20个名额,那剩下的253个IP连一个连接名额也没有了。
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT
7.limit模块
限制报文到达速率,即限制单位时间内流入的包的数量。
可以以秒,分钟,小时,天作为单位进行限制。
常用的扩展匹配条件如下:
--limit-burst:可以指定“空闲时可放行的包的数量”。类比“令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量。
--limit:类比”令牌桶”算法,用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day。
# 示例如下
iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
iptables -t filter -A INPUT -p icmp -j REJECT
8.udp扩展
常用的扩展匹配条件如下:
--sport:匹配udp报文的源地址
--dport:匹配udp报文的目标地址
# 示例如下
iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp -m udp --dport 137:157 -j ACCEPT
可以结合multiport模块指定多个离散的端口
9.icmp扩展
ICMP协议的全称为Internet Control Message Protocol,翻译为互联网控制报文协议,它主要用于探测网络上的主机是否可用,目标是否可达,网络是否通畅,路由是否可用等。
使用ping命令ping某主机时,如果主机可达,对应主机会对ping请求做出回应(此处不考虑禁ping等情况),即发出ping请求,对方则会回应ping请求,虽然ping请求报文与ping回应报文都属于ICMP类型的报文,但如果在概念上细分的话,所属的类型是不同的。发出的ping请求属于类型8的ICMP报文,而对方主机的ping回应报文则属于类型0的ICMP报文,根据应用场景的不同,ICMP报文被细分为如下各种类型。
所有表示”目标不可达”的icmp报文的type码为3,而”目标不可达”又可以细分为多种情况,是网络不可达?还是主机不可达?还是端口不可达?为了更加细化的区分,icmp对每种type又细分了对应的code,用不同的code对应具体的场景。所以,可以使用type/code去匹配具体类型的ICMP报文,比如可以使用”3/1″表示主机不可达的icmp报文。
上图中的第一行就表示ping回应报文,它的type为0,code也为0,可以看出,ping回应报文属于查询类(query)的ICMP报文。从大类上分,ICMP报文还能分为查询类与错误类两大类,目标不可达类的ICMP报文则属于错误类报文。而ping请求报文对应的type为8,code为0。
常用的扩展匹配条件如下:
--icmp-type:匹配icmp报文的具体类型
# 示例如下:
# 禁止所有icmp类型的报文进入本机
iptables -t filter -I INPUT -p icmp -j REJECT
# 只有ping请求类型的报文可以被匹配到,即我们可以ping通别人,但不想让别人ping通我们。
iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT
# type为8的类型下只有code为0的类型,所以可以省略对应的code。
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT
iptables -t filter -I OUTPUT -p icmp -m icmp --icmp-type 0/0 -j REJECT
iptables -t filter -I OUTPUT -p icmp --icmp-type 0 -j REJECT
# 除了能使用对应type/code匹配到具体类型的icmp报文外,还可以用icmp报文的描述名称去匹配对应类型的报文。空格需替换为"-"。
iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT
10.state扩展
state扩展模块可以让iptables实现“链接追踪”机制。
在TCP/IP协议簇中,UDP和ICMP是没有连接的。但对于state模块来说,tcp报文,udp报文,icmp报文都是有连接状态的,即两台机器只要“你来我往”的通信,就算建立了连接。
”连接”其中的报文可以分为5种状态:NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED
NEW:连接中的第一个包,状态就是NEW,可以理解为新连接的第一个包的状态为NEW。
ESTABLISHED:可以把NEW状态包后面包的状态理解为ESTABLISHED,表示连接已建立。
RELATED:从字面上理解RELATED译为关系,举个例子。如FTP服务,FTP服务端会建立两个进程,一个命令进程,一个数据进程。命令进程负责服务端与客户端之间的命令传输(把这个传输过程理解成state中所谓的一个”连接”,暂称为”命令连接”)。数据进程负责服务端与客户端之间的数据传输 ( 把这个过程暂称为”数据连接” )。但是具体传输哪些数据,是由命令去控制的。所以,”数据连接”中的报文与”命令连接”是有”关系”的。那么,”数据连接”中的报文可能就是RELATED状态,因为这些报文与”命令连接”中的报文有关系。
(注:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块nf_conntrack_ftp,如果想要自动加载,可以配置/etc/sysconfig/iptables-config文件)
INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,可以主动屏蔽状态为INVALID的报文。
UNTRACKED:报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接。
上述5种状态的详细解释可以参考如下文章的”User-land states”章节
http://www.iptables.info/en/connection-state.html
怎样判断报文是否是为了回应之前发出的报文?刚才举例中的问题即可使用state扩展模块解决,只要放行状态为ESTABLISHED的报文即可,因为如果报文的状态为ESTABLISHED,那么报文肯定是之前发出的报文的回应,或者更保险起见可以将状态为RELATED或ESTABLISHED的报文都放行,这样,就表示只有回应的报文能够通过防火墙,如果是别人主动发送过来的新的报文,则无法通过防火墙,示例如下。
# 对回应的报文放行
iptables -t filter -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
标签:iptables,匹配,--,报文,tcp,filter,条件,INPUT
From: https://www.cnblogs.com/even160941/p/17581023.html