Netfilter是什么?
Netfilter是Linux的第三代防火墙,因其比之前的两种防火墙ipfwadm及ipchains出色而被Linux组织作为默认的防火墙。Netfilter是自由软件,但在各方面均不逊于商业版的防火墙。
Netfilter与Linux的关系
Netfilter与Linux是两个相互独立的组织,在Linux 2.4早期的版本,并没有包含Netfilter的功能,到后期的版本,才收录了Netfilter的功能。
Netfilter工作的位置
Netfilter以模块的形式存在于linux中,当网卡有数据包传入传出时,出入的数据包都会经由Netfilter穿过。所以Netfilter作为防火墙,能够起到数据包拦截的作用
Netfilter的命令结构
Netfilter要针对数据包进行过滤,就必须要人为制定一些规则,这些规则指示什么样的数据包可以放行,什么样的数据包是危险的,应该丢弃掉,这些规则越来越多之后,就会对其进行分类存储在内存块中,内存就被分为四个表(Table),分别是filter、nat、mangle及raw表,这也是目前Netfilter机制所提供的四大功能。
表 | 链 | 描述 |
---|---|---|
filter | INPUT FORWARD OUTPUT |
filter是Netfilter中最重要的机制,其任务是执行数据包的过滤操作,也就是起到防火墙的作用 |
nat | PREROUTING POSTROUTING OUTPUT |
nat(Network Address Translation, NAT)也是防火墙上一个不可或缺的重要机制,比较通俗的方式来说,其功能就是IP分享器 |
mangle | PREROUTING INPUT FORWARD POSTROUTING |
通过mangle机制来修改经过防火墙内数据包的内容 |
raw | PREROUTING OUTPUT |
负责加快数据包穿过防火墙机制的速度,由此提高防火墙的性能 |
Netfilter的filter机制
filter对数据包的分类如下:
- INPUT类型:网络上其他主机发送给本机进程的数据包就是INPUT类型的数据包
- OUTPUT类型:本机进程所生成的数据包即为OUTPUT类型数据包
- FORWARD类型:数据包对本机而言只是路过而已,那么这就属于FORWARD类型
filter表结构图如下
filter机制的结构图如下:
规则的匹配方式
每条链上都有N条被制定的规则,这些规则该如何匹配呢?first match即优先匹配采用的方式为从INPUT链中的rule-1逐一向下匹配,如果rule-1指明要丢弃数据包,则数据包马上被丢弃,不再执行后面的规则,相反,如果rule-1指明允许数据包进来,则数据包立即进入到本机程序的位置,当前,不管后面的规则内容是什么也都不再重要,这就是优先匹配
不过万一该数据包的特征从INPUT链的rule-1匹配到rule-6均没有匹配成功,该数据包是丢弃还是放行?这就涉及到默认策略(Default Policy)的问题了,请注意,不管链中有多少条规则,默认策略永远在每个链的最底端,而且每个链的默认策略各自独立。linux的默认策略的默认状态是ACCEPT
Netfilter与iptables的关系
Netfilter所需要的规则是存放在内存中的,但是我们如何对这些规则进行添加、删除、修改及查询等操作呢,这个时候必须要有一个针对规则的编辑工具提供给网络管理人员,这个工具就是iptables
iptables工具使用方法
iptables命令可以划分为两个部分,一个是“iptables命令参数”,另一个则是“规则语法”
iptables命令参数
- iptables的命令结构
iptables -t TABLE -操作方式 规则条件 |
---|
语法 | 说明 |
---|---|
-t TABLE | 内置filter、nat、mangle及raw四个表,即Netfilter的四大功能。-t参数的含义是选择我们要操作的功能,如果没有输入,默认则是filter表 |
-操作方式 | 当我们选择好所要使用的表之后,接下来要决定如何操作这个表,在iptables工具中有很多不同的操作方式,在此仅列出必须了解的操作方式,如下: -L: 将所选择的表内容列出 -A: 在指定的链中添加新规则 -F: 将所选择的表内容清除掉 -P: 设置某个链的默认策略 |
规则条件 | 实例规则: -p tcp -j ACCEPT -p udp -j ACCEPT -p icmp -j ACCEPT |
iptables规则语法
- 接口的匹配参数
- 上层协议(upper layer protocol)的匹配参数
- 匹配来源/目的的IP地址
- 匹配来源/目的的端口:使用此参数时,必须指明传输层协议是tcp还是udp,不能单独使用
- 处理方式
使用iptables机制来构建简单的单机防火墙
本节将以下图为例来构建一个简单的单机防火墙。
我们再192.168.0.1主机上分别启用SSH、TELNET、SMTP、WEB以及POP3五项服务。本实例的需求如下:
- 网络上的任何主机都能正常访问192.168.0.1主机上的SSH及TELNET以外的服务。
- 网络上只有192.168.0.200这台主机可正常访问192.168.0.1主机上的所有服务
有了需求后,我们将这些需求转换成iptables看得懂的语法,而在转换成iptables语法时,务必谨记防火墙的原则:先拒绝所有连接,再逐一开放对外提供的服务
单机版防火墙的规则列表:
No. | Commands | Notes |
---|---|---|
1 | iptables -P INPUT DROP | 拒绝所有连接。默认策略最后执行 |
2 | iptables -A INPUT -p tcp -d 192.168.0.1 --dport 25 -j ACCEPT | 放开任何主机对SMTP服务的访问 |
3 | iptables -A INPUT -p tcp -d 192.168.0.1 --dport 80 -j ACCEPT | 放开任何主机对WEB服务的访问 |
4 | iptables -A INPUT -p tcp -d 192.168.0.1 --dport 110 -j ACCEPT | 放开任何主机对POP3服务的访问 |
5 | iptables -A INPUT -p tcp -s 192.168.0.200 -d 192.168.0.1 --dport 22 -j ACCEPT | 只允许192.168.0.200访问SSH |
6 | iptables -A INPUT -p tcp -s 192.168.0.200 -d 192.168.0.1 --dport 23 -j ACCEPT | 只允许192.168.0.200访问TELNET |
Netfilter/iptables的连接跟踪
根据上面的单机防火墙规则,我们让外部所有的主机均能够成功访问SMTP/WEB/POP3服务,只允许192.168.0.200主机访问SSH/TELNET服务。看起来比较完美,但是当单机防火墙作为SSH客户端时,去访问外部主机时可能会失败。因为单机防火墙虽然没有在OUTPUT上设置限制规则,可以让端口号为12345的SSH客户端程序发出连接请求,但当SSH服务器回复数据报时,会因为INPUT链的规则限制(不允许其他主机访问SSH/TELNET)而遭遇拦截。
Netfilter/iptables的连接跟踪功能就可以解决此问题。这个功能有内核xt_state.ko模块所提供。
这个模块在iptables的使用叫做state,称为state模块。state模块定义了数据包的连接状态。分别为ESTABLISHED、NEW、RELATED、INVALID
-
ESTABLISHED: 只要数据包能够成功穿过防火墙,那么之后的所有数据包(包括反向的所有数据包),其状态都会是ESTABLISHED.
iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT 语法 说明 -p tcp 本次所匹配的是tcp协议数据包 -m state 本规则需要引用的state模块 –state ESTABLISHED 给state模块的参数,告知所要匹配的是ESTABLISHED状态的数据包 -j ACCEPT 只有符合以上两个条件的数据包才能进入 -
NEW:NEW与协议无关,其所指的是每一条连接中的第一个数据包
-
RELATED:被动产生的应答数据包,而且这个数据包不属于现在任何的连接(比如tcp连接过程中由路由器产生的ICMP差错报文),RELATED状态的数据包与协议无关,只要应答的数据包是因为本机先送出一个数据包而导致另一条连接的产生,那么这个新连接的所有数据包都属于RELATED状态的数据包。
-
INVALID: 状态不明的数据包,也就是不属于ESTABLISHED、NEW以及RELATED状态的数据包。凡是INVALID状态的数据包皆视为“恶意”的数据包,请将所有INVALID状态的数据包丢弃掉
iptables -A INPUT -p all -m state --state INVALID -j DROP
管理防火墙规则数据库的办法
-
使用iptables工具的规则数据库
命令 说明 service iptables save 命令将Netfilter的规则存储在“/etc/sysconfig/iptables”文件中 chkconfig iptables on 开启自动将“/etc/sysconfig/iptables”文件中的规则载入到Netfilter的各个链中 -
使用shell脚本来管理规则数据库
#bin/bash #===========================< Set Variable >================================ IPT=/sbin/iptables SERVER=192.168.0.1 PARTNER=192.168.0.200 #===========================< Clear Original Rule >=========================== iptables -t filter -F #===========================< Set INPUT RULE >============================= $IPT -A INPUT -p tcp -m state --state INVALID -j DROP $IPT -A INPUT -p tcp -d $SERVER --dport 25 -j ACCEPT $IPT -A INPUT -p tcp -d $SERVER --dport 80 -j ACCEPT $IPT -A INPUT -p tcp -d $SERVER --dport 110 -j ACCEPT $IPT -A INPUT -p tcp -s $PARTNER -d $SERVER --dport 22 -j ACCEPT $IPT -A INPUT -p tcp -s $PARTNER -d $SERVER --dport 23 -j ACCEPT $IPT -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
使用脚本的方式没法直接通过chkconfig iptables on方法来设置开机自启动,不过可以通过下面的方法来设置,假设iptables的脚本名称为/root/firewall.sh
设置firewall.sh的访问权限,一般设置为700 在/etc/rc.d/rc.local文件中加入下列命令: /root/firewall.sh
Netfilter的NAT机制
NAT的结构
- PREROUTING
NAT有很多不同的种类,但不管是哪一种NAT,都是由SNAT及DNAT搭配组合而成的,因此,当我们下发“规则”要去修改数据包的Destinaion IP时,请将规则放入PREROUTING链中 - POSTROUTING
POSTROUTING链的任务是修改数据包内的Source IP - OUTPUT
对本机进程产生并要外送的这些数据包进行DNAT操作
总结
数据入口只能修改目的IP,数据出口只能修改源IP,本机程序往外吐包时,只能在OUTPUT链修改目的IP
NAT的分类
- 一对多NAT(IP分享器)
- 语法实例
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 10.0.1.200 //公司内部主机访问公网服务器时,将内部主机的源ip统一转换为公司统一的公网IP地址10.0.1.200 iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE //如果对外连接为拨号ADSL或者Cable Modem,每次所拿到的公网IP都是不固定的,则可以使用MASQUERADE
- 注意:我们下达的SNAT或DNAT规则时,NAT机制都会自动帮我们判断“另一个方向的应答数据包”,因此,我们只需要下达单一方向的规则即可。
- 多对多NAT
要能够进行多对多NAT的先决条件是你必须拥有多个公网IP,而且这些公网IP必须是连续的。iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 10.0.1.200-10.0.1.205
- 一对一NAT
iptables -t nat -A PREROUTING -i eth0 -d 10.0.1.201 -j DNAT --to 192.168.0.1 iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1 -j SNAT --to 10.0.1.201
- NAPT(Network Address Port Translation)
iptables -t nat -A PREROUTING -i eth0 -p tcp ---dport 80 -j DNAT --to 192.168.0.1:80 iptables -t nat -A PREROUTING -i eth0 -p tcp ---dport 443 -j DNAT --to 192.168.0.1:443
Netfilter的Mangle机制
Mangle是一个比较容易被人忽略的机制,而且Mangle的使用机会并不是很多,但如果需要时又不懂Mangle机制,也是件很麻烦的事,在此还是要说明一下Mangle机制。
当一个数据包“穿过”防火墙时,我们可以通过Mangle的机制来修改数据包的内容
- 修改IP包头的TTL值:
windows的TTL值为128,Linux的TTL值为64,为了增加黑客的入侵难度,可以修改TTL值 - 修改IP包头的DSCP值或对特定的数据包设置特征:
在网络应用中,有时对某些特定通信协议会有特别的需求。例如,在网络电话的应用环境里,我们会希望“不管网络多么拥塞,VoIP的数据包都要能在不延迟的情况下发送出去”。因此有了QOS(Quality of Service)机制,QOS机制可以让我们在有限的带宽中,有效分配不同的带宽给不同的协议来使用。如下图,总带宽是1.5MB/s,我们可以将其分为几部分:512KB/s给HTTP协议来使用、384KB/s给SMTP协议使用、256KB/s给Voice的数据包使用,最后剩下来的带宽则留给未定义的协议。
QOS机制是由两个不同部分组成,其一为“数据包分类器”,其二为“带宽分配器”。当一个数据包进入“数据包分类器”之后,数据包即会被加以分类,被分类后的数据包接着进入“带宽分配器”,再由带宽分配器来决定各类数据包可以使用多少网络带宽,问题是如何分类数据包呢?我们至少可以运用Mangle机制中的两个模块来达到此目的
- 通过IP包内的DSCP值来分类:
我们可以通过Mangle机制来修改IP包内的DSCP值,例如,把DSCP值改为000-01,接着在“带宽分配器”上设置,如果数据包内的DSCP值为0000-01的话,就给予64KB/s的带宽。 - 使用Mangle机制为数据包标识识别码:
Mangle机制可以为特定的数据包来标示不同的识别码,例如,如果数据包内的Source Port 为80,就标示该数据包的识别码为80.接着在“带宽分配器”上设置,如果数据包的识别码为80,就给予512KB/s的带宽,如此也可以达到带宽分类的目的。
Mangle的结构
如果想要改变本机进程所生成的数据包内DSCP值,就必须将规则放置于OUTPUT链中,或是POSTROUTING链之内都可以达到完美的目的,因为本机进程所产生的数据包,除了会流经OUTPUT链之外,也会经过POSTROUTING链,因此,这两个链都可供使用。
- 实施例:
需求:我们希望在QOS机制中将SSH协议的数据包设置为较为优先传输的数据包,因此使用Mangle机制来修改数据包内的DSCP值。iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 43
- 实施例:
需求:将所有进入的tcp连接端口为80的数据包标记为80iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 80
- 实施例:
需求:如果进入FORWARD链的数据包,其MARK值为80的话,就将其丢弃iptables -A FORWARD -p all -m mark --mark 80 -j DROP
Netfilter的完整结构
Netfilter的匹配方式及处理方法
匹配方式
内置的匹配方式
- 接口的匹配方式
iptables -t filter -A FORWARD -i eth0 -o eht1 -j DROP
- Source/Destination Address的匹配
iptables -A FORWARD -i eth0 -o eth1 -p tcp -s 192.168.10.1 -d $WEB_SRV --dport 80 -j DROP
- 协议的匹配方式
iptables -t filter -A INPUT -p icmp -j DROP iptables -t filter -A INPUT -p icmp --icmp-type 8 -j DROP
从模块扩展而来的匹配方式
看完内置匹配方式之后,接下来介绍模块扩展而来的匹配方式。先说明一下,我们并不需要特别去执行加载模块的操作,只要在netfilter规则中使用到模块功能,iptables这个工具便会自动将相应的模块载入,因此不需要考虑这个问题。下面是这些模块在linux系统中的问题
- /lib/modules/kernel_version/kernel/net/netfilter
- /lib/modules/kernel_version/kernel/net/ipv4/netfilter
- /lib/modules/kernel_version/kernel/net/ipv6/netfilter
-
TCP/UDP协议的匹配方式
-
Source Port及Destination Port的匹配:
iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.0.0/24 --dport 21 -j REJECT
- -dport/- -sport除了可以匹配单个端口外,也可以用来匹配一个范围的端口,例如- -dport 20:50即为匹配端口20到端口50之间的范围。
-
TCP-Flags的匹配:
在TCP的包头中有1个字节的空间来存放tcp-flags的状态,而tcp-flags是由8位所构成(旧版本的规格为6位)。下面简单介绍一下较重要的4位字段 标志 说明 位1 Finish 连接终止信号 位2 Synchronize 连接请求信号 位3 Reset 立即终止连接 位5 Acknowledge 确认应答信号 TCP连接建立过程如下:
如果一台主机收到客户端送过来的第一个数据包,其内带有fin标记,系统会如何?(根据tcp协议规定,第一个数据包一定会携带Syn标记,假设有黑客利用此特征,专门发送一个带fin标记的数据包),为了防止发生此类行为,我们将防火墙规则改为:
iptables -A INPUT -p tcp --syn --dport 22 -m state --state NEW -j ACCEPT //Tcp的第一个数据包只有携带syn标记的才允许进入
另一种办法是检查所有TCP-Flags
iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP //检查“所有”TCP-Flags,但只有syn及fin两个标记同时为1时,数据包才会被筛选出来。 iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP //"只检查"TCP-Flags中syn及fin两个标记,而且这两个标记必须同时为1时,数据包才会被筛选出来。
-
UDP协议高级匹配
Source Port及Destination Port的匹配:iptables -A FORWARD -i eth1 -o eth0 -p udp --dport 53 -j ACCEPT
- -dport/- -sport除了可以匹配单个端口外,也可以用来匹配一个范围的端口,例如- -dport 20:50即为匹配端口20到端口50之间的范围。
-
-
MAC地址的匹配
现在很多公司都使用mac地址匹配来限制员工的连接外网行为,因为ip地址基本上都是动态分配的,所以使用mac来匹配是一种手段iptables -A INPUT -p tcp --dport 3306 -m mac --mac-source 00:02:B3:0C:23:1B -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -m mac --mac-source 00:50:56:C0:00:01 -j ACCEPT
-
多端口匹配
有时候多条的语法规则,但仅仅因为端口不一样,我们就需要写多条规则,这样做会显得非常冗余,这个时候就可以使用多端口匹配来达到目的.multiport匹配的目标时端口,因此multiport必须与==-p tcp 或-p udp==结合使用,multiport提供的匹配参数有:- - -dports:匹配目标为Destination Port
- - -sports:匹配目标为Source Port
- - -ports:匹配目标为Destination或Source Port
# old rules iptables -A INPUT -p tcp --syn -m state --state NEW --dport 21 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 22 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 23 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 25 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 80 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 110 -j ACCEPT iptables -A INPUT -p tcp --syn -m state --state NEW --dport 443 -j ACCEPT # new rules iptables -A INPUT -p tcp --syn -m state --state NEW -m multiport --dports 21,22,23,25,80,110,443 -j ACCEPT
-
匹配数据包的MARK值
# 先标记mark值 iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 80 # 匹配指定的mark iptables -A FORWARD -p all -m mark --mark 80 -j DROP
-
Owner的匹配
Owner的匹配方式只适用于OUTPUT链于POSTROUTING链之中。因此,在使用时需要特别注意,Owner可以提供以下两种不同的匹配方式,分别如下:- --uid-owner userid|username:
我们可以使用--uid-owner来匹配数据包是由哪位“使用者”所产生的,由此用来控制特定的使用者只能访问哪些特定的服务。例如,使用jacky在本机上只能使用浏览网页功能。因此,我们在本机上针对jacky这位使用者所产生的所有数据包,只放行DNS以及HTTP即可,规则如下:iptables -A OUTPUT -p tcp -m owner --uid-owner jacky --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp -m owner --uid-owner jacky --dport 53 -j ACCEPT iptables -A OUTPUT -p all -m owner --uid-owner jacky -j DROP
- --gid-owner groupid|groupname:
我们可以使用--gid-owner来匹配数据包是由哪一个“使用者群组”所产生的,由此来控制某一个部门的所有员工可以访问哪些特定的服务。例如,在本机上所有sales这个部门的成员只能使用浏览网页功能。iptables -A OUTPUT -p tcp -m owner --gid-owner sales --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp -m owner --gid-owner sales --dport 53 -j ACCEPT iptables -A OUTPUT -p all -m owner --gid-owner sales -j DROP
测试时不要使用ping命令来测试,因为ping命令都会以root身份来执行,所以匹配–uid-owner将会失效
- --uid-owner userid|username:
-
IP范围的匹配
两个匹配参数- --src-range:
# 匹配“来源地址”范围 iptables -A INPUT -m iprange --src-range 192.168.0.2-192.168.0.62 -j DROP
- --dst-range:
# 匹配“目的地址”范围 iptables -A OUTPUT -m iprange --dst-range 192.168.0.2-192.168.0.62 -j DROP
- --src-range:
-
TTL值的匹配
iptables -A INPUT -m ttl --ttl-eq 64 -j REJECT
-
数据包的状态匹配
iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
-
AH及ESP协议的SPI值匹配
IPSec的加密通信中包含了两个协议,分别是AH(Authentication header,认证头)及ESP(Encapsulating Security Payload,封装安全负载)协议。IPSec由AH以及ESP组合而成。AH负责进行数据包的“完整性验证”,ESP负责数据包的“加密”操作。
不管是AH还是ESP协议,在工作过程中都需要进行“对称式加密”运算,而对称式加密运算一定会需要一把秘钥,这个秘钥是要拿来加密数据用的,假设有三台主机使用IPSec来加密传输数据,这三台主机分别为A、B、C,我们再假设主机A与主机B使用Key-A_B来作为加密秘钥,主机B与主机C使用Key-B_C来作为加密秘钥,因此,主机A的IPSec数据库中会有一把Key-A_B,主机C的IPSec数据库中会有一把Key-B_C,主机B的IPSec数据库中会有一把Key-A_B及Key-B_C,而IPSec为了加快系统查找秘钥的速度,会在IPSec的数据库中为每一把秘钥加上一个索引值,我们称其为SPI值。不管是AH包头还是ESP包头,其内都会含有一个字段叫SPI,而这个SPI值就是告知接收端主机,要使用IPSec数据库中的哪一把秘钥来加密这个数据包。#AH包头内的SPI值为300的允许通过 iptables -A FORWARD -p ah -m ah --ahspi 300 -j ACCEPT #ESP包头内的SPI值为200的允许通过 iptables -A FORWARD -p esp -m esp --espspi 200 -j ACCEPT
-
pkttype匹配
在TCP/IP网络环境中,数据包的传输方式有三种,如下所示:- Unicast: 单播
- Broadcast: 广播
- Multicast: 组播,源IP介于224.0.0.0/4之间
# 过滤掉ping Broadcast数据包 iptables -A FORWARD -i eth0 -p icmp -m pkttype --pkt-type broadcast -j DROP
-
length(MTU值)匹配
- MTU(Maximum Transmission Unit)=(IP包头+IP DATA)
- MSS(Maximum Segment Size)=(IP DATA)
如果我们希望正常的windows系统可以ping到你的主机,那么可以使用如下的语法
# ICMP包头8Byte,Windows icmp DATA部分64Byte,IP数据包包头20Byte,所以MTU=20+8+64 iptables -A INPUT -p icmp --icmp-type 8 -m length --length 92 -j ACCEPT iptables -A INPUT -p icmp --icmp-type 8 -j DROP
匹配的参数 注释 [!] --length 100 匹配MTU值刚好为100个字节的数据包 [!] --length 50 匹配MTU值刚好为50个字节的数据包 [!] --length :100 匹配MTU值小于100个字节的数据包 [!] --length 50:100 匹配MTU值介于50-100个字节的数据包 或许你会觉得奇怪,为何需要匹配ICMP包的大小?这主要是为了防止黑客使用ICMP报文进行恶意攻击。比如在linux下同下使用ping -f -s 16384 xx.xx.xx.xx命令来生成大量“超大型”ICMP数据包来撑爆对方的外网带宽,进而达到瘫痪对方网络的目的。其中-s 选项来指定ICMP所承载的数据大小
-
limit特定数据包重复率的匹配
我们需要对ICMP数据包进行限流,希望每“分钟”允许进入的ICMP包数量是10个,但如果在1分钟内进来了超过10个以上的ICMP包,那么我们就限制每分钟只能进来6个ICMP包# --limit 6/m每分钟只能进来6个数据包 --limit-burst 10则代表每分钟进入10个数据包。 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
如果发送端停止发送ICMP包,limit何时会解除6/m的限制呢?计算方法是将6/m的6和–limit-burst 10相乘,即会得到答案60,也就是说,60s之后limit就会完全解除这个限制。
最后要注意的是如果没写–limit-burst,那么默认值就是–limit-burst 5,除–limit 6/m(minutes)之外,还有s(second)、h(hour)及d(day)可以使用 -
recent特定数据包重复率匹配
参数名称 说明 --name 设置跟踪数据库的文件名 [!] --rcheck 只进行数据库中信息的匹配,并不会对已存在的数据做任何变更操作 [!] --update 如果来源端的数据已存在,则将其更新,若不存在,则不做任何处理 [!] --remove 如果来源端的数据已存在,则将其删除,若不存在,则不做任何处理 [!] --second second 当事件发生时,只会匹配数据库中的前“几秒”内的记录,--seconds必须与--rcheck或--update参数共用 [!] --hitcount hits 匹配重复发生的次数,必须与--rcheck或--update共用 每分钟只能进来6个ICMP数据包,如果超过这个数量就将之丢弃掉,将规则编写如下:
# 在icmp_db中向前搜索60s内的数据做匹配,如果60s内已经超过6个以上的符合记录,则将这个icmp包丢弃 iptables -A INPUT -p icmp --icmp-type 8 -m recent --name icmp_db --rcheck --second 60 --hitcount 6 -j DROP # 将这个数据包的相关信息记录到icmp_db数据库中 iptables -A INPUT -p icmp --icmp-type 8 -m recent --set --name icmp_db
数据库的存储位置/proc/net/xt/recent/icmp_db,recent的数据库之中,默认最多只能记录100条试图入侵的IP。默认数据库存储空间为10个数据包信息,如果需要增加,则使用如下命令重新加载内核模块
[root@fw ~]# modprobe xt_recent ip_list_tot=1024 ip_pkt_list_tot=50
-
IP包头内TOS值的匹配
无 -
使用String模块匹配数据包内所承载的数据内容
参数名称 功能说明 --algo 字符串匹配算法的选择,string模块提供了两种不同的算法,分别是bm(Boyer-Moore)及kmp(Knuth-Pratt-Morris),其中bm算法平均速度会比kmp快,不过,你也不必太在意,因为我们匹配的对象不会太大,因此用哪种都差不多 --from、--to 设置匹配字符串的范围,我们可以使用–from来设置匹配的起点,并以–to来设置匹配的终点,其单位为字节,如–from 10意为从第10个字节开始匹配,如果没有设置这个参数,那么匹配的范围将是整个数据包 [!] --string 匹配条件,如--string “system32”是指要匹配的字符串为system32 [!] --hex-string 匹配条件,但不同于--string参数的地方在于--hex-string是以16进制的方式进行匹配,特别适用于非ascii字符串的匹配,其匹配条件的表示方法为--hex-string “|2e2f303132333435|”, 请注意实际匹配条件为2e2f303132333435,但其左右要使用"|"符号 -
使用connlimit模块限制连接的最大数量
-
使用connbytes模块限制每个连接中所能传输的数据量
-
使用quota模块限制数据传输量的上限
-
使用time模块来设置规则的生效时间
-
使用connmark模块来匹配mark值
-
使用conntrack模块匹配数据包的状态
-
使用statistic模块进行比率匹配
-
使用hashlimit模块进行重复率匹配
-
多功能匹配模块u32
以上16-24的匹配模块由于使用频率较低,暂未做深入举例,感兴趣的可以参考原版书籍查看
处理方法
内置处理方法
- ACCEPT及DROP的处理方法
ACCEPT:允许数据包进入
DROP:丢弃 - QUEUE的处理方法
QUEUE的功能是将符合条件的数据包转发给User Space的应用程序来处理。我们可以在netfilter中指定,如果数据包要送往Mail服务器,那就将数据包转发到User Space上进行病毒过滤以及垃圾邮件的检测操作。iptables -A FORWARD -p tcp -d 192.168.0.1 --dport 25 -j QUEUE
- RETURN的处理方法
主要用于用户定义链中,从用户定义链中返回到上层规则中iptables -I USER_CHAIN 1 -p all -j RETURN
由模块扩展的处理方法
- REJECT的处理方法
REJECT与DROP有点相似。两者的差异在于DROP仅会将数据包丢弃掉,而REJECT在丢掉数据包之后会回送一个icmp包给发送端,由此告诉网络或者服务发生问题,当发送端收到这个icmp包之后,就会终止服务请求的操作。# 自定义回送报文的内容,可选的内容有icmp-net-unreachable/icmp-host-unreachable/icmp-port-unreachable/icmp-proto-unreachable/icmp-net-prohibited/icmp-host-prohibited iptables -A INPUT --p tcp --dport 25 -j REJECT --reject-with icmp-net-unreachable
- LOG的处理方法
指定日志保存的位置:在/etc/rsyslog.conf内加上如下一行:# 将ssh客户端发起的第一个请求报文写入日志中,日志级别为alert,日志前缀SSH_REQUEST iptables -A INPUT -p tcp --syn --dport 22 -j LOG --log-level alert --log-prefix " SSH-REQUEST "
日志保存的位置:/var/log/netfilter# 如果日志是由kernel所生成的,而且某日志级别是alert级的日志,就将日志保存在/var/log/netfilter这个文件中。 kern.=alert /var/log/netfilter
查找时使用命令:grep ’ SSH-REQUEST ’ /var/log/netfilter - ULOG的处理方法
ULOG将日志交给特定的User Space机制来处理。这个User Space程序就是ulogd,详细的可以参考netfilter官方的介绍 - TOS的处理方法
- DSCP的处理方法
# 数据包的来源端口为80,就把这个数据包内的DSCP值改为1 iptables -t mangle -A FORWARD -p tcp --sport 80 -j DSCP --set-dscp 1
- MARK的处理方法
# 将SMTP的数据包的MARK值标记为25 iptables -t mangle -A FORWARD -p tcp --sport 25 -j MARK --set-mark 25
- CONNMARK的处理方法
MARK所设置的mark值我们称为cfmark,CONNMARK所设置的mark我们称为ctmark,两者的差异在于mark值的有效范围;nfmark的有效范围局限在单一一个数据包,ctmark则为一个完整的连接。
当进入本机的数据包将会被丢弃掉,因为数据包进入本机后会先进入mangle表的INPUT链,然后才会进入filter表的INPUT链,所以会被丢弃# 数据包的来源端口为80,就把这个数据包的mark值标记为1 iptables -t mangle -A INPUT -p tcp --sport 80 -j MARK --set-mark 1 # 进入的数据包如果mark值为1,则丢弃 iptables -t filter -A INPUT -m mark --mark 1 -j DROP
上面的实例将不会有任何数据被丢弃掉,原因在于虽然进入本机的数据包在mangle表中被标记为1了,但这个数据包一旦被本机进程接收之后,就相当于这个数据包已经消失了,如此nfmark值自然也就跟着消失了,而本机应答给来源端主机的数据包则为另一个新生成的数据包,其上当然就不会有任何mark值存在。# 数据包的来源端口为80,就把这个数据包的mark值标记为1 iptables -t mangle -A INPUT -p tcp --sport 80 -j MARK --set-mark 1 # 发出去的数据包如果mark值为1,则丢弃 iptables -t filter -A OUTPUT -m mark --mark 1 -j DROP
在以下两个示例中,数据包都被丢弃掉,因为CONNMARK的ctmark值有效范围为一完整的连接,因此不管是送入或送出的数据包,骑上都会包含这个ctmark值。iptables -t mangle -A INPUT -p tcp --sport 80 -j CONNMARK --set-mark 1 iptables -t filter -A INPUT -m connmark --mark 1 -j DROP
复制nfmark功能:在数据包进入本机之后,我们以MARK将数据包nfmark标记为1,接着再以CONNMARK将nfmark存储起来,最后再把nfmark值复制到这条连接上,这样通过CONNMARK的帮助,使得nfmark也可以作用在连接的所有数据包之上。iptables -t mangle -A INPUT -p tcp --sport 80 -j CONNMARK --set-mark 1 iptables -t filter -A OUTPUT -m connmark --mark 1 -j DROP
iptables -t mangle -A INPUT -p tcp --dport 80 -j MARK --set-mark 1 iptables -t mangle -A INPUT -j CONNMARK --save-mark iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark iptables -t filter -A INPUT -m mark --mark 1 -j DROP
- TTL的处理方法
修改TTL值# 设置64 iptables -t mangle -A POSTROUTING -s $WEB_SRV -j TTL --ttl-set 64 # ttl减1 iptables -t mangle -A POSTROUTING -s $MAIL_SRV -j TTL --ttl-dec 1 # ttl加1 iptables -t mangle -A POSTROUTING -s $MAIL_SRV -j TTL --ttl-inc 1
- REDIRECT的处理方法
- MASQUERADE的处理方法
- NETMAP的处理方法
将整个C类网络的公网IP映射到一个私网IP的网段iptables -t nat -A PREROUTING -i eth0 -d 10.0.0.0/24 -j NETMAP --to 192.168.1.0/24 iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j NETMAP --to 10.0.0.0/24
参考文献:
《Linux安全技术与实现第2版》—陈勇勋著