确保 nftables 已安装: Debian 12 默认使用 nftables 作为防火墙框架。检查是否安装:
sudo apt update
sudo apt install nftables
启用并启动 nftables 服务
sudo systemctl enable nftables
sudo systemctl start nftables
下载maxmind数据库
将文件解压后放在任意目录
# 安装iprange
sudo apt install iprange
# 备份 nftables.conf
sudo cp /etc/nftables.conf /etc/nftables.conf.bak
# 清空所有规则
sudo nft flush ruleset
# 停止服务
sudo systemctl stop nftables
删除原配置文件
sudo rm -rf /etc/nftables.conf
修改配置文件
sudo vim /etc/nftables.conf
修改后配置文件如下
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# 定义中国大陆 IPv4 地址集合
set cn_ips {
type ipv4_addr
flags interval
#CN_IPV4_ELEMENTS#
}
# 定义局域网 IPv4 地址集合
set lan_ips {
type ipv4_addr
flags interval
elements = { 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12 } # 替换为你的局域网范围
}
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口
iifname "lo" accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许局域网 IPv4 访问
ip saddr @lan_ips accept
# 允许局域网 IP 访问 ICMP Echo 请求 (ping)
ip saddr @lan_ips icmp type echo-request accept
# 允许中国大陆 IPv4 地址访问指定 TCP 端口
ip saddr @cn_ips tcp dport { 80, 3306, 8443, 25, 465, 587, 110, 995, 143, 993 } accept
# 允许中国大陆 IP 访问 ICMP Echo 请求 (ping)
ip saddr @cn_ips icmp type echo-request accept
# 记录被拒绝的连接(可选)
log prefix "[nftables] Blocked: " flags all counter drop
# 拒绝所有其他连接
counter drop
}
chain output {
type filter hook output priority 0; policy accept;
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
创建替换ip的脚本
sudo vim update_nftables.sh
脚本内容
#!/bin/bash
# 提取中国大陆 IPv4 地址
grep '1814991' GeoLite2-Country-Blocks-IPv4.csv | awk -F',' '{print $1}' > cn_ipv4.txt
# 优化 IPv4 地址范围
iprange cn_ipv4.txt > cn_ipv4_optimized.txt
# 转换为 nftables 集合格式(IPv4)
echo "elements = {" > cn_ipv4_nft.txt
awk '{print $1","}' cn_ipv4_optimized.txt >> cn_ipv4_nft.txt
echo "}" >> cn_ipv4_nft.txt
# 使用 sed 替换 IPv4 占位符
sudo sed -i '/#CN_IPV4_ELEMENTS#/r cn_ipv4_nft.txt' /etc/nftables.conf
sudo sed -i 's/#CN_IPV4_ELEMENTS#//' /etc/nftables.conf
# 应用规则
sudo nft -f /etc/nftables.conf
# 清理临时文件
sudo rm cn_ipv4.txt cn_ipv4_optimized.txt cn_ipv4_nft.txt
# 确保 nftables 服务启用
sudo systemctl enable nftables
sudo systemctl restart nftables
给权限
sudo chmod +x update_nftables.sh
执行脚本
sudo ./update_nftables.sh
检查规则
sudo nft list ruleset
查看被拒绝的信息
查看系统日志文件
sudo grep "\[nftables\] Blocked:" /var/log/syslog
示例输出:
Jun 8 22:30:45 hostname kernel: [nftables] Blocked: IN=eth0 OUT= MAC=... SRC=203.0.113.1 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 PROTO=TCP SPT=54321 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
解释:
- SRC=203.0.113.1:源 IP(被拒绝的外部 IP)。
- DST=192.168.1.100:目标 IP(你的服务器)。
- PROTO=TCP:协议类型。
- SPT=54321 DPT=22:源端口和目标端口(例如,尝试访问 SSH 的 22 端口)。
- IN=eth0:入站接口。
实时监控日志: 使用 tail 实时查看新记录的被拒绝连接:
sudo tail -f /var/log/syslog | grep "\[nftables\] Blocked:"
过滤特定信息: 如果日志量大,可以提取特定字段(如源 IP)
sudo grep "\[nftables\] Blocked:" /var/log/syslog | awk '{print $8}' | sort | uniq
这会提取被拒绝的源 IP(SRC=…)并去重。
查看 nftables 计数器
sudo nft list ruleset
示例输出:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iifname "lo" accept
ct state established,related accept
ip saddr @lan_ips accept
ip6 saddr @lan_ips6 accept
ip saddr @cn_ips accept
ip6 saddr @cn_ips6 accept
log prefix "[nftables] Blocked: " flags all counter packets 123 bytes 4560 drop
counter packets 123 bytes 4560 drop
}
...
}
- counter packets 123 bytes 4560 drop:表示有 123 个数据包(共 4560 字节)被拒绝。
- packets:被拒绝的数据包数量。
- bytes:被拒绝的数据总字节数。
修改/etc/nftables.conf配置文件后只需要执行下面命令就可刷新规则
sudo nft flush ruleset
sudo nft -f /etc/nftables.conf
sudo systemctl restart nftables
#查看当前规则
sudo nft list ruleset