iptables和firewalld相关
1. 基本概念
1.1. 4表5链
防火墙由很多规则组成,每个规则匹配产生不同的动作,这些规则按功能共划分出4个表,一个表由多个相同功能的规则组成:
- raw 控制NAT表中连接跟踪机制的启用状况
- mangle 修改数据
- filter 过滤
- nat 地址转换
在数据经过的各个路径上,设置了5个关键卡点,每个卡点上按顺序有多个规则,共组成5条规则链:
- PREROUTING: 外部数据刚进入
- INPUT: 经过路由决策,要进入本机的数据
- OUTPUT: 本机要出去的数据
- FORWARD: 经过路由决策,经过本机转发的数据
- POSTROUTING: 发送出去的数据
外部数据进入本机,会经过 PREROUTING, INPUT链
本机数据出去,会经过 OUTPUT, POSTROUTING链
外部数据经过本机路由转发出去,会经过 PREROUTING, FORWARD, POSTROUTING链
表 | 控制的链 |
---|---|
filter | INPUT, FORWARD, OUTPUT |
nat | PREROUTING, INPUT, OUTPUT, POSTROUTING |
mangle | PREROUTING, INPUT, FORWARD, POSTROUTING |
raw | PREROUTING, OUTPUT |
raw | mangle | nat | filter | |
---|---|---|---|---|
PREROUTING | √ | √ | √ | |
INPUT | √ | √ | ||
OUTPUT | √ | √ | √ | √ |
FORWARD | √ | √ | ||
POSTROUTING | √ | √ |
在同一条链上,各个表中的规则会按顺序执行,表的优先级为:
raw --> mangle --> nat --> filter
可以自定义链,但是自定义的子链需要当做默认链中一个规则的动作才能被调用到。
1.2. 基本语法
iptables [-t table] COMMAND [chain] CRETIRIA -j ACTION
- -t: 指定要维护的表,默认filter
- COMMAND: 子命令,定义对规则的管理
- chain: 指定链
- CRETIRIA: 匹配参数
- ACTION: 要触发的动作
常用命令 COMMAND
选项 | 功能 |
---|---|
-A | 添加防火墙规则 |
-D | 删除防火墙规则 |
-I | 插入防火墙规则 |
-F | 清空防火墙规则 |
-L | 列出防火墙规则 |
-R | 替换防火墙规则 |
-Z | 清空防火墙数据表统计信息 |
-P | 设置链默认规则 |
-E | 给子链改名 |
-X | 删除一个没有被引用、规则为空的子链 |
常用匹配参数 CRETIRIA
参数 | 功能 |
---|---|
[!]-p | 匹配协议,!表示取反 |
[!]-s | 匹配源地址 |
[!]-d | 匹配目标地址 |
[!]-i | 匹配入站网卡接口 |
[!]-o | 匹配出站网卡接口 |
[!]--sport | 匹配源端口 |
[!]--dport | 匹配目标端口 |
[!]--src-range | 匹配源地址范围 |
[!]--dst-range | 匹配目标地址范围 |
[!]--limit | 匹配数据表速率 |
[!]--mac-source | 匹配源MAC地址 |
[!]--state | 匹配状态(INVALID, ESTABLISHED, NEW, RELATED) |
[!]--string | 匹配应用层字符串 |
常用动作
触发动作 | 功能 |
---|---|
ACCEPT | 允许数据包通过 |
DROP | 丢弃数据包 |
REJECT | 拒绝数据包通过 |
LOG | 将数据包信息记录syslog日志 |
DNAT | 目标地址转换 |
SNAT | 源地址转换 |
MASQUERADE | 地址欺骗 |
REDIRECT | 重定向 |
内核按照顺序检查 iptables 防火墙规则,如果匹配,就执行相关动作, 停止向下继续查找,如果都没有匹配,就按默认处理
2. iptables 和 firewalld
- 都是linux防火墙服务,早期的是 iptables,新的系统一般都是 firewalld。 firewalld 操作会反应到 iptables 规则。
- iptables 只能一条一条规则添加,firewalld 支持将不同的规则组成区域(zone,共9个,默认public),在不同的网络环境使用不同的区域,快速切换。
- 都可以用 systemctl 管理,firewalld 是 centos7自带的,可以直接使用
systemctl status firewalld
, iptables 需要安装一个服务配置:
yum install -y iptables-services
然后就能用 systemctl 管理了。
- iptables 和 firewalld 都是服务,iptables 和 firewall-cmd 都是用户命令行接口,用于控制这两个服务, 只不过 firewalld 的服务和前端是两个名字, iptables 是一个名字。
- centos7 默认使用 firewalld, 使用 firewall-cmd 配置的规则,也能用 iptables 查看,反过来也一样。
3. iptables 例子
3.1. 导入导出当前规则
$ iptables-save
# Generated by iptables-save v1.4.21 on Sun Jun 12 08:08:48 2022
*filter
# 下面是 filter 表的规则
# filter 表中 INPUT 链默认规则是 ACCEPT, [0:0] 表示[packet, bytes], 当前有多少个包经过 filter 表的这个链
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1437:138710]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Sun Jun 12 08:08:48 2022
# 保存到文件
$ iptables-save > ipt.save
# 从文件恢复
$ iptables-restore < ipt.save
# 重启机器后失效,需要保存到文件,重启时导入
# 这里会保存到 /etc/sysconfig/iptables, 相当于使用 iptables-save > /etc/sysconfig/iptables
$ service iptables save
# 保存到其他位置,需要重启的时候增加一个启动项,将配置恢复,一般是放到 /etc/rc.local 中
3.2. 查
# 查看 filter 表所有规则, -v 显示统计值, -n 不解析地址, -L 列出规则
# 结果: policy 表示 filter 表 INPUT 链的默认规则是 ACCEPT
$ iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2566 182K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
6 438 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
1 52 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
33 3006 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 2244 packets, 222K bytes)
pkts bytes target prot opt in out source destination
# 列出 filter 表 INPUT 链的所有规则, --line-numbers(有时候可以用--line匹配) 列出规则序号,方便中间插入时使用
iptables -vnL INPUT --line-numbers
# 列出 nat 表的所有规则
iptables -t nat -vnL
3.3. 增
# 在 filter 表 INPUT 链开头插入一条规则, 匹配源地址, 动作是丢弃报文. DROP是直接丢弃, REJECT 是会通知对端该报文被拒绝
$ iptables -t filter -I INPUT -s 192.168.1.145 -j DROP
# 在 filter 表 INPUT 链的第2个位置插入规则
$ iptables -t filter -I INPUT 2 -s 192.168.1.145 -j DROP
# 在最后增加规则
$ iptables -t filter -A INPUT -s 192.168.1.145 -j DROP
3.4. 删
# 删除 filter 表 INPUT 链第3条规则
$ iptables -t filter -D INPUT 3
# 删除 filter 表 INPUT 链所有规则
$ iptables -t filter -F INPUT
3.5. 改
# 改的时候,需要带上原来的规则匹配语句,这里的改,相当于删掉之前的语句,重写一个规则,所以即使有规则序号,也要写完整原来的规则
$ iptables -t filter -R INPUT 1 -s 192.168.1.146 -j REJECT
# 修改链的默认策略
iptables -t filter -P FORWARD DROP
3.4. 条件匹配
基本匹配
# 匹配源地址
-s 192.168.1.145
# 指定多个源地址,逗号隔开, 会变成两条相邻的规则
-s 192.168.1.123,192.168.1.124
# 指定网段
-s 10.6.0.0/16
# 条件取反,只是规定了不是这个IP的会怎样,没有规定是这个IP会怎样
! -s 192.168.1.123
# 匹配目标地址
-d 192.168.1.101
# 一个规则多个条件,必须都满足才算匹配
-s 1.2.3.4 -d 2.3.4.5
# 匹配协议, tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh, 或者 -p all,默认是所有协议
-p tcp
# 匹配入口网卡, -o 匹配出口网卡,指定数据从哪个网卡出去
-i eth0
扩展匹配
# tcp: 匹配端口,必须用 -p 指定协议, 用 -m 指定扩展模块(协议名和模块名一致的话,可以省略 -m)
-p tcp -m tcp --dport 9999
# tcp: 反选
! --dport 22
# tcp: 匹配端口段,:22 表示0-22的段, 80: 表示 80以后的段, 22:25 表示 22-25的段,tcp模块只能指定连续的段
--dport 22:25
# tcp: 匹配tcp-flags,前一段表示要匹配的位,后一段表示哪一位必须位1。以下两条匹配效果一样,都匹配三次握手的第2个包。
-p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK
-p tcp -m tcp --dport 22 --tcp-flags ALL SYN,ACK
# tcp: 匹配三次握手第一个包
-p tcp -m tcp --dport 22 --syn
# multiport: 匹配零散的端口段,需要用到 multiport 模块, 只能用于 tcp, udp协议
-p tcp -m multiport --dports 22,36,80
# iprange: 匹配IP地址段, --src-range, --dst-range
-m iprange --src-range 192.168.1.127-192.168.1.146
# string: 匹配字符串, --algo bm 指定匹配算法
-m string --algo bm --string "OOXX"
# time: 匹配时间段
-p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00
-p tcp --dport 80 -m time --weekdays 6,7
-p tcp --dport 80 -m time --monthdays 22,23
# connlimit: 限制每个IP地址同时连接到服务器的数量,不能指定IP。限制每个ip不能连接超过2个ssh通道
-p tcp --dport 22 -m connlimit --connlimit-above 2
# limit: 限制单位时间内包速率,使用令牌桶算法进行限速, --limit 限制令牌产生速度, --limit-burst 限制令牌最大个数
# /second, /minute, /hour, /day
-p icmp -m limit --limit 10/minute --limit-burst 3
# state: 连接状态跟踪,tcp,udp,icmp 都有状态,状态有5种:
# NEW: 连接第一个包
# ESTABLISHED: NEW状态之后的包的状态,连接已建立
# RELATED: 相关联的连接
# INVALID: 无法被识别状态的包
# UNTRACKED: 未被跟踪的包,无法找到相关连接
4. 自定义子链
用于集合一组规则。
# 添加子链
-t filter -I IN_WEB -s 192.168.1.123 -j REJECT
# 必须在默认链中使用子链,子链才生效
-I INPUT -p tcp --dport 80 -j IN_WEB
# 给子链改名
-E IN_WEB WEB
# 删除子链
-X WEB
5. 动作
# -j REJECT --reject-with: 提示对方为什么会被拒绝, 默认是icmp-port-unreachable
# icmp-net-unreachable icmp-host-unreachable icmp-port-unreachable icmp-proto-unreachable icmp-net-prohibited icmp-host-pro-hibited icmp-admin-prohibited
-j REJECT --reject-with icmp-port-unreachable
# LOG: 记录匹配的数据包到日志 syslog 中, /var/log/messages, 不进行其他动作
-j LOG --log-level info --log-prefix 'want-in-from-port-22'
# SNAT, DNAT
# MASQUERADE 动态做SNAT,SNAT需要指定转换的目标地址,但有时候目标地址是动态的,用 MASQUERADE 可以自动选择可用地址进行转换.
6. firewalld 使用
# 基本操作
firewall-cmd --state # 显示状态
firewall-cmd --reload # 重新加载服务
firewall-cmd --runtime-to-permanent # 将当前防火墙规则永久保存
firewall-cmd --check-config # 检查配置正确性
# 区域操作
firewall-cmd --get-zones # 所有支持的区域
firewall-cmd --get-active-zones # 查看当前使用的区域信息
firewall-cmd --set-default-zone=public # 设置默认接口区域,立即生效无需重启
# 服务操作, 类似于将端口可视化,服务需要在配置文件中添加,/etc/firewalld 目录下有services文件夹
--add-service=smtp # 添加服务
--remove-service=smtp # 移除服务
firewall-cmd --get-services # 获取所有可以支持的服务列表
# 端口操作
firewall-cmd --add-port=443/tcp # 打开443/TCP端口,这里直接生效,不需要 --reload,但没有写入配置永久生效,可以执行 --runtime-to-permanent,写入配置文件
firewall-cmd --permanent --add-port=3690/tcp # 永久打开3690/TCP端口, 这里是写入到配置文件,并没有生效,需要 --reload
firewall-cmd --zone=public --add-port=0-65535/tcp --permanent # 打开所有端口
firewall-cmd --remove-port 9999/tcp
firewall-cmd --list-ports
# FirewallD包括一种直接模式,直接用iptables的规则,例如打开TCP协议的9999端口
firewall-cmd --direct -add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT
firewall-cmd --reload
# 限制IP 192.168.0.200 访问 80 的tcp端口
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.200" port protocol="tcp" port="80" reject"
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.0.200" port protocol="tcp" port="80" accept"
# 限制IP 192.168.0.200 访问
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.200" reject"
# 限制 IP 段访问
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.0/24" reject"
7. 一个例子
# 启动,加开机启动项
systemctl start firewalld
systemctl enable firewalld
# 启动后,默认值打开 ssh 端口,下面打开所有端口的访问
firewall-cmd --permanent --add-port=0-65535/tcp
firewall-cmd --permanent --add-port=0-65535/udp
firewall-cmd --reload
# 限制某个IP访问
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.200" reject"
firewall-cmd --reload
# 以下可以删除限制
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.0.200" reject"
firewall-cmd --reload
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术