二、区域(zone)
以下是 firewalld 中预定义的区域:
·drop:该区域的策略是拒绝所有传入的数据包,不发送任何响应。这是最严格的安全策略。
·block:该区域也拒绝所有传入的数据包,但会向发送方发送一个错误响应。
·public:该区域适用于公共网络。它允许某些传入连接,但仍然具有较高的安全策略。
·external:该区域适用于外部网络,如连接到因特网的路由器。它通常启用源地址伪装(masquerading)以支持网络地址转换。
·internal:该区域适用于内部网络,如公司局域网。它允许更多的传入连接,但仍然具有一定的安全策略。
·dmz:该区域适用于隔离区,即在内部网络和外部网络之间设置的缓冲区。它允许某些传入连接,但限制了对内部网络的访问。
·work:该区域适用于工作环境。它允许更多的传入连接,但仍然具有一定的安全策略。
·home:该区域适用于家庭网络。它允许更多的传入连接,但仍然具有一定的安全策略。
·trusted:该区域的策略是允许所有传入和传出的数据包。这是最宽松的安全策略。
三、firewalld 安装
通过 dnf 安装 firewalld:
sudo dnf install firewalld
四、firewalld 配置
firewalld 提供两个配置命令:
·firewalld 服务没有启动时,使用 firewall-offline-cmd 修改防火墙配置,添加的配置是永久性的,重启后也会保留;
·firewalld 服务正在运行时,使用 firewall-cmd 修改防火墙配置,添加的配置默认是临时性的,使用 –permanent 参数可将规则永久保存到防火墙配置文件中,并执行 firewall-cmd –reload 生效。
使用 firewalld 首先需要启动对应的 firewalld 服务,启动 firewalld 服务之前,需要确认不会影响当前系统的正常使用,通过 –list-all 可以查看默认区域及其配置:
sudo firewall-offline-cmd –list-all
输出示例:
public target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client mdns ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
默认区域为 public,允许的服务有 dhcpv6-client mdns ssh。需要注意,此处允许的服务相当于启用该服务的默认端口,例如允许 ssh 服务,则启用 22 端口,如果当前机器使用的不是默认端口,需要单独配置端口规则。
如果使用 ssh 登录机器,并且 ssh 服务监听的不是默认 22 端口,请先完成以下操作,再开启防火墙服务:
1. 确认 ssh 服务实际监听的端口号。
2. 在防火墙中启用该端口:
sudo firewall-offline-cmd –zone=public –add-port=<port>/tcp
3. 确认端口已启用后,再启动 firewalld 服务。
启动 firewalld 服务:
# 启动服务sudo systemctl start firewalld.service# 设置开机默认启动服务sudo systemctl enable firewalld.service
查看 firewalld 状态,是否运行:
sudo firewall-cmd –state
输出 running 表示服务正常运行。
当不需要使用 firewalld 时:
# 开机禁用服务sudo systemctl disable firewalld.service# 关闭服务sudo systemctl stop firewalld.service
上文提到,firewalld 提供了多个区域,查看预配置区域列表:
sudo firewall-cmd –get-zones
输出示例:
block dmz drop external home internal nm-shared public trusted work
注意:说明:内部网络可以使用 home 或 work 区域,外部网络可以使用 public 或 external 区域。
查看默认区域,默认区域为 public,在进行配置时可以使用 –zone= 指定区域,不指定则指向默认区域:
sudo firewall-cmd –get-default-zone
输出示例:
public
如果需要在 public 区域允许 http/https 服务,首先查看 firewalld 预定义服务列表,是否包含所需服务:
sudo firewall-cmd –get-services | grep http
输出示例:
… http http3 https …
添加 http、http3、https 服务到默认 public 区域,由于 public 是默认区域,因此也可以不指定 –zone 参数;使用 –permanent 参数设置为永久规则,防止防火墙重启时配置丢失:
sudo firewall-cmd –zone=public –add-service=http –permanentsudo firewall-cmd –zone=public –add-service=http3 –permanentsudo firewall-cmd –zone=public –add-service=https –permanent
查看 public 区域所有打开的端口,此时并没有输出,因为在 firewalld 中,通过服务打开的都是默认端口,不会通过 –list-ports 显示:
sudo firewall-cmd –zone=public –list-ports
如果希望为 http 服务打开一个新的端口 8080/tcp:
sudo firewall-cmd –zone=public –add-port=8080/tcp –permanent
不中断服务,并重新加载 firewall 配置:
sudo firewall-cmd –reload
检验该端口是否已经打开:
sudo firewall-cmd –query-port=8080/tcp
输出 yes 表示端口已打开。
如果需要移除端口:
sudo firewall-cmd –zone=public –remove-port=8080/tcp –permanent
五、保存、恢复配置
·保存:firewalld 会自动保存你所做的更改,因此无需执行额外操作。
·恢复:要恢复 firewalld 的配置,只需将备份的 /etc/firewalld/ 目录复制回原始位置,然后重启 firewalld 服务即可。
sudo systemctl restart firewalld
七、iptables 基础
iptables 通过表(table)、链(chain)和规则(rule)提供灵活高效的包处理和转发服务。
规则可以基于源 IP、目标 IP、源端口、目标端口、传输协议(如 TCP、UDP、ICMP)和服务类型(如 HTTP、FTP、SMTP)等条件进行匹配。可以实现阻止来自特定 IP 的流量或允许某个特定服务的功能。
八、表(Tables)
iptables 一共提供五张表,每张表都包含内置链,也可以包含用户定义的链。iptables 提供的表如下:
·filter:iptables 的默认表,用于过滤数据包。
·nat:用于网络地址转换,通常与 IP 地址重写规则一起使用。
·mangle:用于修改数据包的特定属性,例如数据包的 TTL(生存时间)和 TOS(服务类型)。
·raw:用于设置不被跟踪的数据包。
·security:用于处理与 SELinux 相关的规则。
九、链(Chains)
iptables 一共提供五条链,同时用户可以自定义链。每个链都是可以匹配一组数据包的规则列表,每个规则指定如何处理匹配的数据包。当报文经过系统时,会经过不同的链,并与链上的规则逐条匹配。iptables 提供的链如下:
·INPUT:处理进入本地系统的数据包。
·OUTPUT:处理从本地系统发出的数据包。
·FORWARD:处理在本地系统中进行路由的数据包。
·PREROUTING:处理在路由决策之前到达的数据包。
·POSTROUTING:处理在路由决策之后离开本地系统的数据包。
以下为各个表包含的链:
| 链 | filter | nat | mangle | raw | security |
| PREROUTING | – | ✓ | ✓ | ✓ | – |
| INPUT | ✓ | ✓ | ✓ | – | ✓ |
| FORWARD | ✓ | – | ✓ | – | ✓ |
| OUTPUT | ✓ | ✓ | ✓ | ✓ | ✓ |
| POSTROUTING | – | ✓ | ✓ | – | – |
十、规则(Rules)
链上包含一系列规则。每个规则包含匹配条件(match)和动作(target)。匹配条件用于匹配网络流量,而动作用于控制网络流量的处理方式。
配置防火墙的主要工作就是选取合适的表和链,添加、修改和删除这些规则。常用 target 如下:
·ACCEPT:允许数据包通过。满足匹配条件的数据包将被允许进入下一个链或被处理。
·DROP:丢弃数据包。满足匹配条件的数据包将被丢弃,防火墙不会向发送方发送任何提示或通知。
·REJECT:拒绝数据包。与 DROP 类似,满足匹配条件的数据包会被阻止。但不同之处在于 REJECT 会向数据包的发送方发送一条 ICMP 错误消息,通知对方请求被拒绝。
·LOG:记录数据包。满足匹配条件的数据包会被记录在系统日志中。通常用于调试和监控防火墙规则。
·RETURN:返回上一链。将处理返回到前一个链,接着处理该链中的下一个规则。此目标通常用于自定义链。用户规则和规定常集中在专门的链中,并在名为"用户定义链"的默认链中使用 RETURN 目标结尾。
·REDIRECT:将数据包重定向到另一个端口。类似于 DNAT 操作,但限制在一台系统的 IP 和本地数据包上。用于透明代理等应用场景。
·DNAT:目标地址转换(Destination NAT)。允许在数据包通过系统时更改目标 IP 地址。这通常用于将外部请求转发到内部网络的私有服务器。
·SNAT:源地址转换(Source NAT)。允许在数据包通过系统时更改源 IP 地址。该操作可隐藏内部网络结构,也可将内部 IP 地址映射到外部 IP 地址。
此外,iptables 还提供了许多其他的动作用于实现更复杂的网络流量控制,详见 iptables-extensions(8)。
十一、iptables 安装
通过 dnf 安装 iptables:
sudo dnf install iptables
十二、iptables 使用
以下是一个简单的例子,用于启用 iptables 并配置规则。注意 iptables 配置后立即生效,因此在进行防火墙规则配置时,需要格外注意。
首先查看 iptables 默认配置的规则,使用 –line-numbers 参数显示行号。iptables 默认表为 filter,包含 INPUT、FORWARD 和 OUTPUT 三个链。
sudo iptables –list –line-numbers
输出示例:
Chain INPUT (policy ACCEPT)num target prot opt source destinationChain FORWARD (policy ACCEPT)num target prot opt source destinationChain OUTPUT (policy ACCEPT)num target prot opt source destination
可以看到,默认表 filter 包含三条链,分别是 INPUT、FORWARD 和 OUTPUT,并且它们默认的规则都是 ACCEPT,因此当我们启动 iptables 服务时,经过系统的流量默认都会被接受。
启动 iptables 服务:
# 启动服务sudo systemctl start iptables.service# 开机自启服务sudo systemctl enable iptables.service
当不需要使用 iptables 时:
# 开机禁用服务sudo systemctl disable iptables.service# 关闭服务sudo systemctl stop iptables.service
十三、创建新规则
因为 iptables 规则是从上到下读取的,因此需要合理设置规则的顺序,当创建新规则时,可以使用 -A, –append 在规则最后追加,或者使用 -I, –insert 指定插入规则的顺序(number),如果不指定默认添加到规则列表的首行。
·添加一条规则允许通过 SSH 连接到系统:
sudo iptables -I INPUT -p tcp –dport 22 -j ACCEPT
-p 表示数据包使用 tcp 协议,–dport 表示目的端口为本机的 22 端口,-j 表示执行动作为 ACCEPT。
·添加规则,允许本地回环接口的所有流量通过防火墙:
sudo iptables -A INPUT -i lo -j ACCEPT
-i lo:匹配条件,表示仅处理通过本地回环接口(loopback interface)lo 的数据包。回环接口通常用于本地系统内的通信。
·添加规则,允许已建立连接的流量通过防火墙:
sudo iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-m 指明使用 state 匹配模块。这个模块根据数据包的连接状态来匹配数据包。–state ESTABLISHED,RELATED:匹配条件,表示仅处理已建立(ESTABLISHED)或与已建立连接相关(RELATED)的数据包。已建立的连接表示双方已经进行了数据交换。相关连接通常是指与已建立连接有关的新连接,例如 FTP 数据连接或 ICMP 错误报告。
接下来可以根据需要添加其他规则来限制或允许特定类型的流量。
十四、设置默认策略
设置最后一条策略(policy)为拒绝所有流量,如果进入系统的流量不匹配我们已有的任何规则,则拒绝以保护系统安全。
注意:警告:
注意:iptables 配置后立即生效,因此配置 DENY ALL 规则需要格外谨慎。
sudo iptables -A INPUT -j DROP
也可以通过 -P 直接设置每条链的策略,策略值必须为 ACCEPT 或者 DROP,例如刚刚通过 -A 设置的策略也可以通过 -P 设置:
sudo iptables -P INPUT DROP
十五、允许/拒绝特定 IP
·允许特定 IP 访问:
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT
·拒绝特定 IP 访问:
sudo iptables -A INPUT -s 10.0.0.50 -j DROP
·允许特定 IP 段访问特定端口:
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp –dport 80 -j ACCEPT
十六、允许/拒绝特定端口
·允许 HTTP(80)和 HTTPS(443)端口:
sudo iptables -A INPUT -p tcp –dport 80 -j ACCEPTsudo iptables -A INPUT -p tcp –dport 443 -j ACCEPT
·拒绝特定端口访问:
sudo iptables -A INPUT -p tcp –dport 3306 -j DROP
·允许多个端口(如 8080 和 8443):
sudo iptables -A INPUT -p tcp -m multiport –dports 8080,8443 -j ACCEPT
十七、NAT 配置
iptables 的 nat 表用于网络地址转换,常用于共享上网、端口转发等场景。
·SNAT(源地址转换):用于将内部网络的源 IP 转换为公网 IP,实现共享上网:
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT –to-source 203.0.113.1
·MASQUERADE(动态 SNAT):适用于公网 IP 动态获取的场景(如 ADSL 拨号上网):
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
·DNAT(目标地址转换):用于将外部请求转发到内部服务器,实现端口转发:
sudo iptables -t nat -A PREROUTING -p tcp –dport 80 -j DNAT –to-destination 192.168.1.100:8080
·端口重定向:将本机 80 端口的流量重定向到 8080 端口(透明代理常用):
sudo iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080
开启 IP 转发功能(NAT 前必须配置):
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
永久生效需修改 /etc/sysctl.conf:
net.ipv4.ip_forward = 1
执行 sudo sysctl -p 使其生效。
十八、删除规则
注意:删除规则立即生效。若误删放行 SSH 等关键连接的规则,可能导致当前会话中断且无法再建立新连接。请你在删除前先核对规则编号及对应内容,并确保保留了必要的放行规则。
需要指定列表(INPUT、OUTPUT 或 FORWARD)以及该列表中规则的行号(line-numbers),删除命令没有输出。
sudo iptables –list –line-numbers
输出示例:
Chain INPUT (policy ACCEPT)num target prot opt source destination1 ACCEPT tcp — anywhere anywhere tcp dpt:ssh2 ACCEPT all — anywhere anywhere3 ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED4 DROP all — anywhere anywhereChain FORWARD (policy ACCEPT)num target prot opt source destinationChain OUTPUT (policy ACCEPT)num target prot opt source destination
删除 INPUT 列表的第四条规则,即 DENY ALL 规则:
sudo iptables -D INPUT 4
十九、保存、恢复配置
如需保存当前的 iptables 规则,可以使用 iptables-save 命令将规则输出到文件:
sudo iptables-save > /etc/sysconfig/iptables
如需恢复 iptables 规则,可以使用 iptables-restore 命令从文件中加载规则:
sudo iptables-restore < /etc/sysconfig/iptables
如需查看更多参数以及信息:iptables –help、iptables(8)。
21、nftables 基础
nftables 引入了新的、更简洁的语法,能够更加灵活地处理数据包。相比于 iptables,更推荐使用 nftables 进行防火墙管理。
nftables 通过表(table)、链(chain)和规则(rule)进行规则管理,与 iptables 类似。nftables 默认不创建任何表。
22、地址族(Address families)
nftables 的每张表都有一个对应的地址族(Address families),决定处理的数据包类型。新建一张 nftables 表需要指定地址族,如果不指定,默认值为 ip。
·ip:IPv4 地址族。
·ip6:IPv6 地址族。
·inet:IPv4/IPv6 地址族。
·arp:ARP 地址族,处理 IPv4 ARP 包。
·bridge:网桥地址族,处理通过网桥设备的数据包。
·netdev:Netdev 地址族,处理入口和出口的数据包。
23、nftables 安装
通过 dnf 安装 nftables:
sudo dnf install nftables
24、nftables 配置
使用 nftables 服务的前提是启动对应的 nftables 服务,由于 nftables 默认不创建任何表,也没有任何规则,因此启动 nftables 服务不会对系统有影响。
启动 nftables 服务:
# 启动服务sudo systemctl start nftables.service# 设置开机默认启动服务sudo systemctl enable nftables.service
当不需要使用 nftables 时:
# 开机禁用服务sudo systemctl disable nftables.service# 关闭服务sudo systemctl stop nftables.service
25、创建表和链
查看当前规则并列出所有表信息,nftables 默认不创建任何表,因此输出应该为空:
sudo nft list ruleset
1. 创建一张名为 filter 的新表,作用是过滤数据包,指定地址族为 inet,处理 IPv4/IPv6 相关的数据包:
sudo nft add table inet filter
add 后面可以接 table、chain、rule,分别表示添加表、添加链、添加规则。
2. 为 filter 表创建名为 input 的基本链,基本链是来自网络栈数据包的入口点:
sudo nft add chain inet filter input { type filter hook input priority 0 \\; policy accept \\; }
反斜杠 \\ 用来转义,避免 Shell 将分号解释为命令结束。
3. 列出链信息,筛选地址族为 inet,表名为 filter 的表中,名为 input 的链:
sudo nft list chain inet filter input
输出示例:
table inet filter { chain input { type filter hook input priority filter; policy accept; }}
26、配置规则
添加允许 ssh 登录的规则,dport 可以接常见服务名称,也可以接具体的端口号:
sudo nft add rule inet filter input tcp dport ssh accept
查看当前规则集:
sudo nft list ruleset
输出示例:
table inet filter { chain input { type filter hook input priority filter; policy accept; tcp dport ssh accept }}
可以看到添加了 ssh 默认的 22 端口规则。
·添加允许 HTTP 和 HTTPS 流量的规则:
sudo nft add rule inet filter input tcp dport http acceptsudo nft add rule inet filter input tcp dport https accept
·允许已建立连接的流量通过防火墙:
sudo nft add rule inet filter input ct state established,related accept
·允许 ICMP 流量(ping):
sudo nft add rule inet filter input ip protocol icmp acceptsudo nft add rule inet filter input ip6 nexthdr ipv6-icmp accept
·允许本地回环接口的流量:
sudo nft add rule inet filter input iifname "lo" accept
·设置默认拒绝策略,在以上规则之后添加拒绝所有流量的规则:
sudo nft add rule inet filter input drop
注意:说明:
注意:nftables 规则也是从上到下匹配的,因此 drop 规则应放在允许规则之后,否则所有流量都将被拒绝。
27、配置 NAT
nftables 同样支持 NAT 功能。首先需要在 nat 表创建相应的链:
·创建 nat 表:
sudo nft add table inet nat
·创建 PREROUTING 链(用于 DNAT):
sudo nft add chain inet nat prerouting { type nat hook prerouting priority -100 \\; policy accept \\; }
·创建 POSTROUTING 链(用于 SNAT):
sudo nft add chain inet nat postrouting { type nat hook postrouting priority 100 \\; policy accept \\; }
·MASQUERADE(动态 SNAT):
sudo nft add rule inet nat postrouting oifname "eth0" masquerade
·DNAT(端口转发):将外部 80 端口转发到内部服务器 192.168.1.100:8080:
sudo nft add rule inet nat prerouting tcp dport 80 dnat to 192.168.1.100:8080
28、查看规则(带行号)
使用 -a 参数查看规则的 handle(句柄号),用于删除规则时指定:
sudo nft -a list ruleset
输出示例:
table inet filter { chain input { type filter hook input priority filter; policy accept; tcp dport ssh accept # handle 2 tcp dport http accept # handle 3 tcp dport https accept # handle 4 drop # handle 5 }}
29、删除规则
注意:警告:
注意:删除、清空规则立即生效。误删放行 SSH 等关键连接的规则会导致连接中断;清空所有规则集(flush ruleset)后,链的默认策略将放行所有流量,存在安全风险。请你在操作前先确认规则内容,并保留必要的放行规则。
通过 handle 删除指定规则:
sudo nft delete rule inet filter input handle 5
30、清空规则
·清空指定链中的所有规则:
sudo nft flush chain inet filter input
·清空指定表中的所有链和规则:
sudo nft flush table inet filter
·清空所有规则集:
sudo nft flush ruleset
31、删除链和表
·删除链(链必须为空或无规则引用):
sudo nft delete chain inet filter input
·删除表:
sudo nft delete table inet filter
32、保存、恢复配置
nftables 的配置文件默认位于 /etc/sysconfig/nftables.conf 或 /etc/nftables.conf。
1. 保存当前规则到文件:
sudo nft list ruleset | sudo tee /etc/nftables.conf
2. 从文件加载规则:
sudo nft -f /etc/nftables.conf
3. 重启 nftables 服务会自动加载配置文件中的规则:
sudo systemctl restart nftables.service
一个完整的 nftables 配置文件示例(/etc/nftables.conf):
#!/usr/sbin/nft -fflush rulesettable inet filter { chain input { type filter hook input priority 0; policy drop; # 允许本地回环接口 iifname "lo" accept # 允许已建立连接的流量 ct state established,related accept # 允许 SSH tcp dport ssh accept # 允许 HTTP 和 HTTPS tcp dport { http, https } accept # 允许 ICMP (ping) ip protocol icmp accept ip6 nexthdr ipv6-icmp accept # 拒绝其他所有流量 drop } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; }}
如果需要查看更多参数以及信息:nft –help、nft(8)。
33、nftables 与 iptables 的对比
| 特性 | iptables | nftables |
| 语法 | 每条规则单独命令,语法较复杂 | 语法更简洁,支持脚本化配置 |
| 表/链 | 预定义表和链,灵活性有限 | 可自由创建表和链,灵活性更高 |
| 地址族 | ipv4、ipv6、arp、bridge 分别使用不同命令 | 统一使用 inet 地址族处理 IPv4/IPv6 |
| 规则更新 | 每条规则更新需替换整个规则集 | 支持增量更新,性能更高 |
| 配置文件 | /etc/sysconfig/iptables | /etc/nftables.conf |
| NAT | 支持,需指定 nat 表 | 支持,语法更简洁 |
| 状态跟踪 | -m state –state | ct state(connection tracking) |
| 集合 | 不支持 | 支持命名集合,简化规则管理 |
34、从 iptables 迁移到 nftables
nftables 提供了 iptables-translate 和 ip6tables-translate 工具,可以将 iptables 规则自动转换为 nftables 格式。
转换 iptables 规则:
sudo iptables-translate -A INPUT -p tcp –dport 22 -j ACCEPT
输出示例:
add rule inet filter input tcp dport 22 counter accept
转换 ip6tables 规则:
sudo ip6tables-translate -A INPUT -p tcp –dport 22 -j ACCEPT
输出示例:
add rule inet filter input tcp dport 22 counter accept
批量转换已有规则:
sudo iptables-save | sudo iptables-restore-translate
该命令会将 iptables-save 输出的所有规则批量转换为 nftables 格式,方便整体迁移。
注意:说明:
注意:转换后的规则需要根据 nftables 的表和链结构进行适当调整。建议在迁移前充分测试 nftables 规则,确保防火墙策略正确无误。