如何正确配置CentOS中的nftables?

代码编程 2025-08-24 995

CentOS下nftables配置全攻略:从入门到精通

最近在CentOS系统上折腾防火墙配置,发现很多老教程还在教iptables那一套,但你知道吗?CentOS 8开始已经默认用nftables替代iptables了,这个变化让不少像我这样的运维新手有点懵,今天我就把最近摸索的nftables配置方法整理出来,从基础到进阶,保证让你看完就能上手。

为什么选择nftables?

先说说为啥要学nftables,我最初也是抱着"既然iptables能用,干嘛要学新东西"的心态,但实际用下来发现,nftables确实有它的优势:

CentOS nftables配置方法-用户培训-用户培训
  1. 性能更好:测试发现,在处理大量规则时,nftables比iptables快30%左右
  2. 语法更简洁:一条nftables规则能完成iptables需要多条规则实现的功能
  3. 支持更全面:IPv4/IPv6统一管理,还支持ebtables的功能

举个实际例子,我之前用iptables配置NAT,需要分别写-t nat表的PREROUTING和POSTROUTING规则,而nftables中一条dnatsnat组合规则就能搞定。

安装与基本状态检查

在CentOS 8/9上,nftables通常是预装的,但为了保险,先执行:

sudo dnf install nftables -y

安装后检查版本和服务状态:

nft --version
systemctl status nftables

如果服务没启动,用sudo systemctl enable --now nftables启用,这里要注意,CentOS 8之后firewalld默认使用nftables作为后端,所以如果你同时用firewalld和nftables直接配置,可能会有冲突。

基础配置三步走

创建基础规则集

nftables的配置文件通常放在/etc/nftables.conf,我们先创建一个简单的规则集:

CentOS nftables配置方法-用户培训-用户培训
sudo vim /etc/nftables.conf

写入以下基础内容:

#!/usr/sbin/nft -f
flush ruleset
table ip filter {
    chain input {
        type filter hook input priority 0;
        # 基础允许规则
        ct state established,related accept
        iifname "lo" accept
        icmp type echo-request accept
        # 默认拒绝
        reject with icmp type host-prohibited
    }
    chain forward {
        type filter hook forward priority 0;
        reject
    }
    chain output {
        type filter hook output priority 0;
        accept
    }
}

这个配置做了几件事:

  • 清空现有规则(flush ruleset)
  • 创建filter表,包含input/forward/output三条链
  • 允许已建立的连接和回环接口
  • 允许ICMP回显请求(ping)
  • 其他输入全部拒绝

允许特定端口

假设我们要开放SSH(22)和Web(80)端口,修改input链:

chain input {
    type filter hook input priority 0;
    ct state established,related accept
    iifname "lo" accept
    icmp type echo-request accept
    # 允许SSH
    tcp dport { 22 } ct state new accept
    # 允许HTTP
    tcp dport { 80 } ct state new accept
    reject with icmp type host-prohibited
}

应用配置

保存后执行:

sudo nft -f /etc/nftables.conf

检查是否生效:

sudo nft list ruleset

进阶配置技巧

配置NAT

需要NAT时(比如做端口转发),添加一个nat表:

table ip nat {
    chain prerouting {
        type nat hook prerouting priority -100;
        # 将8080端口转发到内网80端口
        tcp dport 8080 dnat to 192.168.1.100:80
    }
    chain postrouting {
        type nat hook postrouting priority 100;
        # 内网访问外网的源NAT
        oifname "eth0" masquerade
    }
}

使用集合和映射

nftables支持集合(set)和映射(map),可以简化规则管理。

table ip filter {
    # 定义服务端口集合
    set services {
        type inet_service; flags interval;
        elements = { 22, 80, 443 }
    }
    chain input {
        type filter hook input priority 0;
        # 使用集合的规则
        tcp dport @services ct state new accept
        ...
    }
}

日志记录

要记录被拒绝的连接,可以添加日志规则:

chain input {
    type filter hook input priority 0;
    ...
    # 记录被拒绝的TCP连接
    tcp dport { 1-1024 } ct state new log prefix "Rejected TCP: " reject
    ...
}

日志会写入/var/log/messages,可以用journalctl -u nftables查看。

常见问题解决方案

配置后无法连接

我最初配置时遇到SSH被拒绝的情况,原因是:

  • 规则顺序错误:nftables按顺序匹配规则,拒绝规则放在了允许规则前面
  • 状态匹配错误:忘记加ct state new导致只允许已建立连接

解决方法:确保允许规则在拒绝规则之前,并明确指定连接状态。

与firewalld冲突

如果同时使用firewalld和直接配置nftables,会出现规则被覆盖的情况,解决方案:

  • 停用firewalld(systemctl stop firewalld)
  • 使用firewalld的nftables后端(推荐)

规则不生效

检查:

  • 语法错误:用nft -f -c /etc/nftables.conf检查语法
  • 服务未重启:修改后执行nft -f /etc/nftables.conf
  • 规则被覆盖:检查是否有其他管理工具在修改规则

实用脚本示例

这里分享一个我常用的初始化脚本:

#!/bin/bash
# CentOS nftables初始化脚本
# 安装nftables
if ! command -v nft &> /dev/null; then
    echo "安装nftables..."
    sudo dnf install nftables -y
fi
# 备份原有配置
sudo cp /etc/nftables.conf /etc/nftables.conf.bak 2>/dev/null
# 创建基础配置
cat > /tmp/nftables.conf <<EOF
#!/usr/sbin/nft -f
flush ruleset
table ip filter {
    chain input {
        type filter hook input priority 0;
        ct state established,related accept
        iifname "lo" accept
        icmp type echo-request accept
        # 允许SSH
        tcp dport { 22 } ct state new accept
        # 允许Web服务
        tcp dport { 80, 443 } ct state new accept
        reject with icmp type host-prohibited
    }
    chain forward {
        type filter hook forward priority 0;
        reject
    }
    chain output {
        type filter hook output priority 0;
        accept
    }
}
EOF
# 应用配置
sudo mv /tmp/nftables.conf /etc/nftables.conf
sudo nft -f /etc/nftables.conf
echo "nftables配置已完成,当前规则:"
sudo nft list ruleset

保存为init_nft.sh,执行chmod +x init_nft.sh后运行即可。

总结与建议

经过这段时间的实践,我总结了几点经验:

  1. 从简单开始:先配置基本的允许/拒绝规则,再逐步添加NAT、日志等高级功能
  2. 善用集合和映射:特别是管理多个端口或IP时,能大大简化规则
  3. 做好备份:修改前备份配置文件,避免配置错误导致无法连接
  4. 结合日志调试:通过日志能快速定位被拒绝的连接原因

对于CentOS用户,我建议尽早熟悉nftables,因为:

  • CentOS
CentOS中firewalld该如何正确使用以完成能力验证?
« 上一篇 2025-08-24
CentOS启动失败该如何进行排查以实现成本控制?
下一篇 » 2025-08-24

文章评论