iptables的规则匹配原理
说明:iptables规则的添加需在指定表下的可用链上,即注意表和链的对应关系
matches 匹配方式
target 处理方法
数据包经Netfilter的过滤匹配流程
/etc/protocol 匹配协议
一、内置的匹配方式
1.icmp应答包
request 请求 Type=8 Code=0
reply 应答 Type=0 Code=0
#iptables -A INPUT -p icmp --icmp-type 8 -j DROP
#禁止别人ping我,但我能ping别人
2.接口匹配方式
接口: -i, -o
Source/Destination Address: -d, -s
协议: -p
--dport 22 或20:24(20到24端口)
--sport 80
-s 源地址 192.168.3.0或192.168.3.0/24
-d 目标地址
#iptables -A FORWORD -i eth1 -o eth0 -p tcp -s 192.168.3.0/24 --dport 21 -j REJECT
#禁止整个网段访问外网FTP服务
二、模块扩展的匹配方式
模块位置:
/lib/modules/kernel_version/kernel/net/netfilter
/lib/modules/kernel_version/kernel/net/ipv4/netfilter
/lib/modules/kernel_version/kernel/net/ipv6/netfilter
1. TCP/UDP协议
TCP协议高级匹配
TCP-Flags的位含义
位1 finish 连接终止信号
位2 synchronize 连接请求信号
位3 reset 立即终止连接
位5 acknowledge 确认应答信号
TCP建立连接 syn--->syn/ack---->ack
TCP终止连接 fin---->ack/fin---->ack
#iptables -A INPUT -p tcp --syn --dport 22 -m state --state NEW -j ACCEPT
#只有第一个数据包包含syn标记的才允许进入
#iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP
#检查所有TCP-Flags
#iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
#只检查SYN和FIN两个标记
UDP协议的高级匹配方式
#iptables -A FORWORD -i eth1 -o eth0 -p udp --dport 53 -j ACCEPT
#允许内网访问外网DNS
2.MAC地址匹配
-m mac就表示用到xt_mac.ko模块
示例:指定特定mac地址的计算机连接到SQL服务器的3306端口
iptables -A INPUT -p tcp --dport 3306 -m mac --mac-source 00:02:B3:0C:23:1B -j ACCEPT
示例2:以文件来匹配MCA地址
/root/mac_list.txt
23:23:43:er:df #wdxs
46:34:34:we:df #jck
下面是shell的角本,可以添加到防火墙角本里:
cat /root/mac_list.txt | while read MAC
do
MAC=$( echo $MAC | awk {print $1} )
iptables -t filter -A FORWORD -i eth1 -o eth0 -m -mac --mac-source $MAC -j ACCEPT
done
3.Multiport匹配
由xt_multiport.ko模块提供功能,同时匹配多个端口(最多15个)。必须与-p tcp或udp结合使用。
如: --dport 21,22,23,25
iptables -A INPUT -p all -m state --state INVALID -j DROP
iptables -A INPUT -p tcp --syn -m state --state NEW -m multiport --dports 21,22,23,25,80,110,443 -j ACCEPT
iptables -A INPUT -p all -m state --state EATABLISHED,RELATED -j ACCEPT
4.匹配数据包的MARK值
由xt_MARK.ko模块提供功能
将所有经过PREROUTING链且目标端口为80的数据包标记一个值,这里是80
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 80
iptables -A FORWORD -p all -m mark --mark 80 -j DROP
5.Owner的匹配
由ipt_owner.ko模块提供功能,仅适用于OUTPUT链和POSTROUTING链之中。
且只能运用于“本机”,无法在网关上限制谁能不能上网。
--uid-owner userid|username #匹配数据包是哪位“使用者”产生的
只允许jck在机上浏览网页,其它人都关闭
iptables -A OUTPUT -p tcp -m owner --uid-owner jck --dport 80 -j ACCEPT
iptables -A OUTPUT -p udp -m owner --uid-owner jck --dport 53 -j ACCEPT
iptables -A OUTPUT -p all -m owner --uid-owner jck --dport 80 -j DROP
--gid-owner groupid|groupname #匹配数据包是哪个“使用者群组”产生的
只允许sales这个组成员浏览网页
iptables -A OUTPUT -p tcp -m owner --gid-owner sales --dport 80 -j ACCEPT
iptables -A OUTPUT -p udp -m owner --gid-owner sales --dport 53 -j ACCEPT
iptables -A OUTPUT -p all -m owner --gid-owner sales --dport 80 -j DROP
特例: ping命令是个suid的执行文件,实际都是以root身份运行,--uid-owner匹配对此失效。
6.IP范围匹配
由ipt_iprange.ko模块提供功能
--src-range 192.168.0.2-192.168.0.61
iptables -A INPUT -m iprange --src-range 192.168.0.2-192.168.0.61 -j DROP
--dst-range 10.60.2.62-10.62.2.151
7.TTL值匹配
-m ttl --ttl-eq 64 #匹配TTL等于64者
iptables -A INPUT -m ttl --ttl-eq 64 -j REJECT
-m ttl --ttl-lt 64 #匹配TTL小于64者
-m ttl --ttl-gt 64 #匹配TTL大于64者
8.数据包状态匹配
由xt_state.ko模块提供。共4种状态:分别是ESTABLISHED、NEW、RELATED及INVALID。
关键在于/proc/net/nf_conntrack文件。它是连接跟踪功能的。
9.AH及ESP协议的SPI值匹配
IPSec加密通信中包含了2个协议:AH(Authentication header 认证头)和ESP(Encapsulating Security Payload 封装安全负载)协议。
AH负责数据包“完整性”验证;ESP负责“加密”操作。
SPI值的匹配是由ipt_ah.ko及xt_esp.ko模块所提供
iptables -A FORWORD -p ah -m ah --ahspi 300 -j ACCEPT
iptables -A FORWORD -p esp -m esp --sepspi 300 -j ACCEPT
10.PATTYPE匹配
在TCP/IP网络中,数据包传输方式有三种:
Unicast: 数据包发送给特定对象。
Broadcast: 广播型数据包。如192.168.0.255
Multicast: 通常运用于“视频”或“音频”广播,特征是Source IP一定介于224.0.0.0/4之间。
由xt_pkttype.ko模块提供功能, 参数分别为multicast、unicast、broadcast。
写法: -m pkttype --pkt-type broadcast
iptables -A FORWORD -i eth0 -p icmp -m pkttype --pkt-type broadcast -j DROP
11.MTU(Length)匹配
MTU:最大传输单元。实体网络层每次所能传输数据大小的上限。以ICMP包为例,MTU=IP包头+ICMP包头+DATA
MSS: Maxitum Segment Size 最大分段大小。MSS=ICMP包头+DATA
iptables -A INPUT -p icmp --icmp-type 8 -m length --length 92 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j DROP
由xt_length.ko模块提供功能,匹配参数:
[!]--length 100 #匹配MTU=100个字节的数据包
[!]--length :100 #匹配MTU小于100个字节的数据包
[!]--length 50:100 #匹配MTU值介于50到100个字节的数据包
要匹配包大小的目的,可以防止网络攻击,比如ICMP本身就可以拿来做攻击用。
比如Linux下可以用:ping -f -s 16384 xx.xx.xx.xx生成大量“超大”数据包,-s 16386是指生成16K字节的ICMP包,撑爆对方带宽。
或者使用:ping -f -s 0 xx.xx.xx.xx生成大量ICMP请求包,消耗对方CPU资源,达到DOS攻击的目的。
12.limit特定数据包重复率的匹配
由xt_limit.ko模块提供的功能。
示例:限制每分钟允许10个ICMP包进入,如果超过每分钟10个以上,则限制为每分钟只能进来6个
iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 6/m --limit-burst 10 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j DROP
--limit-burst 10代表每分钟进入10个包的阈值, --limit 6/m代表每分钟只能进来6个包,其余ICMP包进入第二行被丢弃。
如果停止发送ICMP包,limit何时接触限制呢?方法是将6/m的6和 --limit-burst 10相乘,6 x 10=60,即60秒后解除这个限制。
如果没注明--limit-burst, 则默认--limit-burst 5, 除了--limit 6/m外,还可以用s(second)、h(hour)、d(day).
13.recent特定数据包重复率的匹配
与limit相比,recent功能更加强大。recent提供了一种“先取证,后处理”的机制,比limit匹配更加灵活,可以设计出多样化的匹配方式。
功能是由xt_recent.ko模块提供,包含的参数较多:
--name #设置跟踪的名称,位于/proc/net/xt_recent目录下。且默认只能记录100条,新数据会覆盖旧数据。
[!]--rcheck #仅对中信息做匹配,不对已经存在的数据做任何变更操作。
[!]--seconds second #当事件发生时,仅匹配中前“几秒”内的记录--update,--seconds必须与--rcheck或--update参数共用。
[!]--hitcoount hits #匹配重复发生的次数,必须与--rcheck或--update参数共用。
每分钟只能进入6个ICMP数据包,其它的丢弃
#!/bin/bash
iptables -F
iptables -A INPUT -p icmp --icmp-type 8 -m recnet --name icmp_db --rcheck --second 60 --hitcout 6 -j DROP
iptables -A INPUT -p icmp --icmp-type 8 -m recnet --set --name icmp_db
每分钟只能进入6个ICMP数据包,如果继续发包,那就禁止ICMP包进入
iptables -A INPUT -p icmp --icmp-type 8 -m recnet --name icmp_db --update --second 60 --hitcout 6 -j DROP
iptables -A INPUT -p icmp --icmp-type 8 -m recnet --set --name icmp_db
只有ICMP包值是某一值的时候,才允许进入某些端口
iptables -A INPUT -p icmp --icmp-type 8 -m length --length 128 -m recent --set --name SSHOPEN --rsource -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 15 --name SSHOPEN --rsource -j ACCEPT
如果超过100笔记记录,修改IP记录值
#modprobe xt_recent ip_list_tot=1024
某个IP的记录值超过20
#modprobe xt_recent ip_list_tot=1024 ip_pkt_list_tot=50
14.IP包头内TOS值匹配
早期TOS是用来作为QOS系统的数据包分类依据,但是RFC 2474已经将TOS改为DSCP(Differentiated Services)。
15.使用string模块匹配数据包内承载的数据内容
由xt_string.ko模块提供的功能。可以在网络层位置直接匹配数据包内容,而无需将数据送到应用层位置才能进行匹配。netfilter
但是string的匹配范围仅限于单一数据包内,如果匹配的特征字串分散在2个数据包之内,则该匹配即失效。不过一般的服务请求都可在一个数据包内完成,不必太过担心
匹配参数:
--algo #字符串匹配算法选择。支持两种算法:bm及kmp。
--from、 --to #设置匹配字符串的范围,--from是起点, --to是终点,单位为字节。如--from 10为从
第10个字节开始,如果不设置此参数,默认则匹配整个数据包。
[!]--string #匹配条件,如--string "system32"就是指要匹配“system32”这个字符串。
[!]--hex-string #以16进制方式进行匹配,特别适用于非asc II字符串匹配。如--hex-string |2e2f303132333435|,注意实际匹配条件为2e2f303132333435,但左右要加"|"符号。
示例:
iptables -A FORWARD -i eth0 -o eth1-p tcp -d $WEB_SERVER --dport 80 -m string --algo bm --string "system32" -j DROP
16.使用connlimit模块限制最大连接数
由xt_connlimit.ko模块提供功能,用于以/proc/net/nf_conntrack文件中的数据为依据,来限制一个IP或一个网段同时对目标主机或服务所能建立的最大连接数。
建议先使用Fiddle工具软件()测试网页所需连接数.
iptables -A FORWORD -i eth0 -o eth1 -p tcp --syn -d $web --dport 80 -m connlimit --connlimit-above 30 --connlimit-mask 32 -j DROP
参数:
[!]--connlimit -above XX #指定最大连接数
--connlimit-mask XX #参数为子网掩码,用于匹配范围。如
--connlimit-mask 8代表一个A类子网,
--connlimit-mask 24代表一个C类子网,
--connlimit-mask 25代表1/2个C类子网,
--connlimit-mask 32代表一个单一IP。netfilter
17.connbytes限制每个连接的传输数据量
参数:
--connbytes-mode #packets: 计算数据包的数量; bytes:计算字节数量
--connbyte #“10:":匹配10个以上的单位量;":50":匹配50以下的单位量; "10:50":匹配10~50之间的单位量。
示例:限制用户以HTTP下载20M以上的数据
iptables -A FORWARD -p -tcp -d $WEB_SERVER --dport 80 -m connbytes --connbytes-dir reply --connbytes-mode bytes --connbytes 20971520: -j DROP
--connbytes-dir reply 只统计服务器返回给客户端的数据
--connbytes-mode bytes 以byte数计量数据包
--connbytes 20971520: 指定大于20MB(20*1024*1024=20971520bytes)以上把数据包丢弃。
实际上建议结合QOS进行连接控制,比如当用户传输数据量大于20M时,限制该连接的带宽。
否则用户往往以为是断网而重复发送重试操作,反而浪费掉更多流量。
18.quota模块限制传输总量
匹配方式为”总量累计小于条件时成立“,所以要两行规则才能完成该功能:一条
是quota规则条件,一条是不符合quota规则的处理条件。
允许使用500m流量
iptables -A FORWORD -i eth0 -o eth1 -p tcp --sport 80 -m quota --quota 524288000 -j DROP
iptables -A FORWORD -i eth0 -o eth1 -p tcp --sport 80 -j DROP
此外,一旦限制的量达到预设值后,该记录会永久保存直至防火墙规则被清除为止。
所以要限制每天的下载量,需每天刷新一次防火墙规则。方法是在/etc/crontab中
加入如下一行:
01 1 * * * root /root/firewall.sh
第一个字段指每天凌晨1点,第二个字段指以root身份执行任务, 第三个字段指执
行内容是/root/firewall.sh这个脚本
19.time模块设置规则生效时间
iptables -A FORWORD -o eth1 -d $web -m time --weekdays Mon,Tue,Web,Thu,Fri --timestart 09:00 --timestop 21:00 -j ACCEPT
iptables -A FORWORD -o eth1 -d $web -j DROP
参数:
--datestart, --datestop #格式:YYYY[-MM[-DD[Thh:mm:ss]]],比如2012-09-12T00:00:00 代表2012年9月12日
--timestart, --timestop #格式:hh:mm[:ss],比如下午2点整就是14:00
[!]--monthdays #一个月中的特定日期。格式:day[,day].......,比如1,4,8,12,31,如本月没有31,则time模块会忽略掉31这个值。
[!]--weekdays #一周中的特定日期,格式同上,但是表示为特定拼写,分别是:Mon, Tue, Wed, Thu, Fri, Sat和Sun。
20.connmark匹配mark值
connmark机制是由xt_connmark.ko模块提供的功能,必须与CONNMARK“处理方法”结合使用。
●“mark匹配方式”与“MARK处理方法”的组合:
MARK处理方法所设置的mark值仅对单个数据包有效。因此对连接单一
方向的所有数据包设mark值,必须单独为每个数据包设置;要为双向的
所有数据包设置mark值,就必须借助CONNMARK的功能才有办法实现。
● “connmark匹配方式”与“CONNMARK处理方式”的组合:
CONNMARK处理方式就是为弥补MARK的不足而设计出来的,它对整条
连接设置mark值。一旦设置了某个连接中一个数据包的mark,该连接双
向的所有数据包均会自动设置这个mark值。
MARK标记的值称为nfmark,CONNMARK则称为ctmark。另外,mark匹
配方式只认识nfmark,而connmark则都能识别。
示例:
iptables -A INPUT -m connmark --mark 1 -j DROP
21.conntrack模块识别数据包状态
connntrack模块可视为state模块的加强版,且使用方法与state模块如出一辙,但其功能更强大,语法更灵活
参数:
[!]--ctstate #数据包状态:ESTABLISHED、NEW、RELATED、INVALID、DNAT及SNAT。前四条和state一样,DNAT用来匹配某条连接是否经过DNAT处理,SNAT用来匹配某条连接是否经过SNAT处理。这两种状态匹配仅能适用于执行NAT的主机。
[!]--ctproto #匹配OSI七层中第四层的协议,功能同iptables -p参数,如-p tcp、-p 47等。
[!]--ctorigdst #匹配连接发起方向的目的端IP
[!]--ctrepldst #匹配数据包应答方向的目的端IP
[!]--ctorigdstport #匹配连接发起方向的目的端端口
[!]--ctrepldstport #匹配数据包应答方向的目的端端口
[!]--ctexpire #连接在conntrack(/proc/net/nf_conntrack)的存活时间匹配特定的存活时间 --ctexpire time匹配特定区间的存活时间 --ctexpire time:time
--ctdir #匹配哪个方向的数据包,不设置默认匹配双向数据包。只匹配连接发起方的数据包--ctdir ORIGINAL只匹配数据应答方向的数据包--ctdir REPLY
限制只有192.168.1.0/24网段的主机可以访问FTP服务,我们分别用state和conntrack模块来举例说明:
#!/bin/bash
iptables -F
modprobe nf_conntrack_ftp
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 21 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j DROP
#!/bin/bash
iptables -F
modprobe nf_conntrack_ftp
iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctproto tcp --ctorigsrc -s 192.168.1.0/24 --ctorigdstport 21 --ctstate NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j DROP
22.statistic模块进行比率匹配
由xt_statistic.ko模块提供的功能,在必要时以随机或规律的方式丢弃部分包
随机丢弃50%送到本机的ICMP包
iptables -A INPUT -p icmp -m statistic --mode random --probability 0.5 -j DROP
以规律的方式第10个icmp包丢弃1个
iptables -A INPUT -p icmp -m statistic --mode nth --every 10 -j DROP
参数:
--mode #工作方式。 rendom:随机方式丢弃包; nth:按一定规律丢弃。
--probability #需结合random模式使用, --probability 0.4 代表随机丢弃40%的数据,数值范围0~1
--every #需结合nth模式使用, --every 10 代表每10个包中丢弃一个包。
--packet #需要和nth模式与--every参数结合使用, 如--every 10 --packet 5,iptables命令下达
后statistic会立即开始计数, --packet 5会忽略前5个数据包后才开始计数及丢包。
23.hashlimit模块进行重复率匹配
hashlimit的功能与limit模块功能雷同但功能更强大
iptables -A INPUT -p icmp -m hashlimit \
--hashlimit-name ICMP \
--hashlimit-burst 5 \
--hashlimit-upto 6/minute \
--hashlimit-mode srcip \
--hashlimit-htable-size 8192 \
--hashlimit-htable-expire 60000 \
--hashlimit-htable-gcinterval 5000 \
-j ACCEPT
iptables -A INPUT -p icmp -j REJECT
参数:
--hashlimit-upto #单位时间内符合条件的数据包超过几个,单位时间可为N/second, N/minute, N/hour, N/day
--hashlimit-above #单位时间内符合条件的数据包低于几个,单位时间同上
--hashlimit-burst #设置缓冲区大小
--hashlimit-mode #设置匹配依据,可为:srcip、srcport、dstip、dstport
--hashlimit-dstmask #同上,差别仅为判断对象是目的端IP的网段。
--hashlimit-name #设置hashlimit名称
--hashlimit-htable-size #设置一个内最大记录多少条数据, 不过实际值=设置值*8.假如需要最大值为10000,设置为1250即可
--hashlimit-htable-expire #设置中某条数据的过期时间,其时间计算方式为“从最后一个符合本规则的包进入系统的时间开始累加”,
时间是毫秒。当累加时间大于或等于该设置值时,数据算过期。
--hashlimit-htable-gcinterval #设置数据过期多久后,将数据从库中删除。
24.匹配模块u32
功能强大,允许我们检查数据包内各包头的任意数据,使用方法比较复杂
/ect/protocol
tcp 为6 udp为7 ICMP为1
使用u32来匹配数据包是否为TCP包
iptables -A INPUT -m u32 --u32 6&0xFF=6 -j DROP
使用u32来匹配数据包是否为IPV4协议的数据包
iptables -A INPUT -m u32 --u32 ‘0&0xF0000000>>28=4 -j DROP
iptables -A INPUT -m u32 --u32 12=0x0A0A0F1D -j DROP
iptables -A INPUT -m u32 --u32 12=0x0A0A0F1D && 6&0xFF=1 && 5&0xFF=128 -j DROP
使用u32来匹配数据包内TCP包头的目的端端口为80
iptables -A INPUT -m u32 --u32 ’6&0xFF=6 && 0&0xF000000>>22@0&0xFFFF=80 -j DROP
使用u32来匹配ICMP type 8的数据包
iptables -A INPUT -m u32 --u32 ’6&0xFF=1 && 0&0xF000000>>22@0&0xFF000000>>24=8 -j DROP
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-29596-1.html
小王子
一分鹅肝酱和一份猪大肠
告诉我康师傅是哪的
美军刚出发就有中军舰尾随
也是醉