#### Debian12 封禁中国大陆 IP 访问 40000‑50000 端口 说明:封禁大陆 IP 段,有两种主流方案:**iptables + ipset(性能好,推荐)**、直接 iptables 批量添加规则(IP 段多,规则膨胀,不推荐)。端口范围:TCP+UDP 40000‑50000。 #### 方案一:ipset + iptables(推荐,Debian12) 1. 安装依赖 ~~~ apt update apt install ipset curl -y ~~~ 2. 创建 ipset 集合存储中国大陆 IP 段, 创建集合,hash:net 存放网段 ~~~ ipset create cn_ip hash:net family inet hashsize 1024 maxelem 65536 ~~~ 3. 获取中国大陆 IP 网段并导入 ipset ~~~ # 清空旧集合 ipset flush cn_ip # 下载cn网段列表写入ipset curl -s https://ftp.apnic.net/stats/apnic/delegated-apnic-latest | awk -F'|' '$2=="CN"&&$3=="ipv4"{printf("add cn_ip %s/%d\n",$4,32-log($5)/log(2))}' | ipset restore ~~~ ⚠️网络不好时 curl 会失败,可以把文件下载到本地再导入。 4. iptables 规则:拒绝 cn_ip 集合访问本机 40000‑50000 TCP/UDP ~~~ # TCP iptables -A INPUT -m set --match-set cn_ip src -p tcp --dport 40000:50000 -j DROP # UDP iptables -A INPUT -m set --match-set cn_ip src -p udp --dport 40000:50000 -j DROP ~~~ 5. 持久化 iptables & ipset(Debian12 保存重启不丢失) 安装`iptables‑persistent` ~~~ apt install iptables-persistent -y ~~~ > 安装弹窗时选择保存当前 ipv4 规则。 ipset 默认不会被 persistent 保存,需要写**定时脚本开机重载 CN IP 列表**。 新建脚本 `/etc/network/if‑pre‑up.d/load‑cn‑ipset` ~~~ #!/bin/sh ipset create cn_ip hash:net family inet hashsize 1024 maxelem 65536 2>/dev/null ipset flush cn_ip curl -s https://ftp.apnic.net/stats/apnic/delegated-apnic-latest | awk -F'|' '$2=="CN"&&$3=="ipv4"{printf("add cn_ip %s/%d\n",$4,32-log($5)/log(2))}' | ipset restore ~~~ 赋予执行权限 ~~~ chmod +x /etc/network/if-pre-up.d/load-cn-ipset ~~~ 注意:服务器断网开机时 curl 下载网段会失败,可把网段文件本地缓存,避免依赖网络。 查看当前规则 ~~~ iptables -L INPUT -n --line-numbers ipset list cn_ip ~~~ #### 方案二:nftables(Debian12 默认防火墙,替代 iptables) Debian12 默认使用 nftables,如果你在用 nftables,示例配置 `/etc/nftables.conf` ~~~ table ip filter { set cn_ip { type ipv4_addr; flags interval; auto-merge; } chain input { type filter hook input priority 0; policy accept; ip saddr @cn_ip tcp dport 40000-50000 drop ip saddr @cn_ip udp dport 40000-50000 drop } } ~~~ 同样需要脚本定期把 APNIC 的 CN 网段填充到`cn_ip`集合。 #### ⚠️重要风险提醒 1. **如果你自己是国内 IP 远程管理这台机器**:千万不要执行完直接断开 SSH!你的 SSH 端口如果落在 40000‑50000 之外不受影响;如果 SSH 端口在 40000‑50000,执行完直接失联。 2. APNIC 网段会变动,需要定期更新 ipset 集合,否则部分新分配大陆 IP 无法拦截。 3. 只拦截**入站**(别人访问本机 40000‑50000);本机向外访问大陆 IP 不受影响。 4. 云服务器:部分云厂商还有**安全组**,iptables/nftables 生效前提是云安全组没有提前放行。 #### ⚠️测试规则是否生效 从国内机器:`telnet 服务器IP 40000`,应当连接超时。 清理回滚(紧急撤销) iptables 版本: ~~~ # 查看行号删除对应规则 iptables -L INPUT -n --line-numbers iptables -D INPUT 【行号】 ipset destroy cn_ip ~~~ 注意:你现在混用了两套方案:**ipset(iptables)** 和 **nftables**,二者不要混用。截图里你删掉了 `/etc/nftables.conf`,用 nano 编辑它。 Debian12 默认防火墙是 nftables,下面完整操作流程: ### 1、先写完 /etc/nftables.conf ### 检查配置语法(非常关键,防止启动失败锁机) ~~~ nft -f /etc/nftables.conf --check ~~~ 2、启动 & 设置开机自启 nftables ~~~ # 启动nftables服务 systemctl start nftables # 设置开机自动加载配置文件 systemctl enable nftables ~~~ 查看运行状态 ~~~ systemctl status nftables ~~~ 显示 `active (exited)` 属于正常,nftables 是一次性加载配置的服务。 ### 查看当前生效规则 ``` nft list ruleset ``` 3、填充中国大陆 IP 网段到 nftables 的`cn_ip`集合 > nftables **不能直接用 ipset 命令**,ipset 是 iptables 的组件。需要脚本把 APNIC 网段导入 nftables set。 新建脚本 `/usr/local/bin/update-cn-set.sh` ``` cat > /usr/local/bin/update-cn-set.sh <<'EOF' #!/bin/bash TMP=$(mktemp) curl -s https://ftp.apnic.net/stats/apnic/delegated-apnic-latest > "$TMP" # 清空集合 nft flush set ip filter cn_ip # 生成 nftables 合法 add element 语法 awk -F'|' '$2=="CN"&&$3=="ipv4"{ len=32 - log($5)/log(2); printf "add element ip filter cn_ip { %s/%d }\n", $4, len }' "$TMP" | nft -f - rm -f "$TMP" EOF chmod +x /usr/local/bin/update-cn-set.sh ``` ``` cat > /usr/local/bin/update-cn-set.sh <<'EOF' #!/bin/bash TMP=$(mktemp) curl -s https://raw.githubusercontent.com/misakaio/chnroutes2/master/chnroutes.txt > "$TMP" nft flush set ip filter cn_ip while read -r net; do [[ -z "$net" || "$net" =~ ^# ]] && continue nft add element ip filter cn_ip { "$net" } done < "$TMP" rm -f "$TMP" EOF chmod +x /usr/local/bin/update-cn-set.sh ``` 赋予执行权限: ``` chmod +x /usr/local/bin/update-cn-set.sh ``` **手动执行一次,加载 CN 网段:** ``` /usr/local/bin/update-cn-set.sh ``` 验证集合是否有网段: ``` nft list set ip filter cn_ip ``` ### 设置开机自动加载网段 编辑 `/etc/network/if-pre-up.d/update-cn-set` ``` #!/bin/sh /usr/local/bin/update-cn-set.sh ``` ``` chmod +x /etc/network/if-pre-up.d/update-cn-set ``` > > 开机网络就绪后,自动拉取 CN 网段填充 nftables 集合。 ## ⚠️重要提醒 1. 你之前执行过`ipset create cn_ip`,**nftables 的 set 和 ipset 完全独立**,之前 ipset 命令创建的集合对 nftables 无效,可以删掉: ``` ipset destroy cn_ip ``` 2. 不要同时跑 iptables/ipset 和 nftables 两套防火墙。 3. **云服务器安全组!** 云服务商控制台安全组优先级高于主机 nftables,安全组如果放行 40000‑50000,主机防火墙拦截会失效。 4. 测试:国内机器访问 40000 端口,应当`connection refused / timeout`。 ## 如果你想回退,清空所有 nftables 规则 ``` nft flush ruleset systemctl stop nftables systemctl disable nftables ``` ## 排查点 - `nft -f /etc/nftables.conf --check` 一定要跑,配置写错直接开机会断连。 - 如果执行`update‑cn‑set.sh`无 IP 写入集合:服务器无法访问 apnic 网站,可以把 delegated‑apnic‑latest 文件下载到本地,修改脚本读取本地文件。 ### 补充:完整可用 `/etc/nftables.conf` 参考 ``` #!/usr/sbin/nft -f flush ruleset table ip filter { set cn_ip { type ipv4_addr flags interval auto-merge } chain input { type filter hook input priority 0; policy accept; ip saddr @cn_ip tcp dport 40000-50000 drop ip saddr @cn_ip udp dport 40000-50000 drop } } ``` 保存后再执行语法校验。