iptables-扩展匹配模块使用
1、multiport模块
1.1、作用
使用 multiport 模块可以添加多个不连续的端口; -m multiport <--sports|--dports|--ports> 端口1[,端口2,..,端口n]
1.2、示例【10.0.0.10 访问本机端口20、21、80、443 允许通过】
iptables -t filter -I INPUT -m multiport -s 10.0.0.10 -d 10.0.0.200 -p tcp --dports 20:22,80,443 -j ACCEPT iptables -t filter -A INPUT -j DROP
2、iprange模块
2.1、作用
使用 iprange 模块可以指定 "一段连续的IP地址范围",用于匹配报文的源地址或者目标地址, iprange 扩展模块中有两个扩展匹配条件可以使用。 [!] --src-range from[-to]: 原地址范围 [!] --dst-range from[-to]: 目标地址范围
2.2、示例【10.0.0.5-10.0.0.10 地址段 ping 本机,则丢弃】
iptables -t filter -I INPUT -p icmp -m iprange --src-range "10.0.0.5-10.0.0.10" -j DROP
3、string模块
3.1、作用
使用 string 扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件。 --algo {bm|kmp} :字符匹配的查询算法; [!] --string pattern :字符匹配的字符串;
3.2、示例【应用返回的报文中包含字符 "hello" ,我们就丢弃当前报文,其余正常通过】
3.2.1、安装httpd准备两个页面
yum install httpd -y echo "hello" > /var/www/html/test.html echo "index-oldxu" > /var/www/html/index.html systemctl start httpd
3.2.2、内容包含hello不给出站过滤
# 开放端口 iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT # 内容包含hello不给出站 iptables -t filter -I OUTPUT -p tcp -m string --string "hello" --algo kmp -j DROP
4、time模块
4.1、作用
使用time扩展模块,根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件。 --timestart hh:mm[:ss] :开始时间 --timestop hh:mm[:ss] :结束时间 [!] --monthdays day[,day...] :指定一个月的某一天 [!] --weekdays day[,day...] :指定周一到周天 --kerneltz :使用内核时区而不是 UTC 时间
4.2、示例
4.2.1、拒绝每天 8:30~12:30(00:30~04:30)、13:30~18:30(05:30~10:30) ,任何主机发送 icmp 协议
# utc时间,与本地快8小时,所以需要-8小时 iptables -t filter -I INPUT -p icmp -m time --timestart 00:30 --timestop 04:30 -j DROP iptables -t filter -I INPUT -p icmp -m time --timestart 05:30 --timestop 10:30 -j DROP
4.2.2、限制用户在上班时间段访问优酷、爱奇艺等资源,其他时间可以正常放行
iptables -t filter -I OUTPUT -p tcp -m string --string "taobao.com" --algo kmp -m time --timestart 01:00 --timestop 04:00 -j DROP iptables -t filter -I OUTPUT -p tcp -m string --string "taobao.com" --algo kmp -m time --timestart 06:00 --timestop 10:30 -j DROP iptables -t filter -I OUTPUT -p tcp -m string --string "aqiyi.com" --algo kmp -m time --timestart 01:00 --timestop 04:00 -j DROP iptables -t filter -I OUTPUT -p tcp -m string --string "aqiyi.com" --algo kmp -m time --timestart 06:00 --timestop 10:30 -j DROP
5、icmp模块
5.1、作用
icmp 扩展模块:默认情况当禁止 ping 后,其他主机无法 ping 通本主机,本主机也无法 ping 通其他主机。 假设现在的需求是本主机可以 ping 通其他主机,而其他主机依然无法 ping 同本主机。 [!] --icmp-type {type[/code]|typename}
指定 ICMP 类型: echo-request(8请求)、echo-reply(0回应)
5.2、示例
# 此方法,会禁用所有的icmp,使用服务器不能ping iptables -t filter -I INPUT -p icmp -j DROP # 本机可以往外ping,外部不能往本机ping iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT
6、connlimit模块
6.1、作用
connlimit 扩展模块,限制每个客户端IP地址到服务器的并行连接数。 --connlimit-upto n :如果现有连接数小于或等于n,则匹配。 --connlimit-above n :如果现有连接数大于n,则匹配。
6.2、示例
6.2.1、限制ssh只能同时支持 2个连接
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
6.2.2、限制,每个客户端主机允许100并发连接80/tcp
iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 100 -j DROP
7、limit模块
7.1、作用
limit扩展模块: 针对"报文速率"进行限制。 限制单位时间内流入包的数量,我们可以以秒为单位进行限制,也可以以分钟、小时、天作为单位进行限制。 --limit rate [second|minute|hour|day] :平均匹配的速率 --limit-burst number :超过限制速率的包,允许超过 burst 所设定值,默认可超出5个
7.2、示例
7.2.1、限制主机每分钟接收10个icmp数据包,差不多6s会接收客户端一个数据包
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT iptables -t filter -A INPUT -p icmp -j REJECT
7.2.2、允许icmp瞬间通过10个数据包通过,超过的数据包每分钟仅能通过一个
iptables -A INPUT -p icmp -m limit --limit 1/m --limit-burst 10 -j ACCEPT iptables -A INPUT -p icmp -j REJECT
7.2.3、限制主机传输时的带宽每秒不超过 500k
#(500k * 1000=500000字节/1500=333个包) iptables -t filter -I OUTPUT -p tcp -m limit --limit 300/second -j ACCEPT iptables -t filter -A OUTPUT -p tcp -j DROP
8、tcp-flags模块
8.1、作用
使用 tcp 扩展模块的 "--tcp-flags" 选项,即可对 TCP 的标志位进行匹配,匹配指定标志位的值是否为"1",在tcp协议建立连接的过程中,需要先进行三次握手,而三次握手就要依靠tcp头中的标记位进行。
8.2、三次握手【标记位】解析
8.2.1、第一次握手
第一次:客户端向服务端发起第一次 TCP 连接时,在 TCP 的 flag 标志位中,SYN,RST,ACK,FIN 等标记位仅有 SYN 为1,其他标记位为0。
8.2.2、第二次握手
第二次:服务端向客户端返回ACK,在TCP的flag标志位中,SYN,RST,ACK,FIN等标记位 SYN、ACK为1,其他标记位为0。
8.2.3、第三次握手
第三次:客户端向服务端返回ACK,在TCP的flag标志位中,SYN,RST,ACK,FIN等标记位 ACK为1,其他标记位为0。
8.3、--tcp-flag作用
我们可以通过 --tcp-flag 指明需要匹配哪些标志位,然后再指明这些标志位中,哪些必须为1,剩余的都必须为0。
所以当服务器接收新请求时,SYN标志位必须1,其他的标志位为0,服务端响应这个连接时, SYN、ACK 标志位必须为1,其他的标志位为0。(这样可以避免木马程序通过端口主动向外发送新连接。)
8.4、示例
8.4.1、需求
客户端连接服务端22端口第一次握手必须是客户端发起的,所以SYN必须为1,剩下全部为0。然后服务端可以通过22端口返回对应的报文。
8.4.2、使用tcp-flag设置ssh只能外面链接入来,服务器连接不出去
# 使用"--syn"选项相当于使用"--tcp-flags SYN,RST,ACK,FIN SYN" iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST SYN -j ACCEPT iptables -t filter -A INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT iptables -t filter -A INPUT -j DROP iptables -t filter -I OUTPUT -p tcp --sport 22 -m tcp --tcp-flags SYN,ACK,FIN,RST SYN,ACK -j ACCEPT iptables -t filter -A OUTPUT -p tcp --sport 22 -mtcp --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT iptables -t filter -A OUTPUT -j DROP
9、state模块
9.1、作用
state(conntrack) 连接跟踪,顾名思义,就是跟踪(并记录)连接的状态。
9.2、图解
如上图:是一台 IP 地址为 10.1.1.2 的 Linux 机器,我们能看到这台机器上 有三条 连接: 机器访问外部 HTTP 服务的连接(目的端口 80) 外部访问机器内 FTP 服务的连接(目的端口 21) 机器访问外部 DNS 服务的连接(目的端口 53) 连接跟踪所做的事情就是发现并跟踪这些连接的状态,但这个追踪状态与TCP协议没有关系。它是由内核nefilter在IP层实现,可IP层是无连接、无追踪的,那是如何知道这个IP此前到底有没有来过? 当用户发送请求时,会将用户的请求存储在内核开辟的内存空间中,记录源IP、目标IP、协议、时间,当下次在有用户发起请求,就可以通过内存空间中获取该用户是否来过,以此来实现连接追踪机制。那
9.3、连接追踪的状态分类
9.3.1、New
新请求,内存中不存在此连接的相关条目,因此识别为第一次请求,状态为NEW
9.3.2、ESTABLISHED
NEW状态之后,再次建立连接,由于此前的连接还没有失效,所以追踪后被视为已连接通讯状态,状态为ESTABLISHED
9.3.3、RELATED
相关的连接。比如ftp有两个连接,命令连接和数据连接。命令连接有来有往是一个独立的循环,数据连接有来有往又是另外一个独立的循环,但是两者之间有关系,如果没有命令连接就不可能有数据连接,
所以我们将这种称为”相关联的连接“
9.3.4、INVALID
无效的连接
9.4、应用场景
正常情况下服务器的80端口不会主动连接其他服务器,如果出现了80端口连接其他服务器,那么说明出现了异常行为,或者可以理解为中了木马程序病毒。反弹端口型
木马如果关闭80端口的响应报文,但那样就会造成请求进来无法响应;如果开放80端口,则又会出现异常行为。
所以我们需要从80端口做连接追踪限制,凡事从80端口出去的就必须是对某个请求的响应,也就是说通过80端口出去的状态必须是ESTABLISHED,不能是NEW。
9.5、示例
9.5.1、SSH 与 HTTP 请求 (NEW、ESTABLISHED)配置
需求:允许接收远程主机的 SSH 与 HTTP 请求 (NEW、ESTABLISHED) ,同时仅允许 本机回应SSH以及HTTP的响应(ESTABLISHED),但不允许本机通过22、80端口主动向外发起连接。 # 进站,允许状态:NEW,ESTABLISHED iptables -I INPUT -p tcp -m multiport --dport 80,22 -m state --state NEW,ESTABLISHED -j ACCEPT # 出站,允许状态:ESTABLISHED iptables -I OUTPUT -p tcp -m multiport --sport 80,22 -m state --state ESTABLISHED -j ACCEPT iptables -A INPUT -j DROP
9.5.2、服务器也需要使用SSH连接其他远程主机配置
需求:如果服务器也需要使用SSH连接其他远程主机,则还需要增加以下配置(但不建议) iptables -I OUTPUT 2 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -I INPUT 2 -p tcp --sport 22 -m state --state NEW,ESTABLISHED -j ACCEPT