Netfilter是Linux的第三代防火墙,因其比之前的两种防火墙ipfwadm及ipchains出色而被Linux组织作为默认的防火墙。Netfilter是自由软件,但在各方面均不逊于商业版的防火墙。
Netfilter与Linux是两个相互独立的组织,在Linux 2.4早期的版本,并没有包含Netfilter的功能,到后期的版本,才收录了Netfilter的功能。
Netfilter以模块的形式存在于linux中,当网卡有数据包传入传出时,出入的数据包都会经由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 |
负责加快数据包穿过防火墙机制的速度,由此提高防火墙的性能 |
filter对数据包的分类如下:
每条链上都有N条被制定的规则,这些规则该如何匹配呢?first match即优先匹配采用的方式为从INPUT链中的rule-1逐一向下匹配,如果rule-1指明要丢弃数据包,则数据包马上被丢弃,不再执行后面的规则,相反,如果rule-1指明允许数据包进来,则数据包立即进入到本机程序的位置,当前,不管后面的规则内容是什么也都不再重要,这就是优先匹配
不过万一该数据包的特征从INPUT链的rule-1匹配到rule-6均没有匹配成功,该数据包是丢弃还是放行?这就涉及到默认策略(Default Policy)的问题了,请注意,不管链中有多少条规则,默认策略永远在每个链的最底端,而且每个链的默认策略各自独立。linux的默认策略的默认状态是ACCEPT
Netfilter所需要的规则是存放在内存中的,但是我们如何对这些规则进行添加、删除、修改及查询等操作呢,这个时候必须要有一个针对规则的编辑工具提供给网络管理人员,这个工具就是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 |
本节将以下图为例来构建一个简单的单机防火墙。
我们再192.168.0.1主机上分别启用SSH、TELNET、SMTP、WEB以及POP3五项服务。本实例的需求如下:
有了需求后,我们将这些需求转换成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 |
根据上面的单机防火墙规则,我们让外部所有的主机均能够成功访问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
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
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 10.0.1.200-10.0.1.205
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
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
Mangle是一个比较容易被人忽略的机制,而且Mangle的使用机会并不是很多,但如果需要时又不懂Mangle机制,也是件很麻烦的事,在此还是要说明一下Mangle机制。
当一个数据包“穿过”防火墙时,我们可以通过Mangle的机制来修改数据包的内容
如果想要改变本机进程所生成的数据包内DSCP值,就必须将规则放置于OUTPUT链中,或是POSTROUTING链之内都可以达到完美的目的,因为本机进程所产生的数据包,除了会流经OUTPUT链之外,也会经过POSTROUTING链,因此,这两个链都可供使用。
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 43
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 80
iptables -A FORWARD -p all -m mark --mark 80 -j DROP
iptables -t filter -A FORWARD -i eth0 -o eht1 -j DROP
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系统中的问题
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提供的匹配参数有:
# 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可以提供以下两种不同的匹配方式,分别如下:
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
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将会失效
IP范围的匹配
两个匹配参数
# 匹配“来源地址”范围
iptables -A INPUT -m iprange --src-range 192.168.0.2-192.168.0.62 -j DROP
# 匹配“目的地址”范围
iptables -A OUTPUT -m iprange --dst-range 192.168.0.2-192.168.0.62 -j DROP
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网络环境中,数据包的传输方式有三种,如下所示:
# 过滤掉ping Broadcast数据包
iptables -A FORWARD -i eth0 -p icmp -m pkttype --pkt-type broadcast -j DROP
length(MTU值)匹配
# 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的匹配模块由于使用频率较低,暂未做深入举例,感兴趣的可以参考原版书籍查看
iptables -A FORWARD -p tcp -d 192.168.0.1 --dport 25 -j QUEUE
iptables -I USER_CHAIN 1 -p all -j RETURN
# 自定义回送报文的内容,可选的内容有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
# 将ssh客户端发起的第一个请求报文写入日志中,日志级别为alert,日志前缀SSH_REQUEST
iptables -A INPUT -p tcp --syn --dport 22 -j LOG --log-level alert --log-prefix " SSH-REQUEST "
指定日志保存的位置:在/etc/rsyslog.conf内加上如下一行:# 如果日志是由kernel所生成的,而且某日志级别是alert级的日志,就将日志保存在/var/log/netfilter这个文件中。
kern.=alert /var/log/netfilter
日志保存的位置:/var/log/netfilter# 数据包的来源端口为80,就把这个数据包内的DSCP值改为1
iptables -t mangle -A FORWARD -p tcp --sport 80 -j DSCP --set-dscp 1
# 将SMTP的数据包的MARK值标记为25
iptables -t mangle -A FORWARD -p tcp --sport 25 -j MARK --set-mark 25
# 数据包的来源端口为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表的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 OUTPUT -m mark --mark 1 -j DROP
上面的实例将不会有任何数据被丢弃掉,原因在于虽然进入本机的数据包在mangle表中被标记为1了,但这个数据包一旦被本机进程接收之后,就相当于这个数据包已经消失了,如此nfmark值自然也就跟着消失了,而本机应答给来源端主机的数据包则为另一个新生成的数据包,其上当然就不会有任何mark值存在。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
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
复制nfmark功能:在数据包进入本机之后,我们以MARK将数据包nfmark标记为1,接着再以CONNMARK将nfmark存储起来,最后再把nfmark值复制到这条连接上,这样通过CONNMARK的帮助,使得nfmark也可以作用在连接的所有数据包之上。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
# 设置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
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版》—陈勇勋著