Linux 系统的防火墙功能是由内核实现的
2.0 版内核中,包过滤机制是 ipfw,管理工具是 ipfwadm
2.2 版内核中,包过滤机制是 ipchain,管理工具是 ipchains
2.4 版及以后的内核中,包过滤机制是 netfilter,管理工具是 iptables
iptables
用户态
位于/sbin/iptables,是用来管理防火墙的命令工具
为防火墙体系提供过滤规则/策略,决定如何过滤或处理到达防火墙主机的数据包
内核态
netfilter: 位于 Linux 内核中的包过滤防火墙功能体系.
内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、
FORWARD、PREROUTING、POSTROUTING),而这五个hook function
向用户开放,用户可以通过一个命令工具(iptables)向其写入规则.
由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则
被分组放在链(chain)上.
注意: /etc/init.d/iptables start ------>则,所有经过防火墙的数据包都会被防火墙处理。
规则表
具有某一类相似用途的防火墙规则,按照不同处理时机区分到不同的规则链以后,被归置到不同的“表”中;
简单理解:规则表是规则链的集合,默认有 4 张规则表
raw 表: 确定是否对该数据包进行状态跟踪
mangle 表: 为数据包设置标记
nat 表: 修改数据包中的源、目标 IP 地址或端口
filter 表: 确定是否放行该数据包(过滤)
规则表的优先顺序:RAW ---> MANGLE ----> NAT ----> FILTER.
规则链
规则的作用在于对数据包进行过滤或处理,根据处理时机的不同,各种规则被组织在不同的“链”中;
简单理解:规则链是防火墙规则/策略的集合,默认的 5 种规则链
INPUT: 处理入站数据包
OUTPUT: 处理出站数据包
FORWARD: 处理转发数据包
POSTROUTING : 在进行路由选择后处理数据包
PREROUTING : 在进行路由选择前处理数据包 come
PREROUTING : 在进行路由选择前处理数据包 come
规则链间的匹配顺序:
入站数据: PREROUTING INPUT
出站数据: OUTPUT POSTROUTING
转发数据: PREROUTING FORWARD POSTROUTING
四表五链的对应关系:
raw: PREROUTING
OUTPUT
mangle: PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
nat: PREROUTING
INPUT
OUTPUT
POSTROUTING
filter: INPUT
FORWARD
OUTPUT
security: INPUT
FORWARD
OUTPUT
注:
此表在CentOS7上开始存在,它在filter表之后被调用,它是基于Linux的安全模块SELinux为基础,做强制安全控制
MAC(Mandatory Access Control)的网络规则,它允许filter表的DAC (Discretionary Access Control) 先执行完成后,
在继续执行MAC。
查看规则基本格式:
iptables -v -n -x [--line-number] -t 表名 [ -L | -S ] 链名
注:
-v: --verbose,输出详情
-n: --numeric,使用数字格式显示IP和端口.
-x: --exact,显示计数器的标准数值.
--line-number: 显示每条规则的在链中的行号.
-L 链名 : --list: 列出当前表 指定链 或 的所有规则记录
-S 链名 : :以iptables的命令行方式显示添加的规则记录
插入|替换的基本格式:
iptables [-v] -t 表名 [-I | -R] 链名 [行号] [!] -i 入接口 [!] -o 出接口 \
[!] -s 源IP/Mask [!] -d 目IP/Mask \
[ [!] -p 协议1,协议2,.. [!] --协议选项 ] \
--扩展模块 \
-j 动作 | --goto 链名
注:
“!” : 意思是取反
-I 链名 [行号] :,--insert: 在当前表 指定行号前插入
-R 链名 [行号] :,--replace:替换当前表 指定行号的规则记录
追加基本格式:
iptables [-v] -t 表名 -A 链名 [!] -i 入接口 [!] -o 出接口 \
[!] -s 源IP/Mask [!] -d 目IP/Mask \
[ [!] -p 协议1,协议2,.. [!] --协议选项 ] \
--扩展模块 \
-j 动作 | --goto 链名
注
-A 链名 :,--append: 在当前表 最后一条规则记录后追加
删除|清空的基本格式:
iptables [-v] -t 表名 [-D | -F | -Z ] 链名 [行号]
注:
-D 链名 行号 :,--delete: 删除当前表 指定行号的规则记录
-F 链名 :,--flush: 删除当前表 指定链的 或 所有链的规则记录
-Z 链名 :,--zero: 置零当前表 指定链的 或 所有链的计数器
新建|删除|重命名链的基本格式:
iptables -t 表名 [-N | -X | -E ] 链名
注:
-N 新链名 :,--new-chain: 创建一个指定名称的链.
-X 链名 :,--delete-chain: 删除自定义的链
-E 链名 :,--rename-chain: 重命名自定义链
修改链的默认策略:
iptables -t 表名 -P 链名 [DROP |ACCEPT]
注:
-P 链名 [DROP |ACCEPT] :,--policy: 设置指定链的默认策略是DROP或ACCEPT.
协议格式:
[!] -p [ tcp | udp ] [ [!] [ --sport | --dport] StartPort:EndPort ] \
[ [!] --tcp-flags 关注标志位 过滤标志位 ] \
[ [!] --syn ] \
[ [!] --tcp-option 选项值 ]
注:
标志位格式: CWR | ECE | URG | ACK | PSH | RST | SYN | FIN | SYN,ACK,..
关注标志位: 可以关注多个tcp标志位.
过滤标志位: 从关注的标志位中,指定仅检测那些标志位被设置了,就去匹配它,然后根据动作来处理匹配的包
--syn: 专用于TCP三次握手中,匹配第一次握手
[!] -p [ icmp ] [ --help ] [ [!] --icmp-type {type[/code] | typename} ]
注:
icmp类型,详情参看附录.
动作列表:
-j [ ACCEPT | DROP | REJECT [ --reject-with 通知拒绝的类型 ] | [ DNAT | SNAT |REDIRECT |MASQUERAND ] | MARK ]
[ LOG |NFLOG |ULOG [ --日志选项] ] #参考扩展模块中日志模块
注:
ACCEPT :允许通过
DROP :丢弃报文,无任何客户端收不到任何回应
REJECT :拒绝,但通知客户端你不受欢迎!
通知拒绝的类型:
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable #默认:通告端口不可达
icmp-proto-unreachable #通告协议不可达
icmp-net-prohibited
icmp-host-prohibited
icmp-admin-prohibited #通告访问被禁止
tcp-reset #重置TCP连接
DNAT :目标地址转换
示例:
Inernet-----------[公网IP:1.0.0.2]企业防火墙[私网IP]----------------内网Web服务器(10.0.1.22)
iptables -t nat -A PREROUTING -s 0/0 -d 1.0.0.2 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:80
SNAT :源地址转换,静态地址转换,我指定多少地址,就只能转换多少地址.
示例:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! –d 10.0.1.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9
MASQUERAND :地址伪装,此为动态SNAT,可简单理解为:我的公网IP可不固定/固定均可,让iptables自动
在我需要访问外网时,帮我自动根据路由判断,使用那个接口的IP做地址转换.
示例:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! –d 10.0.1.0/24 -j MASQUERADE
REDIRECT :端口重定向
示例:
Inernet-----------[公网IP:1.0.0.2]企业防火墙[私网IP]----------------内网Web服务器(10.0.1.22:8080)
iptables -t nat -A PREROUTING -d 1.0.0.2 -p tcp --dport 80 -j REDIRECT --to-ports 8080
MARK : 标记数据包
示例:
Inernet-----------[公网IP:1.0.0.2]企业防火墙[私网IP]----------------内网Web服务器(10.0.1.22:80 和 443)
iptables -t mangle -A PREROUTING -d 1.0.0.2 -p tcp –m multiport --dports 80,443 -j MARK --set-mark 2
iptables -A FORWARD -m mark --mark 2 -j ACCEPT
扩展模块格式:
-m 模块名 --模块选项
1. 会话状态模块:
-m state [!] --state [NEW | ESTABLISHED | INVALID | RELATED | UNTRACKED]
注:
NEW: 正在新建立的TCP会话
ESTABLISHED: 新建会话之后,开始输出数据的过程都叫连接已建立.
INVALID: 数据包不能被识别属于哪个连接或没有任何状态, 这类报文一般都DROP.
原因: 此类包,可能是内存溢出,收到不知属于哪个连接的ICMP错误信息.
RELATED: 此状态在FTP中比较常见,FTP分为 命令连接和数据连接. 这种状态的意思
是一个连接和某个已经ESTABLISHED状态的连接有关系。
UNTRACKED: 此状态有两种说法:
1. 表示处于RELATED状态的包被防火墙忽略而不进行状态跟踪.
2. 表示内核无法找到相关连接,而无法被追踪。
另注:
关于conntrack的详情,可查看iptables学习图.其中说明了TCP,UDP,ICMP在这几种
状态转换的详细情况。
2. 离散多端口模块:
-m multiport [!] [ --source-ports |--sports | --destination-ports |--dports | --ports Port1,Port2,... ]
注:
--ports: 表示匹配源 或 目的端口为 指定端口列表的端口。
3. 地址范围模块:
-m iprange [ --src-range | --dst-range IP1-IP2]
4. 连接数限制模块:
-m connlimit [!] [ --connlimit-above 允许的最大连接数 ]
5. 限速模块:
-m limit [ --limit 个数/[second |minute |hour |day] --limit-burst 初始允许的最大峰值个数(默认5个) ]
注:
它是基于令牌桶机制实现限速的,简单理解:一个包在进入前,会从一个令牌桶中得到一个进入令牌,
然后通过防火墙时,只要出示此令牌就可通过,若没有就不允许通过。
若--limit设置为5/second,则系统会每隔5秒往这个令牌桶中放入一个令牌,而--limit-burst 5, 则是说,
系统启动初始直接向令牌桶中放入5个令牌,用完了,就只能等5秒后,系统放入令牌了,才能取。
另注:
使用时结合拒绝策略一起使用:
iptables -I INPUT -p icmp -m limit 5/second --limit-burst 10 -j ACCEPT
iptables -I INPUT -p icmp j REJECT
6. 过滤数据包中包含指定字符串的模块:
-m string [ --algo bm | kmp ] [ --from 从第几个字节开始偏移(默认:0)] \
[ --to 偏移多少个字节(默认:到包结尾)] \
[!] [ --string 过滤字符串 ]
[!] [ --hex-string 十六进制字符串 ]
注:
--algo: 指定过滤字符串使用的算法,这两种算法,使用那个都可以.
7. 通过时间限制通信的模块:
-m time [ --datestart | --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]] ] \
[ --timestart | --timestop HH:MM[:SS] ] \
[!] [ --monthdays | --weekdays Day[,Day...] ] \
[ --utc | --localtz ]
注:
--utc: 使用UTC时间
--localtz: 使用系统kernel时间,默认值。
--datestart 和 --datestop: 此为指定一段时间内做特定流量匹配。
注:
它的时间范围是: 从 1970-01-01T00:00:00 到 2038-01-19T04:17:07
如:
-m time --datestart 2017-12-24 --datestop 2018-12-27
-m time --datestart 2017-01-01T17:00 --datestop 2020-01-01T23:59:59
--timestart 和 --timestop 及 --monthdays 和 --weekdays:
这些都是相对时间,所以可以设定永久性对特定流量的匹配。
注:
time的时间范围: 00:00:00 ~ 23:59:59
monthdays: 是某月中的 1~31天,但2月需要注意:28或29天.
weekdays: 是某一周内的 Mon, Tue, Wed, Thu, Fri, Sat, Sun其值对应1~7.
如:
-m time --timestart 12:30 --timestop 13:30
-m time --weekdays Fri --monthdays 22,23,24,25,26,27,28
8. 动态IP地址本生成模块:
此模块的功能先使用下面示例做一个简单说明:
例如:
iptables -A INPUT -p icmp --icmp-type echo-request -m length --length 78 -m recent --set --name AdminSSH --rsource -j ACCEPT
注:
此语句的功能是,若匹配到ping包的大小为78字节,则满足记录recent的条件,此时iptables将记录被匹配的IP报文
的源IP 到/proc/net/xt_recent/AdminSSH 文件中.
iptables -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 15 --name AdminSSH --rsource -j ACCEPT
注:
此语句的功能是,若匹配到目标端口为22,并且是新建了TCP连接,则满足检查recent记录文件的条件,此时iptables
将去检查/proc/net/xt_recent/AdminSSH文件中是否有 此次连接的源IP存在,若有则检查此源IP的
last_seen(即:最后一次记录的时间戳),若此时间戳 和当前时间对比,若在15秒内,则允许此源IP访问目的端口22.
recent模块维护了一个IP地址薄,通过匹配条件满足后,记录源IP(--resource) 或 目的IP(--rdest),形成IP列表,这样就可以
引用此IP列表,将其定义为白名单 或 黑名单。 此模块还通过 --update 参数来更新last_seen 同时再执行--rcheck的
动作,而--remove则是再条件匹配后,在IP列表中删除此次连接的IP,这样就完成了对IP列表的增删查改。
此模块使用格式:
-m recent [ --name IP地址薄文件名 [ --set [ --rsource | --rdest ] ] ] [ --rttl ] \
[ --seconds 记录有效时间 [ --hitcount 命中次数 ] [ --rcheck | --update ] ] \
[ --remove ]
参数说明:
--name IP地址薄文件名 : 创建一个指定名称的IP地址薄文件.【创建】
--set --rsource | --rdest : 将匹配连接的源IP 或 目的IP记录到 IP地址薄中。【增】
--remove: 查询IP列表中是否存在此次连接的IP,若存在则删除。 【删】
--update: 先执行 --rcheck ,后更新last_seen 的值。【改】
--rcheck: 及查询IP列表中是否存在此次连接的IP 【查】
--seconds 记录有效时间 : 查询IP列表中是否存在此次连接的IP,若存在则检查其对应的last_seen的时间戳,
是否已经超过 “记录有效时间”了。单位:秒
--hitcount 命中次数: 它通常和 --seconds X 一起使用,表示在 X 秒内允许一个IP连接多少次
--rttl 表示同时匹配IP包的TTL,man手册中解释大概意思可能是 避免源IP伪造攻击,
可通过此参数记录TTL的值,以便比对。【 This may be useful if you have
problems with people faking their source address in order to DoS you
via this module by disallowing others access to your site by sending bogus
packets to you.】
参考完整示例:
#记录前缀SSHAccess的日志:
iptables -A INPUT -p tcp --dport 50001 --syn -j LOG --log-prefix "SSHAccess: "
#符合规则,则创建SSHAccess IP地址薄,并重置TCP连接,记录源IP。
iptables -A INPUT -p tcp --dport 50001 --syn -m recent --set --name SSHAccess --rsource \
--rttl -j REJECT --reject-with tcp-reset
#开启SSH端口,15秒内允许刚刚连接TCP50001的源IP登录SSH。
iptables -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 15 --name SSHAccess \
--rsource -j ACCEPT
#符合规则后,删除SSHAccess列表内的本次连接的源IP记录
iptables -A INPUT -p tcp --dport 50002 --syn -m recent --remove --name webpool --rsource \
-j REJECT --reject-with tcp-reset
iptables -A INPUT -j DROP
通过一些方式连接一次,即可开启SSH
nc host 50001
telnet host 50001
nmap -sS host 50001
补充说明:
echo +1.1.1.1 > /proc/net/xt_recent/SSHAccess #向IP列表中手动添加记录
echo -1.1.1.1 > /proc/net/xt_recent/SSHAccess #从IP列表中手动删除记录
echo / > /proc/net/xt_recent/SSHAccess #清空IP列表
ip_list_tot=100 #recent模块的IP地址薄最多记录100条记录
Number of addresses remembered per table.
ip_pkt_list_tot=20 #记录每个IP的数据包总数为20个
Number of packets per address remembered.
ip_list_hash_size=0
Hash table size. 0 means to calculate it based on ip_list_tot, default: 512.
ip_list_perms=0644 #默认创建IP地址薄的权限
Permissions for /proc/net/xt_recent/* files.
ip_list_uid=0 #IP地址薄的用户UID
Numerical UID for ownership of /proc/net/xt_recent/* files.
ip_list_gid=0 #GID #Numerical GID for ownership of /proc/net/xt_recent/* files.
9. 日志target模块:
-j LOG [ --log-level 日志级别名 | --log-prefix 日志前缀字符串 | --log-tcp-sequence | --log-uid | --log-ip-options | --log-tcp-options ]
注:
--log-level 日志级别 #参考/etc/syslog.conf
--log-prefix 日志前缀字符串 #记录此日志到/var/log/messages时,添加一个记录标记字符串
--log-tcp-sequence #记录TCP连接的序列号.
--log-uid #记录生成数据包的进程的UID
--log-ip-options #记录IP选项信息
--log-tcp-options #记录TCP选项信息
10. 能向用户空间进程转发日志的target模块:
-j NFLOG | ULOG:
若需要iptables匹配指定规则后,向用户空间的进程发送匹配规则的日志,则可以使用此日志模块,
它会在规则被匹配后,由Linux内核通过netlink套接字多播方式向用户空间中加入指定组播组的进程,
发送日志信息。NFLOG:支持1~2^32-1个组播组, ULOG: 支持1~32个组播组
11. NAT target模块:
注:
MASQUERADE:它是动态SNAT,即 其公网IP可以动态获取,并自动用来替换内网源IP.
SNAT :它要加到POSTROUTING链中,因为iptables要知道我替谁做了源地址转换,若加到PREROUTING链中,就意味着,
iptables还没看到给谁转换源地址,就已经换了源地址,你说iptables要如何接着处理回来的数据包?
DNAT :它是要加到PREROUTING链中。
格式:
源地址转换【注: 只能用于nat表中的 POSTROUTING 和 INPUT】:
-j SNAT --to-source [ipaddr[-ipaddr]][:port[-port]] [--random] [--persistent]
注:
--random : 是使用随机端口来识别每一个转换后的NAT连接.以便回应报文可以正确转换为内网地址。
默认使用它,若指定了端口范围,则不使用随机端口。
--persistent: 为每个NAT转换保存记录,以便下次该客户端需要转换时,不用随机从源地址池中再次分配新地址给它。
仅在指定了一个可选的转换源地址范围时,可用,但这个源地址范围一定要能满足所有内网地址转换的需求!
-j MASQUERADE [--to-ports port[-port]] [--random]
目的地址转换【注: 只能用于nat表中的 PREROUTING 和 OUTPUT】:
-j DNAT --to-destination [ipaddr[-ipaddr]][:port[-port]] [--persistent] [--random]
注:
参数含义和SNAT基本类似,只是转换地址是目标地址。
12. 标记target模块:
-j MARK --set-mark 标记号码
注:
此模块是给数据包打标记的,它可以配合CONNMARK一起使用,完成更强大的功能,CONNMARK是给一个连接
(注: 连接是两个方向,一个请求流,一个响应流组成)打标记。
13. 连接标记target模块:
-j CONNMARK [--set-mark value[/mask]] [--save-mark | --restore-mark [--mask mask]]
注:
#此格式是CONNMARK最基本的用法,高级用法参考man手册【高级用法主要是对mark如何与mask做运算,得到需要的mark值.】.
--set-mark value[/mask] : 给一个连接打指定的标记. mask: 是标记的掩码位,即:value 和 mask做或运算的值。
--save-mark:将nfmark复制到ctmark中, 即: 将连接中的标记值,保存到/proc/net/nf_conntrack中.
--restore-mark: 将ctmark复制到nfmark中, 即: 将/proc/net/nf_conntrack中mark的值恢复到连接mark中。
--mask 掩码值: 即在保存 或 恢复时,是否执行 mark 与 mask的或运算, 若需要则添加mask.
例:
附件中遗留问题,左边遇到的问题的解决方案: 完成策略路由
Linux网关:
iptables -F
iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark #恢复连接mark到数据包mark中.
iptables -t mangle -A POSTROUTING -m mark --mark 20 -j ACCEPT #检测数据包mark若为20则直接转发
iptables -t mangle -A POSTROUTING -s 1.1.1.0/24 -j MARK --set-mark 20 #若为一个新连接就给数据包添加标记20
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark #将连接中数据包的标记保存到nf_conntrack中.
iptables -t nat -A POSTROUTING -s 1.1.1.0/24 -j SNAT --to-source=10.0.0.1 #连接打上标记后,再做SNAT.
#默认策略:
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -c 0 0 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -c 0 0 -j DROP
iptables -A INPUT -p tcp --dport 22 --syn -j ACCEPT
iptables -A INPUT -c 0 0 -j REJECT --reject-with icmp-host-prohibited
14. 连接状态匹配模块:
-m conntrack [[!] [--ctstate | --ctstatus 状态列表]] [[!] --ctproto tcp|udp|sctp|..四层协议.. ] [...其它选项...]
注:
其它选项:
--ctdir {ORIGINAL|REPLY} #指定仅匹配(ORIGINAL)源或(REPLY)目的地址,默认都匹配.
[!] [--ctorigsrc |--ctoridst |--ctreplsrc |--ctrepldst address[/mask]] #匹配起始方或响应方的源或目的地址
[!] [--ctorigsrcport |--ctorigdstport |--ctreplsrcport |--ctrepldstport port[:port]] #匹配起始方或响应方的源或目的端口
[!] --ctexpire time[:time] #根据提供的时间范围来匹配剩余生存时间。
--ctstate 可用的连接状态值:
NEW #新建立连接的状态
ESTABLISHED
RELATED #与现有连接相关联的连接状态,如FTP数据传输或ICMP错误。
SNAT #它是一种虚拟状态,若起始源地址与响应目标地址不匹配时,则为此连接状态.
DNAT #它是一种虚拟状态,若响应源地址与起始目的地址不匹配时,则为此连接状态.
UNTRACKED #没有被nf_conntrack追踪的连接状态,注:iptables -t raw .. -j CT --notrack,显式指定
不追踪该报文,则会出现此连接状态.
INVALID #无法识别的无效状态.
--ctstatus 可用的连接状态值:
NONE #以下都不是
EXPECTED #这是一个预期的连接(即conntrack helper设置过的连接)。
SEEN_REPLY #Conntrack在两个方向上都看到了连接的数据包。
ASSURED #Conntrack入口永远不应该提前过期。
confirmed #确认连接:原始数据包已离开本机
15. 速率估算器
-m rateest [...参数选项..]
例:
#使用以下示例来说明该模块的使用方法:
1. 定义两个速率估算器分别叫eth0 和 ppp0,它们都以250毫秒为速率测量时间间隔,
允许前后误差在0.5秒内,收集eth0 和 ppp0两个接口的速率。
iptables -t mangle -A POSTROUTING -o eth0 -j RATEEST --rateest-name eth0 \
--rateest-interval 250ms --rateest-ewma 0.5s
iptables -t mangle -A POSTROUTING -o ppp0 -j RATEEST --rateest-name ppp0 \
--rateest-interval 250ms --rateest-ewma 0.5s
2. 在eth0 和 ppp0两个接口之间负载流量。
#若eth0这个速率估算器收集了速率为Erate0,ppp0收集的速率为Prate0
#则规则1:
Erate0 减去 2.5mbit = ECZ0 ; 若 ECZ0 为负数,则将ECZ0赋值为0,为正数,则直接赋值为差值.
Prate0 减去 2mbit = PCZ0 ; 标准与ECZ0一样。
若 ECZ0 > PCZ0 则 给流量打上标记1.
iptables -t mangle -A balance -m conntrack --ctstate NEW -m helper --helper ftp \
-m rateest --rateest-delta --rateest1 eth0 --rateest-bps1 2.5mbit \
--rateest-gt \
--rateest2 ppp0 --rateest-bps2 2mbit \
-j CONNMARK --set-mark 1
#规则2 与规则1原理一样,eth0大于ppp0,则给流量打上标记2
iptables -t mangle -A balance -m conntrack --ctstate NEW -m helper --helper ftp \
-m rateest --rateest-delta --rateest1 ppp0 --rateest-bps1 2mbit \
--rateest-gt \
--rateest2 eth0 --rateest-bps2 2.5mbit \
-j CONNMARK --set-mark 2
iptables -t mangle -A balance -j CONNMARK --restore-mark
参数选项:
比较操作符:
[!] --rateest-eq #等于
[!] --rateest-gt #大于
[!] --rateest-lt #小于
--rateest-delta #指定是使用相对比较 或 绝对比较. 相对比较: 即差值比较,绝对比较,
即: 直接使用速率估算器中的值做比较.
--rateest name
--rateest-bps [value] #bps:即每秒多少bit位.
--rateest-pps [value] #pps:即每秒多少个数据包
例:
#指定按bps来比较,直接使用速率估算器中的值来比较。
iptables -t mangle ... -m rateest --rateest-bps --rateest eth0 --rateest-gt --rateest ppp0 -j ...
--rateest1 name
--rateest2 name
--rateest-bps1 [value]
--rateest-bps2 [value]
--rateest-pps1 [value]
--rateest-pps2 [value]
注:
速率可用单位: bit, [kmgt]bit, [KMGT]ibit, Bps, [KMGT]Bps, [KMGT]iBps.
kbit 是千bit位,这是SI标准写法,Windows支持此标准, Kibit 也是千bit位,
这是IEC标准写法,目前Linux,Unix,MacOSX都支持此种标准.
KBps 是每秒多少千字节。
16. CT target模块
-j CT [ ...] #此模块仅做了基本介绍,没做详细使用说明,
详细使用参考: https://home.regit.org/netfilter-en/secure-use-of-helpers/
注:
CT模块引入的背景和作用:
helper模块:它是解决类似于ftp这种协议,使用两个连接 singaling flow(信令流) 和 data flow(数据流),
信令流用于协商配置参数,而数据流用于传输数据 的这种协议连接的匹配问题,因为iptables为
了解决这个问题,引入了一个3/4层参数,而它打破了OSI七层的规范,所以后来就引入了helper
模块来解决此问题。
helper模块的问题:
它是为了解决helper模块的在iptables规则一旦引用,该helper模块将自动开始在所有接口上解析报文,
以便找到与指定协议相关的连接,这带来的问题就是,造成CPU和内存资源被使用过多,而且其中很多
连接是不需要的解析的。
CT target模块:
它是helper模块的升级版,它包含helper模块,并将其做为一个根据需要调用的功能,当匹配到我们
关系的流量时,才调用它,来分析该链接流量是否为相关已建立链接的数据流。
为了更好让helper模块工作,建议在使用前,先禁止它处理指定 anyIP:端口 上所有数据包,然后再
使用CT在需要时调用它:
Linux3.5以后使用以下命令来禁止:
modprobe nf_conntrack nf_conntrack_helper=0 #这是在使用前可操作的方法.
vim /etc/modprobe.d/firewalld-sysctls.conf 应该类似此方式.
或
echo 0 > /proc/sys/net/netfilter/nf_conntrack_helper
#这是在装载模块后使用此方式来禁止.
#Please note that flows that already got a helper will keep using it even if automatic
helper assignment has been disabled.
# 请注意,已经获得助手的流将继续使用它,即使自动助手分配已被禁用。
Linux3.5以下禁止帮助模块行为的方式:
modprobe nf_conntrack_$PROTO ports=0
以下模块若禁止其处理 anyIP:port 上所有数据包后,它们将在所有流上被停用:
ftp, irc, sane, sip, tftp
以下模块必须使用ports参数,否则无法正常工作:
amanda, h323, netbios_ns, pptp, snmp
注:
若使用ports=0 这种方式禁止了指定模块,则该模块在conntrack中将被自动
重命名为 $PROTO-0. 所以需要手动更新CT的调用.
例:
iptables -A PREROUTING -t raw -p tcp --dport 21 -d 2.3.4.5 -j CT --helper ftp-0
#以下列表描述了不同的连接跟踪帮助程序模块及其相关的自由度:
Fixed: Value of a connection tracking attribute is used. This is not a candidate for forgery.
【使用连接跟踪属性的值。这不是伪造的候选人。】
In CMD: Value is fetched from the payload. This is a candidate for forgery.
【从有效负载中获取值。这是伪造的候选人。】
rpfilter:
它是帮助 helper模块 做安全监测的一个反欺骗(Anti-spoofing)模块,由于helper模块依赖于客户端
和服务器的数据做检测,来判断相关连接,它并不能像conntrack一样能跟踪连接的其余部分,因此
无法做任何一致性检查,这就给伪造数据的欺骗攻击带来的便利,而rpfilter就是来解决此问题的。
注:
rpfilter 模块是从Linux3.3 和 iptables1.4.13后才有的模块。它是基于路由的反向路径过滤实现。
ls /proc/sys/net/ipv4/{all, Interfaces}/rp_filter #可用于激活rp_filter功能
#【当对{interface}进行源验证时,将使用conf/{all,interface}/rp_filter的最大值。】.
注:
0: 不做源地址验证
1:严格源地址反向路径验证模式。每个传入数据包都要根据fib_validate_source函数进行测试,
如果接口不是最佳的反向路径,即入接口不是响应报文的出接口,则数据包检查将失败。
默认情况下,失败的包将被丢弃。【RFC3704】
2:松散源地址反向路径验证模式。 每个传入数据包的源地址也将根据fib_validate_source函数进行测试,
如果通过任何接口都无法访问源地址,则数据包检查将失败。
RFC3704目前推荐的做法是启用严格模式,以防止IP欺骗攻击DDos。
如果使用非对称路由或其他复杂路由,则建议使用松散模式。
https://home.regit.org/netfilter-en/secure-use-of-helpers/
这篇英文博客,有对该模块的介绍和使用,为了不理解错误,先记录到此。
https://www.cnblogs.com/lipengxiang2009/p/7446388.html
另注:
若启用了rpfilter功能,若需要知道内核丢弃了那些报文,可启用log_martians功能.
echo 1 >/proc/sys/net/ipv4/conf/<interfacename>/log_martians
17. 匹配下载的连接
-m connbytes [!] --connbytes [从多少[:到多少]] --connbytes-dir [original |reply |both] --connbytes-mode [packets |bytes |avgpkt]
注:
--connbytes-mode : 设置判断连接(或组成连接的两个数据流中的一个流)是否为下载流量的依据,
是按packets(数据包)来统计,还是按照 bytes(字节) 或 avgpkt(每个数据包的平均字节数)
--connbytes 10000:100000 : 若按bytes来统计,则一个数据流传输的字节数若在一万到十万字节之间时,
则认为它是下载流量。
--connbytes-dir : 指定对哪种类型的数据流做监控,original: 原始流, reply:重放流,both:一般使用两者都监控.
例:
iptables .. -m connbytes --connbytes 10000:100000 --connbytes-dir both --connbytes-mode bytes ...
18. 连接标记
-m connmark [!] --mark Value[/Mask]
注:
这个是给一个连接(默认为TCP)添加标记. 它和CONNMARK功能类似,只是CONNMARK是target(即: -j CONNMARK, 目标动作)。
19. 根据连接数 或 源目地址块 来限制并发连接数.
-m connlimit [ --connlimit-upto | --connlimit-above Num ] [ --connlimit-saddr | --connlimit-daddr] [ --connlimit-mask PrefixLength]
注:
upto 和 above: 分别根据连接数来匹配; upto:连接数小于或等于Num, above:连接数大于Num
saddr |daddr : 设置匹配其源或目地地址来匹配
PrefixLength : 设置匹配地址段的长度 或叫掩码长度,若省略PrefixLength,默认根据网络地址,确定其最大掩码.
例:
iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 --connlimit-mask 24 -j REJECT
#注: 将每个源地址为C类网络的并行HTTP请求数量限制为最大16个。
ip6tables -p tcp --syn --dport 80 -s fe80::/64 -m connlimit --connlimit-above 16 --connlimit-mask 64 -j REJECT
#注:将IPv6链接地址的并行HTTP请求数量限制为最大16个
iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT
#注: 限制每个客户端只能有两个并发连接telnet.
附件:
icmp类型:
【类型/代码】
any 默认匹配所有.
echo-reply (pong) 0/0
destination-unreachable
network-unreachable 3/0 :网络不可达
host-unreachable 3/1
protocol-unreachable 3/2
port-unreachable 3/3
fragmentation-needed 3/4: 链路上需要分片,但设置了不分片标志位.
source-route-failed 3/5: 源地址路由失败
network-unknown 3/6: 目的网络未知
host-unknown 3/7
network-prohibited 3/9:目标网络被禁止
host-prohibited 3/10
TOS-network-unreachable 3/11: 由于服务类型TOS,网络不可达
TOS-host-unreachable 3/12
communication-prohibited 3/13:由于过滤,通信被强制禁止
host-precedence-violation 3/14:主机越权
precedence-cutoff 3/15:优先终止生效(Precedence cutoff in effect)
source-quench 4/0:源端被关闭(基本流控制)
redirect
network-redirect 5/0
host-redirect 5/1
TOS-network-redirect 5/2:对服务类型和网络重定向
TOS-host-redirect 5/3
echo-request (ping) 8/0
router-advertisement 9/0: 路由器通告
router-solicitation 10/0:路由器请求
time-exceeded (ttl-exceeded)【TTL时间溢出,即超时】
ttl-zero-during-transit 11/0:传输期间生存时间等于0,而超时返回.
ttl-zero-during-reassembly 11/1:数据报在组装期间生存时间等于0,而超时返回.
parameter-problem【参数问题】
ip-header-bad 12/0:损坏的IP首部(包括各种传输损坏)
required-option-missing 12/1:缺少必须的选项
timestamp-request 13/0【已作废】
timestamp-reply 14/0【已作废】
address-mask-request 17/0:地址掩码请求
address-mask-reply 18/0:地址掩码应答