nftables怎样管理Linux防火墙

联启 网络工具 15

本文目录导读:

nftables怎样管理Linux防火墙-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

  1. 核心架构概念
  2. 环境准备:安装与启用
  3. 基础操作:nft 命令行
  4. 核武器:集 (Sets)
  5. 保存与加载规则
  6. 实用场景示例
  7. 常见问题与排错
  8. 总结:nftables vs iptables

nftables 是 Linux 内核自 3.13 版本起引入的新一代防火墙框架,旨在替代传统的 iptables(以及 ip6tablesebtables 等),它提供了更简洁的语法、更好的性能(规则集原子性替换)以及更清晰的架构。

以下是关于 nftables 管理 Linux 防火墙 的完整指南,从基础概念到常用操作。


核心架构概念

iptables(有多个表和固定链,不可扩展)不同,nftables 的核心是表 (Tables)链 (Chains)规则 (Rules)

  • 表 (Table):规则集的最高层级容器,每个表通常对应一个地址族 (Address Family)
    • ip:IPv4 协议(默认)
    • ip6:IPv6 协议
    • inet:同时适用于 IPv4 和 IPv6 的混合表(强烈推荐,能减少一半规则)
    • arp:ARP 协议
    • bridge:网桥(二层)过滤
    • netdev:处理入口路径上的数据包(基于网卡,非常底层)
  • 链 (Chain):规则的集合,有两种类型:
    • 基础链 (Base Chain):直接挂载在协议栈钩子点(如 preroutinginputforwardoutputpostrouting),需要指定钩子 (hook)优先级 (priority)策略 (policy)(accept 或 drop)。
    • 普通链 (Regular Chain):作为跳转目标,用于规则分组和复用(类似函数调用)。
  • 规则 (Rule):匹配条件 + 动作(裁决),格式:匹配表达式 动作表达式
  • 集 (Sets)nftables 最强大的功能之一,可以存储 IP 地址、端口、网卡等元素的列表或区间,供规则引用,支持匿名集(直接写在规则中)和命名集(可动态更新,性能极高)。

环境准备:安装与启用

大多数现代 Linux 发行版(CentOS 8+、RHEL 8+、Fedora、Ubuntu 20.04+、Debian 11+)已默认安装或可通过包管理器安装。

# 查看是否安装
nft --version
# 如果未安装(以 Debian/Ubuntu 为例)
sudo apt update && sudo apt install nftables
# 以 RHEL/CentOS/Fedora 为例
sudo dnf install nftables

启动并设置开机自启(强烈建议先关掉旧的 iptables 避免冲突)

# 1. 停止并屏蔽旧的 iptables/ip6tables/ebtables 服务(如果有)
sudo systemctl stop iptables ip6tables ebtables
sudo systemctl disable iptables ip6tables ebtables
# 2. 启用 nftables
sudo systemctl enable nftables --now
# 3. 检查状态
sudo systemctl status nftables

基础操作:nft 命令行

所有管理都通过 nft 命令完成,可以是交互式(nft -i)或单次命令。

1 查看当前规则

# 列出所有规则集(包括所有表、链、规则)
sudo nft list ruleset
# 只列出特定地址族和表
sudo nft list table inet filter
# 格式化输出(便于阅读)
sudo nft list ruleset | less

2 创建表

# 创建一个 inet 类型的表,名为 "filter"(最常用)
sudo nft add table inet filter
# 也可以创建 IPv4 专用表
sudo nft add table ip mytable

3 创建基础链(Base Chain)

# 在 inet filter 表中创建 input 链
sudo nft add chain inet filter input {
    type filter hook input priority 0
    policy drop    # 关键点:设置默认策略(accept 或 drop)
}
# 创建 forward 和 output 链(default policy accept)
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy accept \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
  • hookprerouting | input | forward | output | postrouting | ingress (netdev)
  • priority:数字或名称(如 raw=300, mangle=150, filter=0, nat=-100),数字越小优先级越高,越早处理。
  • policyaccept(如果未匹配任何规则则允许)或 drop(如果未匹配则丢弃)。对于 input 链,建议设为 drop 并显式放行需要的流量

4 添加规则

规则按照顺序匹配,一旦匹配则执行动作(accept, drop, jump, continue, return 等)。

# 1. 允许本地回环接口 (lo 接口)
sudo nft add rule inet filter input iif lo accept
# 2. 允许与现有连接相关的回包(状态防火墙)
sudo nft add rule inet filter input ct state established,related accept
# 3. 允许 SSH (端口 22) 入站
sudo nft add rule inet filter input tcp dport 22 accept
# 4. 允许 HTTP/HTTPS (80, 443)
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
# 5. 允许 ICMP (ping)
sudo nft add rule inet filter input ip protocol icmp accept
# 6. 拒绝所有其他 SSH 尝试(记录日志并拒绝)
sudo nft add rule inet filter input tcp dport 22 reject with tcp reset
# 7. 允许从特定 IP 访问 (源地址过滤)
sudo nft add rule inet filter input ip saddr 192.168.1.100 tcp dport 3306 accept
# 8. 允许来自特定网段的流量
sudo nft add rule inet filter input ip saddr 10.0.0.0/8 accept
# 9. 限制连接速率(防止端口扫描)
sudo nft add rule inet filter input tcp dport 2222 limit rate 10/minute accept

核武器:集 (Sets)

集是 nftables 的核心优势,大幅简化并加速复杂规则。

1 匿名集 (Anonymous Set)

直接在规则中用花括号 定义,适用于少量元素。

# 允许从 192.168.1.1, 192.168.1.2, 172.16.0.1 访问 SSH
sudo nft add rule inet filter input \
    ip saddr { 192.168.1.1, 192.168.1.2, 172.16.0.1 } tcp dport 22 accept

2 命名集 (Named Set) —— 动态管理利器

命名集可以独立于规则被更新(添加/删除元素),无需重新加载整个规则集,非常适合动态 IP 黑/白名单。

# 1. 创建一个命名为 "whitelist" 的 IPv4 地址集
sudo nft add set inet filter whitelist {
    type ipv4_addr
    flags interval    # 可选:支持子网 /24
    elements = { 192.168.1.0/24, 10.10.10.5 }
}
# 2. 创建一个名为 "blacklist" 的 IPv4 地址集
sudo nft add set inet filter blacklist {
    type ipv4_addr
}
# 3. 在规则中引用命名集
sudo nft add rule inet filter input ip saddr @whitelist accept                      # 白名单直接接受
sudo nft add rule inet filter input ip saddr @blacklist drop                        # 黑名单直接丢弃
sudo nft add rule inet filter input tcp dport 80 ip saddr @whitelist accept         # 更精细的匹配
# 4. 动态管理命名集(添加/删除元素,无需重启 nft)
sudo nft add element inet filter whitelist { 172.16.0.10 }
sudo nft delete element inet filter blacklist { 10.0.0.1 }
# 5. 查看命名集内容
sudo nft list set inet filter whitelist

集合类型优点:使用 @set 引用集合比写多条独立规则性能高得多(哈希查找),且维护方便。


保存与加载规则

规则默认不持久化在配置文件中,你需要手动保存。

1 方法一:使用 nftables 服务(推荐)

nftables 默认读取 /etc/nftables.conf

# 1. 将当前运行中的规则集导出到文件
sudo nft list ruleset > /etc/nftables.conf
# 2. 或者通过 systemd 保存(自动调用 nft list ruleset > 某个位置)
sudo systemctl restart nftables    # 重启后会自动读取配置
# 但注意:直接 systemctl restart nftables 会清空运行中的规则,然后读取 /etc/nftables.conf
# 所以最佳实践是:修改配置 -> 保存 -> 激活
sudo nft -f /path/to/your_rules.conf   # 加载一个规则文件

2 方法二:使用 nft -f 加载文件

创建一个规则文件,~/my_rules.nft

#!/usr/sbin/nft -f
# 清空整个规则集
flush ruleset
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        iif lo accept
        ct state established,related accept
        ip saddr @whitelist accept
        tcp dport ssh accept
        # ... 其他规则
    }
    chain forward {
        type filter hook forward priority 0; policy drop;
        # ...
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
    set whitelist {
        type ipv4_addr
        elements = { 192.168.1.0/24, ... }
    }
}

然后执行:

sudo nft -f ~/my_rules.nft

注意flush ruleset 会清空所有现有规则,务必小心。


实用场景示例

1 标准 Linux 桌面防火墙(允许本地、已建立连接、SSH、Web)

sudo nft add table inet filter
sudo nft add chain inet filter input   { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output  { type filter hook output priority 0 \; policy accept \; }
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input tcp dport { 22, 80, 443 } accept
sudo nft add rule inet filter input icmp type echo-request accept

2 简单的 NAT(网络地址转换)

# 创建一个 NAT 表
sudo nft add table ip nat
# 创建源 NAT 链 (postrouting)
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# 添加 MASQUERADE(伪装):适用于动态 IP 的上网共享
sudo nft add rule ip nat postrouting oif eth0 masquerade
# 创建目的 NAT 链 (prerouting),并添加端口转发(将 2222 转发到内网 192.168.1.10 的 22 端口)
sudo nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add rule ip nat prerouting tcp dport 2222 dnat to 192.168.1.10:22

常见问题与排错

1 规则覆盖或顺序错误

  • 检查规则顺序:nft list ruleset 查看执行顺序。
  • input 链策略是 drop,一定要有 established,related 放行规则放在前面。

2 锁死自己(SSH 被断)

绝对不要在不安全的 SSH 会话中设置 input policy drop 而不先添加 SSH 放行规则!

急救方法

  1. 使用备用控制台(物理机或 IPMI)。
  2. 重启网络服务:sudo systemctl restart networking(可能清空规则,取决于配置)。
  3. 直接清空规则:sudo nft flush ruleset(会立即清空所有防火墙规则,谨慎使用,会暴露系统但恢复连接)。
  4. 使用 cron 或 at 定时任务:设置一个定时脚本在几分钟后恢复默认规则(如开机启动时)作为安全网。

3 日志记录

  • 使用 log 动作:
    sudo nft add rule inet filter input tcp dport 22 log prefix "SSH-ATTEMPT: " reject
  • 日志通常会发往系统日志(/var/log/syslogjournalctl)。

4 性能监控

  • 使用 nft monitor 实时查看被匹配的规则(调试用,生产慎用)。

  • 查看计数器(counter 动作):

    sudo nft add rule inet filter input tcp dport 80 counter accept
    sudo nft list ruleset  # 会显示匹配到的包和字节数

nftables vs iptables

特性 nftables iptables
语法 规则为表达式(ip saddr 1.2.3.4 tcp dport 80 accept 命令式(iptables -A INPUT -s 1.2.3.4 -p tcp --dport 80 -j ACCEPT
内核架构 单一框架,规则集一次性原子替换 多个内核模块(ipt, ip6t, ebt, arpt)、不同表不同后端
集(Sets) 原生、一流支持,高性能 需要 ipset 工具,两层管理
规则数量 单个表支持 inet 混合处理 IPv4/IPv6,规则数量减半 IPv4 和 IPv6 需要两套规则集
动态更新 支持原子性更新(添加/删除规则不会中断流量) 重新加载规则集有短暂中断窗口(除非用 iptables-restore
兼容性 原生,推荐新系统使用 旧系统标准,通过 iptables-translate 可转换

对于 Linux 防火墙管理,强烈推荐使用 nftables,它在性能、可维护性、语法清晰度上都明显优于 iptables,一旦熟悉其基于表/链/集的词汇表和表达式语法,你会觉得比 iptables 更加直观和强大,从 iptables 迁移(通过 iptables-translate)也很容易。

标签: Linux防火墙

抱歉,评论功能暂时关闭!