Debian 11 上的 nftables防火墙 简单配置(配置文件)

本文主要记录直接修改nftables引用的源配置文件,来配置相关的防火墙规则。如需命令行,可以参考另一篇文章:使用命令行快速创建nftables通用规则(有空再补吧……)。

简述

对于dd debian11后的小鸡,防火墙可以使用自带的nftables,“优雅”的管理防火墙规则。

简单使用nftables来管理:

  • 允许本地环回
  • 禁Ping:ipv4 & ipv6
  • 仅放行22,80,443等常用端口
  • 搭配IP集合限制来源 如仅允许Cloudflare访问,仅允许自己访问
  • ……

所有的表名、链名其实都可以定义成自己喜欢的,只要它们不是关键字就好。

1.检测状态

网络重装后的Debian11系统直接使用命令:systemctl status nftables

2.设置自启动

Debian11默认是不开机自启动nftables的,因此若需要使机器重启后,能够自动加载防火墙规则配置,则使用命令:

systemctl enable nftables

3.列出规则

Debian11的nftables默认防火墙规则是空的,可以使用命令列出查看:

nft list ruleset

或者去查看规则引用的源文件:cat /etc/nftables.conf 可以看到它仅输出默认的表、链和规则。

nftables default rules

4.备份文件

再修改之前,先习惯性的备份当前的防火墙规则源

cp /etc/nftables.conf /etc/nftables.conf.bak

5.规则参考

直接修改配置文件就ok,再也不用记iptables那些个繁杂的规则……

#可以命令行编辑 也可以找个ssh工具编辑源文件 怎么开心怎么来了
nano /etc/nftables.conf
下面列举一些可能会用到的规则

5.1 常用规则集

简单的通用规则集

使用前可以选择性的将“每行后面”的中文注释移除掉,不然可能粘贴到ssh窗口后,里面的中文部分可能会出现乱码,虽然用起来没有影响……

#!/usr/sbin/nft -f

flush ruleset

table inet filter { 
    chain input {
        type filter hook input priority 0;
        tcp dport { 22,80,443 } accept #放行22 80 443端口
        iifname lo accept #允许本地环回

        icmp type echo-request counter drop #禁ping ipv4
        icmpv6 type echo-request drop #禁ping ipv6
        icmpv6 type { nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert } accept # 放行ipv6邻居发现等 (对于不开启nftables能正常ping通外部网络 而当开启了nftables则无法使用ipv6时 这很重要!)

        ct state related,established accept # 放行已建立的或相关的连接
        counter reject # 拒绝上述规则以外的入站请求
    }

    chain forward {
        type filter hook forward priority 0;
    }

    chain output {
        type filter hook output priority 0;
    }
}

5.2 限定CF源

对于仅接受来自Cloudflare的IP地址段

使用前可以选择性的将“每行后面”的中文注释移除掉,不然可能粘贴到ssh窗口后,里面的中文部分可能会出现乱码,虽然用起来没有影响……


#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    set cfip4 {
        type ipv4_addr
        flags interval
        elements = { cloudflare ipv4地址段 搭配定时任务自动更新 } #cf_ipv4
    }
    set cfip6 {
        type ipv6_addr
        flags interval
        elements = { cloudflare ipv6地址段 搭配定时任务自动更新 } #cf_ipv6
    }
     
    chain input {
        type filter hook input priority 0;
        ip saddr @cfip4 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv4网段
        ip6 saddr @cfip6 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv6网段
        tcp dport { 22,8006 } accept #放行22 8006
        iifname lo accept #允许本地环回

        icmp type echo-request counter drop #禁ipv4 ping
        icmpv6 type echo-request drop #禁ipv6 ping
        icmpv6 type { nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert } accept # 放行ipv6邻居发现等 (对于不开启nftables能正常ping通外部网络 而当开启了nftables则无法使用ipv6时 这很重要)

        ct state related,established accept # 放行已建立的或相关的连接
        counter reject # 拒绝上述规则以外的入站请求
    }

    chain forward {
        type filter hook forward priority 0;
    }

    chain output {
        type filter hook output priority 0;
    }
}

5.3 限定CF源+自己的ip段

对于仅接受自己的IP地址段和Cloudflare的IP地址段

使用前可以选择性的将“每行后面”的中文注释移除掉,不然可能粘贴到ssh窗口后,里面的中文部分可能会出现乱码,虽然用起来没有影响……




#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    set myip {
        type ipv4_addr
        flags interval
        elements = { 自己的ip白名单 }
    }
    set cfip4 {
        type ipv4_addr
        flags interval
        elements = { cloudflare ipv4地址段 搭配定时任务自动更新 } #cf_ipv4
    }
    set cfip6 {
        type ipv6_addr
        flags interval
        elements = { cloudflare ipv6地址段 搭配定时任务自动更新 } #cf_ipv6
    }
     
    chain input {
        type filter hook input priority 0;
        ip saddr @cfip4 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv4网段
        ip6 saddr @cfip6 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv6网段
        ip saddr @myip tcp dport { 22,8006 } accept #放行22 8006 限定自己的ip网段
        iifname lo accept #允许本地环回

        icmp type echo-request counter drop #禁ipv4 ping
        icmpv6 type echo-request drop #禁ipv6 ping
        icmpv6 type { nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert } accept # 放行ipv6邻居发现等 (对于不开启nftables能正常ping通外部网络 而当开启了nftables则无法使用ipv6时 这很重要)

        ct state related,established accept # 放行已建立的或相关的连接
        counter reject # 拒绝上述规则以外的入站请求
    }

    chain forward {
        type filter hook forward priority 0;
    }

    chain output {
        type filter hook output priority 0;
    }
}

5.4 限定源+PVE环境

对于还安装了PVE的宿主机 可以使用nat表的prerouting链和postrouting链等来处理流量和请求

使用前可以选择性的将“每行后面”的中文注释移除掉,不然可能粘贴到ssh窗口后,里面的中文部分可能会出现乱码,虽然用起来没有影响……




#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    set myip {
        type ipv4_addr
        flags interval
        elements = { 自己的ip白名单 }
    }
    set cfip4 {
        type ipv4_addr
        flags interval
        elements = { cloudflare ipv4地址段 搭配定时任务自动更新 } #cf_ipv4
    }
    set cfip6 {
        type ipv6_addr
        flags interval
        elements = { cloudflare ipv6地址段 搭配定时任务自动更新 } #cf_ipv6
    }
     
    chain input {
        type filter hook input priority 0;
        ip saddr @cfip4 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv4网段
        ip6 saddr @cfip6 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv6网段
        ip saddr @myip tcp dport { 22,8006 } accept #放行22 8006 限定自己的ip网段
        iifname lo accept #允许本地环回

        icmp type echo-request counter drop #禁ipv4 ping
        icmpv6 type echo-request drop #禁ipv6 ping
        icmpv6 type { nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert } accept # 放行ipv6邻居发现等 (对于不开启nftables能正常ping通外部网络 而当开启了nftables则无法使用ipv6时 这很重要)

        ct state related,established accept # 放行已建立的或相关的连接
        counter reject # 拒绝上述规则以外的入站请求
    }

    chain forward {
        type filter hook forward priority 0;
    }

    chain output {
        type filter hook output priority 0;
    }
}
table ip nat {
    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        #tcp dport 2222 dnat to 192.168.1.100 #将宿主机2222入站请求转发到内网ip为192.168.1.100的2222端口上
        #tcp dport 3389 dnat to 192.168.1.101 #将宿主机3389入站请求转发到内网ip为192.168.1.101的3389端口上
        #tcp dport { 2223,7800 } dnat to 192.168.1.103 #将宿主机2223入站流量转发到内网ip为192.168.1.103的2223端口上
        #……
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        ip saddr 192.168.1.0/24 masquerade #设置源NAT
    }
}

对于还安装了PVE的宿主机 可以使用nat表来处理流量和请求 并限定其来源

使用前可以选择性的将“每行后面”的中文注释移除掉,不然可能粘贴到ssh窗口后,里面的中文部分可能会出现乱码,虽然用起来没有影响……




#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    set myip {
        type ipv4_addr
        flags interval
        elements = { 自己的ip白名单 }
    }
    set cfip4 {
        type ipv4_addr
        flags interval
        elements = { cloudflare ipv4地址段 搭配定时任务自动更新 } #cf_ipv4
    }
    set cfip6 {
        type ipv6_addr
        flags interval
        elements = { cloudflare ipv6地址段 搭配定时任务自动更新 } #cf_ipv6
    }
     
    chain input {
        type filter hook input priority 0;
        ip saddr @cfip4 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv4网段
        ip6 saddr @cfip6 tcp dport { 80,443 } accept #放行80 443端口 限定cf ipv6网段
        ip saddr @myip tcp dport { 22,8006 } accept #放行22 8006 限定自己的ip网段
        iifname lo accept #允许本地环回

        # icmp
        icmp type echo-request counter drop #禁ipv4 ping
        
        icmpv6 type echo-request drop #禁ipv6 ping
        icmpv6 type { nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert } accept # 放行ipv6邻居发现等 (对于不开启nftables能正常ping通外部网络 而当开启了nftables则无法使用ipv6时 这很重要)
        
        ct state related,established accept # 放行已建立的或相关的连接
        counter reject # 拒绝上述规则以外的入站请求
    }

    chain forward {
        type filter hook forward priority 0;
    }

    chain output {
        type filter hook output priority 0;
    }
}
table ip nat {
    set myip {
        type ipv4_addr
        flags interval
        elements = { 自己的ip网段白名单 }
    }

    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        ip saddr @myip tcp dport 2222 dnat to 192.168.1.100 #将宿主机2222入站请求转发到内网ip为192.168.1.100的2222端口上 仅允许限定的来源访问
        ip saddr @myip tcp dport 3389 dnat to 192.168.1.101 #将宿主机3389入站请求转发到内网ip为192.168.1.101的3389端口上 仅允许限定的来源访问
        ip saddr @myip tcp dport { 2223,7800 } dnat to 192.168.1.103 #将宿主机2223入站流量转发到内网ip为192.168.1.103的2223端口上 仅允许限定的来源访问
        #……
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        ip saddr 192.168.1.0/24 masquerade #设置源NAT
    }
}

6.使用配置

上面的/etc/nftables.conf 规则配置保存好了以后,接下来就是如何使之生效的问题。博主这里用的是直接使用命令重启防火墙。当然也可以使用命令导入规则:nft -f /etc/nftables.conf ,反正怎么开心怎么来了呗。

#重启nftables防火墙
systemctl restart nftables

碎碎念

不得不说比起iptables,nftables强大了很多,修改、添加、删除、查看规则都很方便,特别是“集合”这一功能,使得整体的规则变的巨“优雅”,也很方便理解。

最后,nftables强大的功能远不止于此,本文仅仅是简单记录一些自己经常用到的规则集,如果后面有其它的需求再慢慢来完善和记录吧……

阅读剩余
THE END