持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
1.Iptables防火墙扩展模块的匹配规则
Iptables的扩展模块有以下几种:
- multiport:多端口匹配模块。
- iprange:多IP范围匹配模块
- string:
- time:
- icmp:
- connlimit:
- limit:
- tcp-flags:
2.Iptables防火墙multiport模块扩展匹配规则
在前面做端口匹配的时候都是通过--dport
参数来指定一个端口或者连续的一组端口,如果我们想同时对多个不连续的端口添加防火墙规则,那么--dport
参数就无法实现了。
基于这种情况,防火墙提供了-m
参数指定扩展模块,通过multiport
参数就可以同时指定多个不连续的端口号,一条防火墙规则最大支持同时添加15个不同的端口号。
案例:仅允许192.168.20.21访问本机的80、443、20、21、22端口,其余所有主机都不允许访问本机的80、443、20、21、端口。
1)编写防火墙规则
在INPUT链的filter表中添加对应的规则。
1.允许192.168.20.21访问本机的80、443、20、21、22
[root@jxl-1 ~]# iptables -t filter -I INPUT -s 192.168.20.21 -d 192.168.20.20 -p tcp -m multiport --dports 20,21,22,80,443 -j ACCEPT
#还有另一种写法
[root@jxl-1 ~]# iptables -t filter -I INPUT -s 192.168.20.21 -d 192.168.20.20 -p tcp -m multiport --dports 20:22,80,443 -j ACCEPT
2.拒绝所有主机访问本机的TCP端口
[root@jxl-1 ~]# iptables -t filter -A INPUT -p tcp -m multiport --dports 20,21,80,443 -j DROP
2)查看添加的规则
允许192.168.20.21主机访问本机的20,21,22,80,443端口,其余所有主机都不允许访问本机的20,21,80,443端口。
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 653 packets, 601K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT tcp -- * * 192.168.20.21 192.168.20.20 multiport dports 20,21,22,80,443
2 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 20,21,80,443
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 676 packets, 993K bytes)
num pkts bytes target prot opt in out source destination
[root@jxl-1 ~]#
3)测试效果
随便选择一个端口,以80为例,可以看到192.168.20.21可以正常使用,而192.168.20.22则无法使用。
4.2.Iptables防火墙iprange模块扩展匹配规则
iprange模块可以同时设置多个IP或者设置IP的某一段连续的范围,通过iprange模块可以对多个来源地址同时设置策略。
iprange模块的参数:
--src-range
:指定源地址范围。--dst-range
:指定目标地址范围。! --src-range
:非指定的源地址。! --dst-range
:非指定的目标地址。
可以在参数前面加!号表示去反。
案例:源地址范围为192.168.20.10-192.168.20.19的IP地址都不允许ping192.168.20.20这个目标地址。
1)编写防火墙规则
在INPUT链的filter表中添加对应的规则。
1.无需指定目标地址
[root@jxl-1 ~]# iptables -t filter -I INPUT -p icmp -m iprange --src-range 192.168.20.10-192.168.20.19 -j DROP
2.也可以指定目标地址,效果都一样
[root@jxl-1 ~]# iptables -t filter -I INPUT -p icmp -m iprange --src-range 192.168.20.10-192.168.20.19 --dst-range 192.168.20.20 -j DROP
2)查看添加的规则
禁止192.168.20.10-192.168.20.19的源地址请求的ICMP协议数据报文进入本机。
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 2033 packets, 2002K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0 source IP range 192.168.20.10-192.168.20.19
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 2072 packets, 3079K bytes)
num pkts bytes target prot opt in out source destination
3)测试效果
登陆192.168.20.10这个服务器中ping192.168.20.20,发现ping不通,登陆192.168.20.21这个服务器,发现能ping通192.168.20.20。
3.Iptables防火墙string模块扩展匹配规则
String模块的作用是来匹配请求报文中指定的字符串,经常应用于拦截用户访问某些网站的场景,将防火墙当做路由器使用,例如上班时间不允许用户访问淘宝网站等等场景。
String模块的常用参数:
--string pattern
:指定要匹配的字符串。! --string pattern
:反向匹配。--algo
:指定匹配的查询算法,有bm和kmp两种算法。
可以在参数前面加!号表示去反。
案例:当用户请求的数据报文中包含taobao.com,则拒绝通行,其余的正常放行。
用户通过防火墙流出然后访问目标端,因此需要在OUTPUT链添加规则。
1)首先来准备含有taobao.com数据报文的WEB网站。
1.安装httpd
[root@jxl-1 ~]# yum -y install httpd
[root@jxl-1 ~]# echo hahaha > /var/www/html/ha.html
[root@jxl-1 ~]# echo taobao.com > /var/www/html/taobao.html
[root@jxl-1 ~]# systemctl restart httpd
2.正常的两个页面
[root@jxl-1 ~]# curl 127.0.0.1/ha.html
hahaha
[root@jxl-1 ~]# curl 127.0.0.1/taobao.html
taobao.com
2)编写防火墙规则,拒绝数据包中包含taobao.com内容的数据包。
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp -m string --string "taobao.com" --algo bm -j DROP
3)查看设置的防火墙规则。
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 7011 packets, 6693K bytes)
num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 7310 packets, 11M bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "taobao.com" ALGO name bm TO 65535
4)测试效果,发现hahaha的页面可以正常访问,taobao.com页面的请求将被拦截。
.4.Iptables防火墙time模块扩展匹配规则
time模块的作用是根据时间范围来匹配报文,例如在上午的8点30到下午18点30关于浏览淘宝的报文都拒绝。
time模块的常用参数:
--timestart
:指定开始时间。--timestop
:指定结束时间。--monthdays
:指定一个月中的某一天。--weekdays
:指定一周中的周期,例如1-7。--kerneltz
:使用内核时区的时间。
可以在参数前面加!号表示去反。
time模块默认使用的实际UTC时间,UTC时间比我们正常的时间慢8小时。
案例:在周一到周五的8:00到18:00禁止访问淘宝网站。
此案例也是将防火墙看做了是路由器,在流量流出时定义防火墙规则,也就是在防火墙的OUTPUT链定义规则。
1)编写防火墙规则
在周一到周五的8点到18点时间段,所有发往taobao.com的TCP 80端口的报文都会被拒绝。
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp -d taobao.com --dport 80 -m time --timestart 00:00 --timestop 10:00 --weekdays 1,2,3,4,5 -j DROP
2)查看设置的防火墙规则
淘宝网的地址有很多,写入防火墙后,会将解析出来的多个IP地址都写入到表中,如下图所示。
3)测试效果
在周一到周五的早上8点到晚上18点的范围之间,再想访问淘宝网,则会被拦截。
5.Iptables防火墙icmp模块扩展匹配规则
在前面做icmp协议的DROP动作规则时,其他主机确实无法ping通本机了,但是本机也同样无法ping通别的主机,那是因为拒绝动作是在INPUT链完成的,ping是有请求和回应的,INPUT链已经把icmp协议拒绝了,无法回应,就导致本机也无法ping通其他主机。
icmp模块常用的参数:
-
--icmp-type
:指定icmp协议的类型,icmp协议有请求和回应两种类型,其他主机ping本机属于请求类型,本机ping其他主机属于回应类型。- echo-request:请求类型,ID为8。
- echo-reply:回应类型,ID为0。
可以在参数前面加!号表示去反。
案例:禁止其他主机ping本机,本机依旧可以ping其他主机。
1)编写防火墙规则
[root@jxl-1 ~]# iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j DROP
2)查看设置的防火墙规则
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 962 packets, 843K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 945 packets, 1266K bytes)
num pkts bytes target prot opt in out source destination
3)测试效果
其他主机无法ping通本机,本机依旧可以ping通其他主机。
6.Iptables防火墙connlimit模块扩展匹配规则
connlimit模块的作用是限制请求报文对特定服务的并发连接数限制的,例如Telnet服务,默认情况下没有并发连接数的限制,可以允许n个客户端同时连接,如果应用了connlimit模块,可以对并发连接数进行限制。
connlimit模块常用参数:
--connlimit-upto
:如果现有连接数小于或等于设置的并发连接数值,那么就放行。--connlimit-above
:如果现有连接数大于设置的并发连接数值,那么就放行。
案例:每个客户端主机仅允许同时对本机发起两个ssh连接。
数据流入的操作,在INPUT链的filter表添加相应的规则。
1)编写具体的防火墙规则
[root@jxl-1 ~]# iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
2)查看设置的规则
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 52358 packets, 43M bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 #conn src/32 > 2 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 52598 packets, 68M bytes)
num pkts bytes target prot opt in out source destination
3)测试效果
同时登陆两个ssh没问题,第三个时就提示无法连接了。
7.Iptables防火墙limit模块扩展匹配规则
limit模块的作用是针对报文的速率进行限制,限制的单位有秒、分钟、小时、天等,例如一分钟内只接收10个请求报文,多余的报文则会被丢弃。
limit模块的常用参数:
--limit rate[/second|/minute|/hour|/day]
:指定限制的平均速率单位,以秒(s)、分(m)、时(h)、天为单位,默认是3小时。--limit-burst
:要匹配的最大初始包的数量,例如1分钟内限制10个请求报文,那么首先一次性会接收我们指定初始化包的数量,剩余请求包按着速率单位来进行接收,默认值为5个报文。
1)限制每分钟接收10个ICMP数据报文
1.先添加一条规则,限制1分钟内只收10个icmp协议的请求报文。
[root@jxl-1 ~]# iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
2.然后添加第二条规则,超出10个报文后,其余的报文全部丢弃。
[root@jxl-1 ~]# iptables -t filter -A INPUT -p icmp -j DROP
3.查看添加的防火墙规则
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 1331 packets, 1111K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5
2 0 0 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 1334 packets, 1844K bytes)
num pkts bytes target prot opt in out source destination
查看效果,可以看到前5个数据包都可以正常接收,那是因为limit默认初始包就是5个,因此没有任何问题,从第六个数据包开始后,每隔6秒才会正常处理一个数据包,因为1分钟限制10次数据包的接收,那就表示6秒收一个,效果如下图所示。
也可以理解为是一开始可以快速通过5个数据报文,后面的数据报文是每分钟通过10个。
2)允许10个数据报文快速通过,然后限制每分钟接收1个个ICMP数据报文
实现思路和1)中一模一样,只不过就是调整一下初始包的数量。
1.先添加一条规则,限制1分钟内只收10个icmp协议的请求报文。
[root@jxl-1 ~]# iptables -t filter -I INPUT -p icmp -m limit --limit 1/m --limit-burst 10 -j ACCEPT
2.然后添加第二条规则,超出10个报文后,其余的报文全部丢弃。
[root@jxl-1 ~]# iptables -t filter -A INPUT -p icmp -j DROP
效果如下,首先发送了10个数据包正常接收,剩下的数据包每隔1分钟接收1个。
3)限速案例,限制网络传输的带宽不可以超过500k/s
限速如何通过limit模块来实现呢?其实也很简单,我们可以计算出1个数据包的大小,然后用500k的大小除以数据包的大小,得出500k能换算出多少个数据包,例如是300个,那么最后设置1秒钟接收的数据包的数量为300个,就可以实现每秒的传输速率带宽在500k左右。
一个数据包的大小大概在1500字节。
公式:(限制的带宽速率*1000)/(单个数据包的大小)
500k的限速,每秒可限制的数据包数量大概为(500*1000/150 = 300个)300个。
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp -m limit --limit 300/s -j ACCEPT
[root@jxl-1 ~]# iptables -t filter -A OUTPUT -p tcp -j DROP
速率带宽多多少少是由落差的,如果就想限制在500k以内,可以根据测试的结果来调整每秒数据包的效果,如下图所示,拉取文件的速率为327k/s,此时数据包的数量我是设置的120个。
8.Iptables防火墙tcp-flags模块扩展匹配规则
tcp-flags模块的作用是判断TCP协议数据报文标志位的返回值的,在TCP的三次握手中,第一次握手客户端向服务器发送syn=1的数据报文,第二次握手服务端向客户端发送sync和ack=1的报文,第三次握手客户端向服务端发送ack=1的报文。
tcp-flags模块就是来判断发送报文中指定的标志位是否等于1,并且该条报文中只包含指定的标志位,否则就拒绝通行,例如我们指定的标志位是SYN,那么该条报文中就只能包含SYNC,如果再包含ACK,那么就不放行,并且标志位的值要为1。
案例: 只允许其他客户端发送TCP请求报文到本机,本机响应可以,但是本机不可向其他主机发送TCP请求报文。
首先来分析,"只允许其他客户端发送TCP请求到本机",根据这句话可以明确是在INPUT链添加相应的规则,客户端发起请求一共需要发送2次TCP握手,分别是第一次握手和第三次握手,通过tcp-flags模块确保客户端发送的报文中标志位都是正确的,需要在INPUT链添加3条规则,第一条规则是匹配客户端发送的报文中是否只包含syn标志位,并且值是否等于1,第二条规则是匹配客户端发送的报文中是否只包含ack,并且值是否等于1,如果这两条规则都满足,那么就说明是客户端向服务端发送的请求,最终的动作是允许,第三条规则是拒绝其他标志位的TCP连接请求。
然后来分析"本机只可以响应客户端发起的TCP请求,但是本机不可以向其他客户端发送请求",根据这句话可以明确出规则是要添加在OUTPUT链的,我们只需要在OUTPUT链添加上第二次握手所包含的TCP标志位的规则,完成响应客户端的TCP连接请求,最后在添加一条规则,禁止其他的TCP标志位从OUTPUT链发出,也就可以拒绝本机向其他的客户端发起TCP请求。
tcp-flags模块使用的命令格式:--tcp-flags {标志位集合} {要判断哪个标志位等于1}
1)编写具体的防火墙规则
1.添加允许客户端向本机发起TCP请求的规则
#syn=1的标志位规则
[root@jxl-1 ~]# iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST SYN -j ACCEPT
#ack=1的标志位规则
[root@jxl-1 ~]# iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT
#其余的报文都拒绝
[root@jxl-1 ~]# iptables -t filter -A INPUT -j DROP
2.添加本机响应客户端TCP连接请求以及拒绝发起TCP请求的规则
#syn和ack都等于1
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp --sport 22 -m tcp --tcp-flags SYN,ACK,FIN,RST SYN,ACK -j ACCEPT
#ack-1
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp --sport 22 -m tcp --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT
#其余的报文全部拒绝
[root@jxl-1 ~]# iptables -t filter -A OUTPUT -j DROP
2)查看设置的防火墙规则
[root@jxl-1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 82 6416 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x17/0x10
2 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x17/0x02
3 5169 1958K DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 41 4348 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 tcp flags:0x17/0x10
2 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 tcp flags:0x17/0x12
3 293 65316 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
3)查看效果
本机无法发起TCP连接请求。
其他主机可以向本机发起TCP连接。
9.Iptables防火墙state模块扩展匹配规则
state模块也就是conntrack连接追踪的概念,主要作用就是源端到目标端所经过的路由跟踪记录,通过连接跟踪,就可以分析出源端到目标端所经过的地址,然后判断出有哪些是异常的,哪些是正常的。
连接追踪,第一次建立的请求时NEW状态,基于NEW状态之后,在建立的连接是ESTABLISHED状态,RELATED是相关的连接,INVALID是无效的连接。
一个典型的场景:当本机的80端口向其他客户端发起了请求,但是并不是ESTABLISHED状态,而是NEW状态,此时一定是有问题的,WEB 80端口不会向客户端发起请求,只能是ESTABLISHED状态,此时通过iptables防火墙的state模块就可以很好的解决此问题,当追踪的状态不对时,直接拒绝通行。
案例:允许接收远程主机ssh和http的请求(NEW、ESTABLISHED),响应时仅允许本机回应ssh、http的ESTABLISHED的请求。
接收请求时可能是NEW和ESTABLISHED状态,但是响应是一定只有ESTABLISHED状态,否则就是异常现象,在INPUT添加接收时的规则,在OUTPUT链添加响应时的规则。
1)编写防火墙规则
先添加允许特定状态的规则,随后添加拒绝所有的规则
1.添加允许接收ssh和http NEW和ESTABLSHED请求的规则
[root@jxl-1 ~]# iptables -t filter -I INPUT -p tcp -m multiport --dport 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@jxl-1 ~]# iptables -A INPUT -j DROP
2.添加允许响应ssh和http ESTABLSHED请求的规则
[root@jxl-1 ~]# iptables -t filter -I OUTPUT -p tcp -m multiport --sport 22,80 -m state --state ESTABLISHED -j ACCEPT
[root@jxl-1 ~]# iptables -A OUTPUT -j DROP
2)查看设置的防火墙规则
3)查看效果
其他主机向本机发送ssh和http请求,接收正常。
本机主动发起NEW状态,发起异常。