TencentOS Server 提供了三种防火墙管理工具:firewalld、iptables 和 nftables。firewalld 是默认推荐的高级防火墙管理工具;iptables 是传统的防火墙工具;nftables 是新一代防火墙框架,将逐步替代 iptables。
firewalld
区域(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
输出示例:
publictarget: defaulticmp-block-inversion: nointerfaces:sources:services: dhcpv6-client mdns sshports:protocols:forward: yesmasquerade: noforward-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 基础
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)。nftables
nftables 基础
nftables 引入了新的、更简洁的语法,能够更加灵活地处理数据包。相比于 iptables,更推荐使用 nftables 进行防火墙管理。
nftables 通过表(table)、链(chain)和规则(rule)进行规则管理,与 iptables 类似。nftables 默认不创建任何表。
地址族(Address families)
nftables 的每张表都有一个对应的地址族(Address families),决定处理的数据包类型。新建一张 nftables 表需要指定地址族,如果不指定,默认值为 ip。
ip:IPv4 地址族。
ip6:IPv6 地址族。
inet:IPv4/IPv6 地址族。
arp:ARP 地址族,处理 IPv4 ARP 包。
bridge:网桥地址族,处理通过网桥设备的数据包。
netdev:Netdev 地址族,处理入口和出口的数据包。
nftables 安装
通过 dnf 安装 nftables:
sudo dnf install nftables
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
创建表和链
查看当前规则并列出所有表信息,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;}}
配置规则
添加允许 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 规则应放在允许规则之后,否则所有流量都将被拒绝。配置 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
查看规则(带行号)
使用
-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 2tcp dport http accept # handle 3tcp dport https accept # handle 4drop # handle 5}}
删除规则
警告:
删除、清空规则立即生效。误删放行 SSH 等关键连接的规则会导致连接中断;清空所有规则集(
flush ruleset)后,链的默认策略将放行所有流量,存在安全风险。请您在操作前先确认规则内容,并保留必要的放行规则。通过 handle 删除指定规则:
sudo nft delete rule inet filter input handle 5
清空规则
清空指定链中的所有规则:
sudo nft flush chain inet filter input
清空指定表中的所有链和规则:
sudo nft flush table inet filter
清空所有规则集:
sudo nft flush ruleset
删除链和表
删除链(链必须为空或无规则引用):
sudo nft delete chain inet filter input
删除表:
sudo nft delete table inet filter
保存、恢复配置
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# 允许 SSHtcp dport ssh accept# 允许 HTTP 和 HTTPStcp dport { http, https } accept# 允许 ICMP (ping)ip protocol icmp acceptip6 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)。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) |
集合 | 不支持 | 支持命名集合,简化规则管理 |
从 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 规则,确保防火墙策略正确无误。