在iptables(一)中已经介绍了 iptables 的表、链的概念和关系,以及表的基本操作。
本次 iptables(二)中将介绍iptables 的匹配方式和常用的扩展模块。
一、基本匹配
基本匹配条件:原地址 Source IP 和 目标地址 Destination IP
1. 使用-s
参数时批量添加 ip
示例:
root@kvm:~# iptables -t filter -I INPUT -s 10.1.1.2,10.1.1.3 -j DROP
root@kvm:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 29 packets, 2202 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 10.1.1.3 0.0.0.0/0
0 0 DROP all -- * * 10.1.1.2 0.0.0.0/0
5 420 DROP all -- * * 192.168.55.132 0.0.0.0/0
-s
添加多个 IP 时中间使用逗号","分割即可
2. 使用-s
参数添加网段
示例:
root@kvm:~# iptables -t filter -I INPUT -s 10.1.2.0/10 -j ACCEPT
root@kvm:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 9 packets, 636 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 10.0.0.0/10 0.0.0.0/0
0 0 DROP all -- * * 10.1.1.3 0.0.0.0/0
0 0 DROP all -- * * 10.1.1.2 0.0.0.0/0
5 420 DROP all -- * * 192.168.55.132 0.0.0.0/0
3. 使用-s
时可以对条件取反,在-s
前添加叹号"!"即可
示例:
root@kvm:~# iptables -t filter -I INPUT ! -s 10.1.1.2 -j ACCEPT
root@kvm:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13 932 ACCEPT all -- * * !10.1.1.2 0.0.0.0/0
- 规则解释:
规则的意思只要报文原地址不是10.1.1.2都接受。
现在使用10.1.1.2去 ping iptables测试机发现是可以 ping 通的。
因为没有规则说明当 ip 地址是10.1.1.2的时候去做什么动作,所以当10.1.1.2通过 INPUT 链时,是找不到相应规则的,它执行的是filter 表 INPUT 链默认ACCEPT规则。
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
也就是说当你的filter 表 INPUT 链默认是 DROP 时,10.1.1.2的机器将不能 ping 通本机。
- 错误理解:
只要报文原地址是10.1.1.2就不接受。这样理解是不对的
4. 使用-d
参数定制目标 IP 地址规则
示例:
iptables 测试机 ip 信息
root@kvm:~# ifconfig | awk '/inet addr/{print $1,$2}'
inet addr:192.168.55.128
inet addr:192.168.55.129
inet addr:192.168.55.130
inet addr:127.0.0.1
inet addr:10.0.80.1
添加禁止192.168.55.132地址到192.168.55.128地址的数据请求
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -d 192.168.55.128 -j DROP
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 82 packets, 6368 bytes)
pkts bytes target prot opt in out source destination
2 168 DROP all -- * * 192.168.55.132 192.168.55.128
-s
与-d
是与的关系,如下例:
只有从192.168.55.132地址到192.168.55.128地址的数据才被接受
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -d 192.168.55.128 -j ACCEPT
5. 使用-p
参数定制协议类型规则
示例:
添加禁止192.168.55.132地址到192.168.55.128地址 tcp 数据请求
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.128 -d 192.168.55.129 -p tcp -j REJECT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 192.168.55.128 192.168.55.129 reject-with icmp-port-unreachable
6. 使用-i
参数定制网卡接口规则
-
-i
只能用于 PREROUTING、 INPUT、 FORWARD 这三个链,因为只有这三个链可以判断数据从那个网卡流入
iptables -t filter -I INPUT -i eth2 -p icmp -j DROP
-
-o
只能用于 FORWARD、 OUTPUT、 POSTROUTING这三个链,因为只有这三个链可以判断数据从那个网卡流出
iptables -t filter -I INPUT -o eth2 -p icmp -j DROP
二、 扩展匹配
扩展条件是netfilter 中的一部分,只是以模块的形式存在,要使用这个,则需要指定依赖模块。
iptables 指定模块参数:
参数 | 说明 | 示例 |
---|---|---|
--match -m match |
指定扩展模块 | iptables -t filter -I INPUT -s 192.168.55.132 -p tcp -m tcp --dport 22 -j REJECT 示例:禁止这个 ip 使用tcp 22端口访问, -m tcp :是加载 tcp 扩展模块; |
1. TCP模块端口规则
参数说明
参数 | 说明 | 示例 |
---|---|---|
--dport |
tcp扩展模块中的-目标端口 | --dport 22; --dport 22:50 |
--sport |
扩展模块中的-源端口 | --sport 22; --sport 22:50 |
--tcp-flags |
匹配TCP报文头标志位 | --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN |
参数 --tcp-flags
示例:
# iptables -f filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
# iptables -f filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT
--tcp-flags中有两部分:
- “SYN,ACK,FIN,RST,URG,PSH ”: 需要匹配的标志位列表
- “SYN”:在第一部分 “SYN,ACK,FIN,RST,URG,PSH ”中 SYN 值必须是1,其他标志位必须是0
上面两种写法是一样的。
2. multiport模块
指定一个连续不到的的端口
参数说明
参数 | 说明 | 示例 |
---|---|---|
--dports |
同时定义多个不同的不连续的源端口 | iptables -t filter -I INPUT -s 10.0.1.2 -p tcp -m multiport --dport 22,36,80 -j DROP |
--sports |
同时定义多个不同的不连续(也可以指定连续的)的目标端口 | iptables -t filter -I INPUT -s 10.0.1.2 -p tcp -m multiport --sport 22,80:88 -j DROP 80:88指的是80到88的所有端口 |
3. iprange 模块
指定一个连续的IP地址范围
参数说明
参数 | 说明 | 示例 |
---|---|---|
--src-range |
指定连续的原地址范围 | iptables -t filter -I INPUT -m iprange --src-range 10.1.1.2-10.1.1.10 -j DROP |
--dst-range |
指定连续的目标地址范围 | iptables -t filter -I INPUT -m iprange --dst-range 10.1.1.2-10.1.1.10 -j DROP |
在--src-range
或--dst-range
这个前面加"!"可以取反
4. stging 模块
可以指定要匹配的字符串,如果报文中包含对应的字符串,则复合匹配条件。
参数说明:
参数 | 说明 | 示例 |
---|---|---|
--algo bm |
指定对应的算法bm 、kmp
|
iptables -t filter -I INPUT -m string --algo bm --string "xxx" -j DROP |
--string xxx |
指定要匹配的字符串 | iptables -t filter -I INPUT -m string --algo bm --string "xxx" -j DROP |
5. time模块
可以根据时间段去匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件
参数说明:
参数 | 说明 | 示例 |
---|---|---|
--timestart time |
开始时间 | iptables -t filter -I INPUT -m time --timestart 09:00:00 --time stop 10:00:00 -j DROP |
--timestop time |
结束时间 | iptables -t filter -I INPUT -m time --timestart 09:00:00 --time stop 10:00:00 -j DROP |
--weekdays week |
指定每周的周几,指定多个用逗号分开。 | iptables -t filter -I INPUT -p tcp --dport 80 -m time --weekdays 6,7 -j ACCEPT 示例中只允许每周的周6日进行 tcp 80端口访问 |
--monthdays day |
指定每个月的第几天,指定多天用逗号分开。 | iptables -t filter -I INPUT -p tcp --dport 80 -m time --monthdays 20,25 -j ACCEPT 示例中只允许每月的20日和25日进行 tcp 80端口访问 |
--datestart date |
指定开始日期 | iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2017-12-24 --datestop 2019-01-27 -j REJECT |
--datestop date |
指定结束日期 | iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2017-12-24 --datestop 2019-12-27 -j REJECT |
-
--weekdays
和--monthdays
联合使用
#iptables -t filter -I INPUT -p tcp --doprt 80 -m time --weekdays 5 --monthdays 10,11,12,13,14,15,16 -j DREP
表示只有在周五是10~16号时拒绝访问
-
--weekdays
和--monthdays
也可以使用"!"取反。
6. connlimit模块
可以限制每个IP 地址同时连接到 server 端的连接数量。
不指定 IP 则表示,是针对每个请求 IP进行限制
参数说明:
参数 | 说明 | 示例 |
---|---|---|
--connlimit-above number |
限制IP 的连接数量上限 | iptables -f filter -I INPUT -p tcp -dport 22 -m connlimit --connlimit-above 2 -j REJECT 示例:只允许每个 IP 有两个 ssh 连接到服务器 |
--connlimit-mask |
限制某类网段的连接数量 | iptables -f filter -I INPUT -p tcp -dport 22 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j REJECT 示例:限制 C 类网段的连接次数,24转换就是255.255.255.0, 也就是254个 ip 有2个可以访问 |
7. limit模块
可以限制单位时间内流入包的数量
可以用秒、分、小时、天作为单位进行限制
参数说明:
参数 | 说明 | 示例 |
---|---|---|
--limit number/type |
显示单位时间内流入包的数量 /second; /minute; /hour; /day |
下面--limit 示例 |
--limit-burst |
空闲时可放行包的数量,默认5(类似一个连接池,里面默认有5个连接,所以当请求来的时候先去池里面找,如果有就拿去用,当5个都用完时,每过一段时间会再次生成一个。 |
如: --limit 3/second 表示每3秒产生一个连接。--limit 30/minute 每分钟产生30个) |
-
--limit
示例
首先添加一个每分钟只允许10次 ping 的规则。也就是每6秒放行一个包。
root@kvm:~# iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
root@kvm:~# iptables -vnL NIPUT
Chain INPUT (policy ACCEPT 14 packets, 1057 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5
然后在一台机器上 ping 这个 iptables 测试机。会发现 ping 这个完全不受影响。
实际上被放行的规则已经和定义的规则匹配上,为什么不应该放行的规则被放行了呢?因为被表的默认规则匹配到了,且默认规则正好是 ACCEPT,所以相当于所有的 ping 都被放行了。
解决办法,修改表中链的默认规则,或者添加一个新的规则来匹配其他 ping;
root@kvm:~# iptables -t filter -A INPUT -p icmp -j REJECT
root@kvm:~# iptables -vnL
Chain INPUT (policy ACCEPT 11 packets, 784 bytes)
pkts bytes target prot opt in out source destination
8 672 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5
0 0 REJECT icmp -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
再次 ping iptables 测试机是发现前5个ping 没有被控制,因为参数--limit-burst
默认值是5,提前保留了5个可放行的包数,所以前5个 ping 并不受影响。
8. udp模块
用户匹配 upd 报文的源端口与目标端口
参数说明:
参数 | 说明 | 示例 | |
---|---|---|---|
--sport |
源端口(可以设置连续端口) | iptables -t filter -I INPUT -p udp -m udp --dport 13 -j ACCEPT | |
--dporr |
目标端口(可以设置连续端口) | iptables -t filter -I INPUT -p udp -m udp --dport 80:88 -j ACCEPT | 、、 |
8. icmp模块
icmp 报文类型: (百度百科)
类型 | 类型代码 | 说明 |
---|---|---|
0 | 0 | Echo Reply——回显应答(Ping应答) |
3 | 0 | Network Unreachable——网络不可达 |
3 | 1 | Host Unreachable——主机不可达 |
3 | 2 | Protocol Unreachable——协议不可达 |
3 | 3 | Port Unreachable——端口不可达 |
3 | 4 | Fragmentation needed but no frag. bit set——需要进行分片但设置不分片比特 |
3 | 5 | Source routing failed——源站选路失败 |
3 | 6 | Destination network unknown——目的网络未知 |
3 | 7 | Destination host unknown——目的主机未知 |
3 | 8 | Source host isolated (obsolete)——源主机被隔离(作废不用) |
3 | 9 | Destination network administratively prohibited——目的网络被强制禁止 |
3 | 10 | Destination host administratively prohibited——目的主机被强制禁止 |
3 | 11 | Network unreachable for TOS——由于服务类型TOS,网络不可达 |
3 | 12 | Host unreachable for TOS——由于服务类型TOS,主机不可达 |
3 | 13 | Communication administratively prohibited by filtering——由于过滤,通信被强制禁止 |
3 | 14 | Host precedence violation——主机越权 |
3 | 15 | Precedence cutoff in effect——优先中止生效 |
4 | 0 | Source quench——源端被关闭(基本流控制) |
5 | 0 | Redirect for network——对网络重定向 |
5 | 1 | Redirect for host——对主机重定向 |
5 | 2 | Redirect for TOS and network——对服务类型和网络重定向 |
5 | 3 | Redirect for TOS and host——对服务类型和主机重定向 |
8 | 0 | Echo request——回显请求(Ping请求) |
9 | 0 | Router advertisement——路由器通告 |
10 | 0 | Route solicitation——路由器请求 |
11 | 0 | TTL equals 0 during transit——传输期间生存时间为0 |
11 | 1 | TTL equals 0 during reassembly——在数据报组装期间生存时间为0 |
12 | 0 | IP header bad (catchall error)——坏的IP首部(包括各种差错) |
12 | 1 | Required options missing——缺少必需的选项 |
13 | 0 | Timestamp request (obsolete)——时间戳请求(作废不用) |
14 | 0 | Timestamp reply (obsolete)——时间戳应答(作废不用) |
15 | 0 | Information request (obsolete)——信息请求(作废不用) |
16 | 0 | Information reply (obsolete)——信息应答(作废不用) |
17 | 0 | Address mask request——地址掩码请求 |
18 | 0 | Address mask reply——地址掩码应答 |
参数说明:
参数 | 说明 | 示例 |
---|---|---|
--icmp-type |
匹配 icmp 报文的具体类型 | iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT |