iptables防火墙
iptables防火墙
基于Netfilter模块,linux系统内核自带功能,rhel8之前使用iptables工具管理,之后改为使用firewalld工具
基本原理
netfilter的hook function(钩子函数):
- prerouting
- input
- output
- forward
- postrouting
链(内置):
- PREROUTING
- INPUT
- OUTPUT
- FORWARD
- POSTROUTING
表:
- filter:过滤、防火墙
- nat:地址转换,用于修改源ip、目标ip、端口
- mangle:拆解报文,做修改,并重新封装
- raw:关闭nat表上启用的连接追踪机制
- security
每个表可用链:
规则匹配优先级顺序,以下为准
- raw: PREROUTING、OUTPUT
- mangle: PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
- nat: PREROUTING、INPUT、OUTPUT、POSTROUTING
- filter:INPUT、FORWARD、OUTPUT
报文流向

规则:
组成部分:
- 匹配条件:
- 基本匹配条件。
- 扩展匹配条件,由模块定义
- 处理动作:
- 基本处理动作
- 扩展处理动作,模块定义
- 自定义
iptables链: 内置和自定义
内置,对应于hook function
自定义,用于内置链的扩展和补充,实现更灵活管理
规则定义注意:
- 同类规则(访问同意应用),匹配范围小的放上面
- 不同类的规则(访问不应用),匹配到报文频率较大的放在上面
- 将那些可由同一条规则描述的多个规则合并起来
- 设置默认策略
iptables命令:
高度模块化,由诸多扩展模块实现其他检查条件或处理动作的定义
模块目录:
/usr/lib64/xtables/
其中ipv6是libip6_,ipv4是libt_ 、libxt
iptables-service包:
rhel8单独提供的服务包,可以systemd管理
- iptables-save,保存规则
- iptables-restore,重载
- iptables-apply,安全更新规则
- iptables-restore-translate,格式转换为nfttables规则(nfttables下一篇将)
iptables-restore
iptables-restore [选项]
-n 不清除原有规则。文件重载会把iptables已有的内容清
-t 仅分析生成规则集,不提交
iptables命令
iptables [-t table] comm chain [扩展匹配条件 options] [-j target target-options]
-t table raw,mangle,nat,filter(默认)
comm部分详解:
链管理:
-N 新建一条自定义规则链
-X 删除一条自定义链(内部没有规则定义)
-P 设置默认策略,对filter表,策略支持:
ACCEPT 接收
DROP 丢弃
REJECT 拒绝
-E 重命名自定义链,引用计数不为0的自定义链不能被重命名,也不可被删除(也就是内部无规则定义)
规则管理:
-A 追加,默认filter
-I 插入,不指明位置默认第一条
-D 删除。
指明规则序号
指明规则本身
-R 替换指定链上的规则
-F 清空指定规则链
-Z 清零,比如流量计数
iptables每条规则都有两个计数器
1.匹配到的报文的个数
2.匹配到的所有报文大小之和
查看:
-L 列出指定链的所有规则,默认filter
***以下补充参数都要写在L前面,或单独-
-n 以数字格式显示地址和端口号
-v 显示详细信息,v越多越详细
-x 显示计数器结果的精确值(非四舍五入结果)
--line-numbers 显示规则序号
--modprobe=command
chain部分:
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
匹配条件:
基本匹配条件:
无需加载模块,自行提供的。
“!”是取反意思
[!] -s ip/mask 指定源地址。s为本机
[!] -d ip/mask 目标地址,d为远程主机
[!] -p 协议 支持tcp、udp、udplite、icmp、icmpv6、esp、ah、sctp、mh。all为支持所有
[!] -i 网卡 数据流入接口,用于PREROUTING、INPUT、FORWARD
[!] -o 网卡 数据流出接口,应用于FORWARD、OUTPUT、POSTROUTING链
扩展匹配条件:
要加载模块
- 隐式扩展:不用手动加载模块,用的是协议模块,不用在-p 之前使用“-m ”
- 显式扩展:必须使用-m 选项指明模块
隐式扩展:
tcp:
--sport 端口[:port] 匹配报文源端口,支持范围
[!] --dport 端口[:port] 目标端口,支持范围
[!] --tcp-flags mask comp 表示匹配三次握手的内容是否符合
mask 为要检查的内容
comp 以这个定义的为准
如:
--tcp-flags SYN,ACK,FIN,RST SYN #表示检查tcp握手的标志位SYN,ACK,FIN,RST四个,其中SYN必须为1,其他必须为0
--tcp-flags ALL ALL
--tcp-flags ALL NONE
[!] --syn 用于匹配tcp第一次握手,作用同上
udp:
[!] --sport 端口[:端口]
[!] --dport 端口[:端口]
icmp:
注意:如果需要允许icmp,需要防火墙和内核都是配置,两者都受限制
#1为禁用所有,0为默认允许
icmp_echo_ignore_all = 0
icmp-typev {type[/code]或typename} #可百度icmp-type查看类型和代码含义
echo-request:8 #ping的请求是8
echo-reply:0/0 #ping的返回结果是0/0
显式扩展:
multiport:
以离散或连续的方式,定义多个端口匹配条件,最多15个,支持tcp,udp,udplite,dccp,sctp
[!] --sports 端口[,端口 or ,端口:端口]
[!] --dports 端口[,端口 or ,端口:端口]
例:
iptables -A INPUT -d 192.168.65.7 -p tcp -m multiport --dports 22,80,3306,... -j ACCEPT
iprange:
以连续地址的方式来指明多ip地址匹配条件
[!] --src-range 192.168.0.1-192.168.0.100
[!] --det-range 192.168.0.1-192.168.0.100
time:
设置访问时间段
--timestart 10:00[:00]
--timestop 10:10[:00]
[!] --weekdays [1-7]
[!] --monthdays day
--kerneltz 使用内核配置的时区,而非硬件时钟
例:
#允许2.2.规定的ip,在周一至周五,10点到16点之间(用时区时间),访问1.1.的23端口
iptables -I INPUT -d 1.1.1.10 -p tcp --dport 23 -m iprange --src-range 2.2.2.10-2.2.2.30 -m time --timestart 10:00 --timestop 16:00 --weekdays 1,2,3,4,5 --kerneltz -j ACCEPT
string:
数据包内容的字符串检查,只对明文协议有用,加密无效
--algo {bm|kmp} 必须项。基于哪种字符匹配算法
[!] --string "字符" 过滤的字符串
[!] --hex-string "字符" 支持16进制字符
--from 起始位 字符匹配从哪位开始
--to 结束位
例:
#数据中字符串有gay的字符,拒绝出站,用bm算法
iptables -I OUTOUT -m string --alge bm --string "gay" -j REJECT
connlimit:
单ip并发连接数限制
--connlimit-upto 5 0 5个以内允许连接。如果策略是drop,那么为白名单
--connlimit-above 20 大于20拒绝。如果策略是drop,那么小于该数为白名单
例:
#2.2.2连接1.1.1的23端口,数量超过2个以上就拒接
iptables -I INPUT -d 1.1.1.10 -p tcp --dport 23 -s 2.2.2.20 -m connlimit --connlimit-upto 2 -j REJECT
limit:
令牌桶限制。令牌桶为每个进程,内核申请调用后,发数据,每一次发送都要拿一个令牌才能发,令牌可以做每秒内次数限制(1s3次),如果进程只用了一个令牌,它可以把令牌攒起来(令牌桶中),limit可限制桶中只能攒多少、每秒发多少令牌
注:可用hping3(网络攻击)工具来测试发包
--limit 速率[/second/minute/hour/day] 限制每s/m/h发包速率
--limit-burst 10 可最多收集10个令牌
例:
#访问1.1.主机80端口的tcp入站请求,限制每秒收100个,令牌桶最大攒5个,多出来的匹配策略组
iptables -I INPUT -d 1.1.1.10 -p tcp --dport 80 --syn -m limit --limit 100/second --limit-burst 5 -j ACCEPT
state:
传输层、网络层的连接追踪。默认两层是没有访问记忆的,所以在内核中开启一段内存,用于记录请求的tcp、udp访问过程、信息,断开连接后,该记录存放一定时间后清零。
清零之前再次访问直接进来,清零后重新通过。而内核中的内存空间,访问量大时会被占满,所以3种解决:
- 关闭连接追踪
- 开辟的内存空间调大
- 改超时时间长短
[!] --state 状态
状态:
NEW 新记录
ESTABLISHED 记录后开始连接并未删除
UNTRACKED raw关闭nat表的追踪功能
RELATED 新记录,用的新端口或协议,但与之前的new记录有关联,记录以后,再次连接都叫established
INVALID 无法识别、不合法的连接
依赖内核模块:
nf_conntrack
nf_conntrack_ipv4
加载模块:
#手动
modprobe nf_conntrack_ftp
#配置文件加载
vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp"
查看追踪信息:
- 已追踪的连接记录位置:/proc/net/nf_conntrack
- 调整记录的数量最大值:/proc/sys/net/nf_conntrack_max
- 超时时长:/proc/sys/net/netfilter/*timeout*
例:
实现安全入网,木马程序禁止出站的功能,或可让别人established、new状态进来,除了established出站,其他拒绝
#入站
iptables -I INPUT -p tcp -m multiport --dports 22,23,80,443 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP
#出站
iptables -A OUTPUT -s 1.1.1.1 -m state --state ESTABLISHED -j ACCEPT
target(处理动作):
简单动作:
- ACCEPT
- DROP,丢弃包,也是无底洞,使用丢弃时
扩展动作:
在特殊表中,有特殊的动作,在下面nat表中继续描述
REJECT
拒绝包
--reject-with 拒绝类型
类型:
icmp-net-unreachable 网络不可达
icmp-host-unreachable 主机不可达
icmp-port-unreachable 默认。端口不可用
icmp-proto-unreachable 协议
icmp-net-prohibited 网络被禁止
icmp-host-prohibited 主机被禁止
icmp-admin-prohibited 管理被禁止
LOG
客户端访问记录日志,默认存于/var/log/messages/
注:使用时应放在第一条规则,一般不开,写日志可能影响性能
--log-level 日志级别
--log-prefix 日志文件名前缀
例:
iptables -I INPUT -d 1.1.1.10 -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "is ssh access: "
RETURN
在调用过程中返回主链,在自定义链中使用,需要做高级规则时可使用,docker、k8s、istio中常见
自定义链做为target
调用自定义链的过程相当于程序中if语句的过程
例:
#新建自定义链
iptables -N in_ping_rule
iptables -A in_ping_rule -s 2.2.2.2 -p tcp --dport 22 -j REJECT #自定义链中加入规则
iptables -I INPUT 2 -s 2.2.2.2 -p tcp -j in_ping_rule #INPUT引用,第2条,当源地址2.2.为tcp时,处理交给in_ping_rule自定义链匹配
#删除自定义链
iptables -D INPUT 2 #删除引用
iptables -F in_ping_rule #清空自定义链内容
iptables -X in_ping_rule #删除链
规则保存和载入:
#保存iptables规则到文件,文件路径可自选,非固定
iptables-save > /etc/sysconfig/iptables-2021.v1
#重载文件,把文件中的命令加载到iptables
iptables-restore < /etc/sysconfig/iptables-2021.v1
规则优化思路:
使用自定义链管理特定应用的相关规则,模块化管理规则
- 优先放行双方向状态为ESTABLISHED的报文
- 服务于不同类型的功能的规则,匹配到报文可能性更大的放前面
- 服务于同一类型的功能的规则,匹配条件较为严格的放前面
- 设置默认策略(白名单机制)。不建议“iptables -P ”设置默认策略,建议最后一条写全部拒绝
案例
filter表
例1:实现拒绝所有人访问
#方法1:有小风险,如果-F了,凉凉,只能主机改
iptables -P INPUT DROP
iptables -P OUPUT DROP
#方法2:不改默认策略,只设置网卡不能入站,风险较上面小
iptables -I INPUT -i 网卡 -j REJECT
iptables -I OUTPUT -o 网卡 -j REJECT
例2:我ping别人,别人ping不通我
iptables -I OUPUT 2 -d 192.168.65.7 -p icmp --icmp-type 8 -j ACCEPT #允许8 类型代码访问外部
iptables -I INPUT 2 -d 192.168.65.7 -p icmp --icmp-type 0/0 -j ACCEPT #允许0/0 类型代码返回主机
forward表
例:允许客户机访问服务器
在内网环境中,使用1台linux主机当防火墙,所有内网主机通过防火墙主机访问外网
一般内核转发功能没有开通,网关的两个网卡,同一主机内可以互ping,但不能ping另外主机
| 节点 | ip |
|---|---|
| 客户机 | 1.1.1.10/24 |
| 网关 | 1.1.1.1/24、2.2.2.1/16 |
| web服务器 | 2.2.2.20/16 |
1)网关开启内核转发
echo “”net.ipv4.ip_forward=1" > /etc/sysctl.conf
2)添加两台机器的路由
场景1:两台主机的网关不指向本次实验网关机
#客户机添加
route add -net 2.2.2.0/16 gw 1.1.1.1
#web服务器添加
route add -net 1.1.1.10/24 gw 2.2.2.1
场景2:两台主机的网关指向本次实验网关机
#网关添加
route add -net 1.1.1.0/24 gw 1.1.1.1
route add -net 2.2.2.0/16 gw 2.2.2.1
3)允许访问web服务
#网关添加
iptables -A FORWARD -j REJECT
iptables -I FORWARD -d 2.2.0.0/16 -p tcp --sport 80 -j ACCEPT #只允许通过80端口访问外网
iptables -I FORWARD -s 1.1.1.0/24 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -I FORWARD -d 2.2.2.20 -m state --state RELATED -j ACCEPT
#以上三条条开放内网访问外网
nat表
特殊动作:
- SNAT,转换源地址,改变数据包的源地址
- MASQUERADE,IP伪装,只适用于ADSL等动态拨号上网的IP伪装,如果主机IP是静态分配的,就用snat
- DNAT,目的地址转换,改变数据包的目的地址
- REDIRECT,端口重定向,只用在本地的端口映射,可将本地80转到8080上
环境:
| 节点 | ip |
|---|---|
| 内网 | 1.1.1.10 |
| 网关 | 1.1.1.1、 2.2.2.1 |
| 外网 | 2.2.2.20 |
例1:snat模式,内ip-->网关ip-->外
2.2.2.20上抓包,显示结果已经变化
#1.1.1.0/24网段访问外网时,源ip都改用1.1.1.1
iptables -t nat -A PREROUTING -s 1.1.1.0/24 -j SNAT --to-source 2.2.2.1
例2:MASQUERADE模式
iptables -t nat -I POSTROUTING -s 1.1.1.0/24 -j MASQUERADE
例3:DNAT模式
#访问网关的80时转到1.1.1.10:8080
iptables -t nat -I PREROUTING -d 2.2.2.1/24 -p tcp --dport 80 -j DNAT --to-destination 1.1.1.10:8080
例4:REDIRECT模式
#访问 1.1.1.10:80,转为访问本地8080
iptables -A PREROUTING -t nat -d 1.1.1.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080
生产环境案例
*filter
:INPUT ACCEPT [85890:4530430]
:FORWARD ACCEPT [76814:55698470]
:OUTPUT ACCEPT [166620:238017546]
-A FORWARD -s 172.16.0.100/32 -j ACCEPT
-A FORWARD -s 172.16.0.200/32 -j ACCEPT
-A FORWARD -s 172.16.0.67/32 -j ACCEPT
#-A FORWARD -s 172.16.0.0/16 -j ACCEPT
#-A FORWARD -s 172.18.0.0/16 -j ACCEPT
#-A FORWARD -s 172.18.0.0/16 -j REJECT
#-A FORWARD -s 172.16.0.68/32 -j ACCEPT
#-A FORWARD -s 172.16.0.69/32 -j ACCEPT
#-A FORWARD -s 172.16.0.6/32 -j ACCEPT
-A FORWARD -s 172.17.200.200/32 -j ACCEPT
-A FORWARD -s 172.17.136.136/32 -j ACCEPT
-A FORWARD -s 172.17.0.100/32 -j ACCEPT
-A FORWARD -s 172.18.100.1/32 -j ACCEPT
-A FORWARD -s 172.18.0.100/32 -j ACCEPT
-A FORWARD -s 172.18.200.2/32 -j ACCEPT
-A FORWARD -s 172.18.200.3/32 -j ACCEPT
-A FORWARD -s 172.18.211.211/32 -j ACCEPT
-A FORWARD -s 172.18.212.212/32 -j ACCEPT
-A FORWARD -m iprange --src-range 172.16.0.100-172.16.0.110 -j ACCEPT
-A FORWARD -m iprange --src-range 172.17.0.100-172.17.0.110 -j ACCEPT
-A FORWARD -m iprange --src-range 172.18.0.100-172.18.0.110 -j ACCEPT
-A FORWARD -m iprange --src-range 172.17.100.6-172.17.100.16 -j ACCEPT
-A FORWARD -m iprange --src-range 172.18.100.61-172.18.100.70 -j ACCEPT
-A FORWARD -s 172.16.0.0/16 -m string --string "verycd.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "tudou.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "youku.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "iqiyi.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "pptv.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "letv.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m string --string "xunlei.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "verycd.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "tudou.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "youku.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "iqiyi.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "pptv.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "letv.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m string --string "xunlei.com" --algo kmp --to 65535 -j REJECT --reject-with icmp-port-unreachable
#-A FORWARD -s 172.18.0.0/16 -j REJECT
#-A FORWARD -s 172.16.0.0/16 -j REJECT
#-A FORWARD -i ppp0 -m string --string ".exe" --algo bm --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.18.0.0/16 -m time --timestart 08:50:00 --timestop 18:00:00 --weekdays Mon,Wed,Fri --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.17.0.0/16 -m time --timestart 08:50:00 --timestop 18:00:00 --weekdays Mon,Wed,Fri --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m time --timestart 08:50:00 --timestop 12:30:00 --weekdays Tue,Thu,Sat --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -s 172.16.0.0/16 -m time --timestart 13:50:00 --timestop 18:00:00 --weekdays Tue,Thu,Sat --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
#-A FORWARD -s 172.17.0.0/16 -m time --timestart 08:50:00 --timestop 12:30:00 --weekdays Mon,Wed,Fri --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
#-A FORWARD -s 172.17.0.0/16 -m time --timestart 13:30:00 --timestop 18:10:00 --weekdays Mon,Wed,Fri --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
#-A FORWARD -s 172.18.0.0/16 -m time --timestart 08:50:00 --timestop 18:10:00 --weekdays Mon,Wed,Fri --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmp-port-unreachable
#-A FORWARD -s 172.18.0.0/16 -m time --timestart 08:50:00 --timestop 18:10:00 --weekdays Tue,Thu --datestop 2038-01-19T11:14:07 -j REJECT --reject-with icmpport-unreachable
COMMIT
*nat
:PREROUTING ACCEPT [1429833:65427211]
:POSTROUTING ACCEPT [850518:35452195]
:OUTPUT ACCEPT [120198:9146655]
-A POSTROUTING -s 172.16.0.100/32 -j MASQUERADE
-A POSTROUTING -s 172.18.0.100/32 -j MASQUERADE
#-A POSTROUTING -s 172.16.0.200/32 -j MASQUERADE
-A POSTROUTING -s 172.16.0.69/32 -j MASQUERADE
-A POSTROUTING -s 172.17.200.200/32 -j MASQUERADE
-A POSTROUTING -s 172.17.136.136/32 -j MASQUERADE
-A POSTROUTING -s 172.17.0.100/32 -j MASQUERADE
#-A POSTROUTING -s 172.18.0.0/16 -j MASQUERADE
#-A POSTROUTING -s 172.16.0.6/32 -j MASQUERADE
-A POSTROUTING -m iprange --src-range 172.16.0.100-172.16.0.110 -j MASQUERADE
-A POSTROUTING -m iprange --src-range 172.17.0.100-172.17.0.110 -j MASQUERADE
-A POSTROUTING -m iprange --src-range 172.18.0.100-172.18.0.110 -j MASQUERADE
-A POSTROUTING -s 172.16.0.0/16 -p tcp -m multiport --dports 80,443,53,22,6666 -j MASQUERADE
-A POSTROUTING -s 172.16.0.0/16 -p udp -m multiport --dports 22 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 -p tcp -m multiport --dports 80,443,53,22,6666 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 -p udp -m multiport --dports 22 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 -p tcp -m multiport --dports 80,443,53,22,6666,1206,5938,1949 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 -p udp -m multiport --dports 22,1206,5938,1949 -j MASQUERADE
COMMIT

浙公网安备 33010602011771号