BY xzllll

Linux(For VPS) 防火墙配置 By Nftables 实践

实践 | Practices 2025年1月25日

1.First | 序

N年前使用 CentOS 时防火墙管理工具使用的是 Firewalld

换到 openSUSE 后使用 Nftables 实现

目前无论是 Homelab 还是 VPS 均使用 Nftables

Homelab 配置留着下篇记录

本篇主要记录 VPS

1.1.What is Nftables ? | 什么是Nftables ?

👩‍🏫
以下释义来自ChatGPT

nftables 是一种现代的 Linux 防火墙框架,用于管理和过滤网络流量。它是 iptables 的后继者,由 Netfilter 项目开发,旨在简化防火墙规则的管理并提高性能。

1.1.1.nftables 的特点

  1. 统一框架:

    • nftables 取代了 iptables、ip6tables、arptables 和 ebtables,提供了一个统一的框架来处理 IPv4、IPv6、ARP 和桥接流量。
  2. 简化的语法:

    • 相较于 iptables 的复杂规则,nftables 使用了一种更简单、更易读的 DSL(领域专用语言)。
  3. 性能更优:

    • nftables 使用了更高效的数据结构,例如基于哈希表的集合和字典,能够更快地匹配规则。
    • 减少了规则链的重复检查,提升了性能。
  4. 动态更新规则:

    • nftables 支持动态更新规则,而无需删除现有规则或重新加载整个规则集。
  5. 状态跟踪:

    • 继承了 iptables 的状态跟踪功能,可用于跟踪连接的状态(如 NEW、ESTABLISHED 等)。
  6. 支持复杂匹配:

    • 可以基于 IP 地址、端口、协议类型、数据包内容等设置复杂的过滤规则。

1.1.2.nftables 的基本概念

  • 表(table):规则集的容器,指定流量的处理范围(如 ip、ip6、bridge 等)。
  • 链(chain):规则链,定义了特定流量的处理逻辑(如 input、output、forward)。
  • 规则(rule):实际的流量匹配条件和动作。
  • 集合(set):高效存储和匹配一组元素(如 IP 地址或端口)。
  • 计数器(counter):用于统计匹配到的流量数量。

1.1.3.基本用法示例

以下是 nftables 的一个简单示例:

# 创建一个表
sudo nft add table ip filter

# 在表中创建链
sudo nft add chain ip filter input { type filter hook input priority 0; }

# 添加规则来允许 SSH 流量
sudo nft add rule ip filter input tcp dport 22 accept

# 阻止所有其他流量
sudo nft add rule ip filter input drop

1.1.4.查看和管理规则

  • 查看规则:
    sudo nft list ruleset
    
  • 删除规则:
    sudo nft delete rule ip filter input handle 3
    
    (其中 handle 3 是规则的标识符,可以通过 list ruleset 查到。)

1.1.5.为什么选择 nftables ?

  • 现代化:使用更高效的架构和语法。
  • 灵活性:支持复杂场景,例如 NAT、QoS 等。
  • 简化管理:统一管理所有类型的网络流量。

2.2.Version

2.2.1.OS

2.2.2.Nftables

2.Setting | 设置

目前使用 systemd 管理 nftables

若你的发行版运行基于 iptables 的防火墙管理工具请移除它

例如

  • firewalld (iptables)
  • UFW

2.1. Setting nftables.conf

先来看 nftables.conf


#!/usr/sbin/nft -f
flush ruleset

define NET_PODMAN = podman0

table ip V4Rules {
        set NET_PODMAN {
                type ipv4_addr
                flags interval
                elements = { 10.88.0.1/16 }
        }
        set web-s {
                type inet_service
                flags interval
                elements = { http, https }
        }
        set nfs-s {
                type inet_service
                flags interval
                elements = { nfs }
        }
        set ssh-c {
                type ipv4_addr
                flags interval
                elements = { 255.255.255.255/32 }
        }
        set web-c {
                type ipv4_addr
                flags interval
                elements = { 255.255.255.255/32 }
        }
        chain ALL-input {
                type filter hook input priority filter; policy drop;
                iifname lo counter accept
                iifname eth0 goto eth0-input
                iifname $NET_PODMAN goto Podman-input
        }
        chain eth0-input {
                iifname lo counter accept
                ip saddr @ssh-c icmp type echo-request counter accept
                icmp type echo-request limit rate 20 bytes/second burst 200 bytes counter accept
                icmp type echo-request counter drop
                ct state {established,related} accept
                ip saddr @ssh-c tcp dport 22 ct state new limit rate 15/minute  counter accept
                ip saddr @web-c tcp dport @web-s counter accept
                ip saddr @web-c udp dport @web-s counter accept
                ct state { invalid } counter drop
        }
        chain Podman-input {
                iifname lo counter accept
                iifname $NET_PODMAN counter accept
                ct state {established,related} counter accept
                ct state { invalid } counter drop
        }
}

2.2.Analysis nftables.conf | nftables.conf 解析

👩‍🏫
以下释义来自ChatGPT (已修正部分内容)

这份 nftables.conf 文件定义了一个完整的防火墙规则集,用于管理 IPv4 流量。以下是对配置的解析和解释:


2.2.1.基础设置

#!/usr/sbin/nft -f
flush ruleset
  • #!/usr/sbin/nft -f: 指定使用 nft 解释器加载规则。
  • flush ruleset: 清空当前的规则集,确保规则不会被累积。

2.2.2 定义变量

define NET_PODMAN = podman0
  • NET_PODMAN: 定义一个网络接口变量,表示 podman0 接口(可能用于容器网络)。

2.2.3.定义V4Rules表

整个规则集被定义在名为 V4Rules 的表内。


IP地址和端口集合

  • NET_PODMAN:

    set NET_PODMAN {
        type ipv4_addr
        flags interval
        elements = { 10.88.0.1/16 }
    }
    
    • 定义了一个IPv4地址集合,包含子网 10.88.0.1/16,通常为 Podman 的容器网络。
  • web-s:

    set web-s {
        type inet_service
        flags interval
        elements = { http, https }
    }
    
    • 定义了一个服务端口集合,包含 http (80) 和 https (443)。
  • nfs-s:

    set nfs-s {
        type inet_service
        flags interval
        elements = { nfs }
    }
    
    • 定义了一个服务端口集合,包含 nfs 服务。
  • ssh-c:

    set ssh-c {
        type ipv4_addr
        flags interval
        elements = { 255.255.255.255/32 }
    }
    
    • 定义了允许通过 SSH 的来源地址集合。
  • web-c:

    set web-c {
        type ipv4_addr
        flags interval
        elements = { 255.255.255.255/32 }
    }
    
    • 定义了允许通过 Web 服务(HTTP/HTTPS)的来源地址集合。

2.2.4 规则链定义

  1. ALL-input 链

    chain ALL-input {
        type filter hook input priority filter; policy drop;
        iifname lo counter accept
        iifname eth0 goto eth0-input
        iifname $NET_PODMAN goto Podman-input
    }
    
    • 功能:
      • 是 input 钩子链,处理所有进入流量。
      • 默认策略: policy drop,丢弃所有未明确允许的流量。
    • 规则:
      1. 接受来自 lo(本地回环)的流量。
      2. 将来自 eth0 的流量转到 eth0-input 链。
      3. 将来自 podman0 的流量转到 Podman-input 链。
  2. eth0-input

    chain eth0-input {
        iifname lo counter accept
        ip saddr @ssh-c icmp type echo-request counter accept
        icmp type echo-request limit rate 20 bytes/second burst 200 bytes counter accept
        icmp type echo-request counter drop
        ct state {established,related} accept
        ip saddr @ssh-c tcp dport 22 ct state new limit rate 15/minute counter accept
        ip saddr @web-c tcp dport @web-s counter accept
        ip saddr @web-c udp dport @web-s counter accept
        ct state { invalid } counter drop
    }
    
    • 功能:
      • 定义了针对 eth0 接口的流量规则。
    • 规则:
      1. 接受来自 lo 的流量。
      2. 接受来自 @ssh-c 的 ICMP 请求。
      3. 对其他 ICMP 流量进行速率限制,20 字节/秒,突发 200 字节。
      4. 接受已建立或相关的连接。
      5. 接受来自 @ssh-c 的 SSH 新连接并限制速率为每分钟 15 次
      6. 接受来自 @web-c 的 TCP/UDP 流量,并目标端口为 @web-s。
      7. 丢弃无效连接。
  3. Podman-input 链

    chain Podman-input {
        iifname lo counter accept
        iifname $NET_PODMAN counter accept
        ct state {established,related} counter accept
        ct state { invalid } counter drop
    }
    
    • 功能:
      • 定义了针对 podman0 接口的流量规则。
    • 规则:
      1. 接受来自 lo 的流量。
      2. 接受来自 podman0 的流量。
      3. 接受已建立或相关的连接。
      4. 丢弃无效连接。

2.2.5.总结

  • 安全性: 默认丢弃所有流量,仅明确允许的流量会被接受。
  • 功能性:
    • 为 SSH、新连接速率、ICMP 以及容器网络流量提供限制和保护。
    • 定义了对 HTTP/HTTPS 和 NFS 流量的来源限制。
  • 模块化: 使用集合 (set) 和链 (chain) 提高规则的可读性和复用性。

2.3.Setting nft.service | 设置 nft.service

编辑好 nftables.conf 后

其次我们需要定义一个 nft.service 以便使用 systemd 进行管理

🔽
nft.service 示例如下
# /usr/lib/systemd/system/nft.service
[Unit]
Description=nftables
Documentation=man:nft(8) http://wiki.nftables.org
Wants=network-pre.target
Before=network-pre.target shutdown.target
Conflicts=shutdown.target
DefaultDependencies=no

[Service]
Type=oneshot
RemainAfterExit=yes
StandardInput=null
ProtectSystem=full
ProtectHome=true
ExecStart=/usr/sbin/nft -f /etc/nftables.conf
ExecReload=/usr/sbin/nft -f /etc/nftables.conf
ExecStop=/usr/sbin/nft flush ruleset

[Install]
WantedBy=sysinit.target
⤵️
随后依次运行如下命令重载&启动nft服务

# 重载 systemd

systemctl daemon-reload

## 启动 nft.service

systemctl start nft

Thanks & Copy

Nftables

nftables wiki

nftables wiki

标签

xzllll

三分钟热度三分钟收获