这是一套基于 UFW + IPSet 的防火墙方案,用于仅允许 中国大陆与 Cloudflare 访问网站的 80/443 端口。 脚本自动管理规则,兼容双栈网络,并支持每日更新 IP 段。
主要特色:
🧩 原生兼容 UFW:不修改现有规则,只在用户链中追加放行逻辑。
🌏 精准放行:限制访问来源为中国大陆与 Cloudflare。
🔄 自动更新:通过 systemd 定时任务每日刷新 IP 数据。
⚡ 双栈支持:IPv4 与 IPv6 独立控制。
🚀 一键部署脚本
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/ufw_cn.sh \
&& chmod +x ufw_cn.sh \
&& ./ufw_cn.sh
✅ 说明: 脚本会自动检测现有 UFW 状态与规则,并在不影响原有策略的前提下,附加 CN 与 Cloudflare 放行规则。
🔍 查看当前规则
iptables -L ufw-user-input -n --line-numbers
ip6tables -L ufw6-user-input -n --line-numbers
🧹 删除规则(恢复原状)
该操作将清除 IPSet 与相关放行策略,使防火墙恢复默认状态:
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/cleanup_ipset.sh \
&& chmod +x cleanup_ipset.sh \
&& ./cleanup_ipset.sh
随后重新调整放行顺序以避免冲突:
# IPv4
sudo iptables -D ufw-user-input -p tcp --dport 80 -j ACCEPT
sudo iptables -D ufw-user-input -p tcp --dport 443 -j ACCEPT
sudo iptables -A ufw-user-input -p tcp --dport 80 -j ACCEPT
sudo iptables -A ufw-user-input -p tcp --dport 443 -j ACCEPT
# IPv6
sudo ip6tables -D ufw6-user-input -p tcp --dport 80 -j ACCEPT
sudo ip6tables -D ufw6-user-input -p tcp --dport 443 -j ACCEPT
sudo ip6tables -A ufw6-user-input -p tcp --dport 80 -j ACCEPT
sudo ip6tables -A ufw6-user-input -p tcp --dport 443 -j ACCEPT
验证规则是否正确加载:
iptables -L ufw-user-input -n --line-numbers
ip6tables -L ufw6-user-input -n --line-numbers
⚙️ 其他命令
手动允许某个 IP:
sudo ipset add china 6.6.6.6
从集合中移除指定 IP:
sudo ipset del china 6.6.6.6
保存规则
ipset save > /etc/iptables/ipset.rules
放行bingbot(必应爬虫)
sudo ipset add china 157.55.39.0/24
sudo ipset add china 207.46.13.0/24
sudo ipset add china 40.77.167.0/24
sudo ipset add china 13.66.139.0/24
sudo ipset add china 13.66.144.0/24
sudo ipset add china 52.167.144.0/24
sudo ipset add china 13.67.10.16/28
sudo ipset add china 13.69.66.240/28
sudo ipset add china 13.71.172.224/28
sudo ipset add china 139.217.52.0/28
sudo ipset add china 191.233.204.224/28
sudo ipset add china 20.36.108.32/28
sudo ipset add china 20.43.120.16/28
sudo ipset add china 40.79.131.208/28
sudo ipset add china 40.79.186.176/28
sudo ipset add china 52.231.148.0/28
sudo ipset add china 20.79.107.240/28
sudo ipset add china 51.105.67.0/28
sudo ipset add china 20.125.163.80/28
sudo ipset add china 40.77.188.0/22
sudo ipset add china 65.55.210.0/24
sudo ipset add china 199.30.24.0/23
sudo ipset add china 40.77.202.0/24
sudo ipset add china 40.77.139.0/25
sudo ipset add china 20.74.197.0/28
sudo ipset add china 20.15.133.160/27
sudo ipset add china 40.77.177.0/24
sudo ipset add china 40.77.178.0/23
nftable版本
一键管理脚本
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/nft-m.sh \
&& chmod +x nft-m.sh \
&& ./nft-m.sh
或者使用以下脚本和命令
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/nft_cn.sh \
&& chmod +x nft_cn.sh \
&& ./nft_cn.sh
查看完整规则集
nft list ruleset
查看 IPv4 集合
nft list set inet filter china_ipv4
查看 IPv6 集合
nft list set inet filter china_ipv6
手动允许某个 IP:
sudo nft add element inet filter china_ipv4 { 6.6.6.6 }
从集合中移除指定 IP:
sudo nft delete element inet filter china_ipv4 { 6.6.6.6 }
放行 Bingbot(必应爬虫):
cat > /tmp/bingbot.txt << 'EOF'
157.55.39.0/24
207.46.13.0/24
40.77.167.0/24
13.66.139.0/24
13.66.144.0/24
52.167.144.0/24
13.67.10.16/28
13.69.66.240/28
13.71.172.224/28
191.233.204.224/28
20.36.108.32/28
20.43.120.16/28
40.79.131.208/28
40.79.186.176/28
52.231.148.0/28
20.79.107.240/28
51.105.67.0/28
20.125.163.80/28
40.77.188.0/22
65.55.210.0/24
199.30.24.0/23
40.77.202.0/24
40.77.139.0/25
20.74.197.0/28
20.15.133.160/27
40.77.177.0/24
40.77.178.0/23
EOF
{
echo "add element inet filter china_ipv4 {"
cat /tmp/bingbot.txt | sed 's/$/,/' | sed '$ s/,$//'
echo "}"
} | nft -f - 2>&1 | grep -v "interval overlaps" || echo "Bingbot IP 段添加完成(跳过了已存在的)"
# 保存规则
nft list ruleset > /etc/nftables/nftables.rules
删除规则
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/cleanup_nftables.sh \
&& chmod +x cleanup_nftables.sh \
&& ./cleanup_nftables.sh
其他命令
完全切换到 nftables
# 完整清理并重新配置
cat > /tmp/clean_firewall.sh << 'EOF'
#!/bin/bash
# 停止所有防火墙服务
systemctl stop iptables ip6tables firewalld ufw 2>/dev/null
systemctl disable iptables ip6tables firewalld ufw 2>/dev/null
# 清空所有 nftables 规则
nft flush ruleset
# 删除可能冲突的表
nft delete table ip filter 2>/dev/null
nft delete table ip6 filter 2>/dev/null
nft delete table ip nat 2>/dev/null
nft delete table ip6 nat 2>/dev/null
# 确保 nftables 服务启用
systemctl enable nftables
systemctl restart nftables
echo "✅ 防火墙已清理,可以重新运行 nft_cn.sh"
EOF
chmod +x /tmp/clean_firewall.sh
/tmp/clean_firewall.sh
# 然后重新运行你的脚本
./nft_cn.sh
清空系统中所有防火墙配置(iptables、UFW、firewalld、nftables)」并「重置为一个干净的 nftables 环境
查看所有表(输出:table inet filter,只有一个表)
nft list tables
查某个 IP 是否在这些集合中
sudo nft get element inet filter china_ipv4 { 190.93.240.0/20 }
判断某个 IPv6 段
sudo nft get element inet filter china_ipv6 { 2400:cb00::/32 }
中国 IPv4 段数量
nft list set inet filter china_ipv4 | grep -oP '\d+\.\d+\.\d+\.\d+/\d+' | wc -l
IPv6 Cloudflare 段数量
nft list set inet filter china_ipv6 | grep -oP '([0-9a-f:]+/\d+)' | wc -l
查看规则链
nft list chain inet filter input
查看自动更新任务
crontab -l | grep china
查看开机自启服务
systemctl list-unit-files | grep nftables
查看防火墙状态
systemctl status nftables
手动更新 IP 段
/usr/local/bin/update_china_nftables.sh
黑名单
基于nftbales防火墙
创建一个管理脚本:
cat > /usr/local/bin/manage_blacklist.sh << 'EOF'
#!/bin/bash
BLACKLIST_FILE="/etc/nftables.d/blacklist.conf"
mkdir -p /etc/nftables.d
case "$1" in
add)
if [ -z "$2" ]; then
echo "用法: $0 add <IP或IP段>"
exit 1
fi
# 添加到黑名单集合
nft add element inet filter blacklist { $2 } 2>/dev/null || {
# 如果集合不存在,先创建
nft add set inet filter blacklist { type ipv4_addr \; flags interval \; }
nft insert rule inet filter input ip saddr @blacklist drop
nft add element inet filter blacklist { $2 }
}
# 保存到文件
echo "$2" >> "$BLACKLIST_FILE"
echo "✅ 已拉黑: $2"
;;
remove)
if [ -z "$2" ]; then
echo "用法: $0 remove <IP或IP段>"
exit 1
fi
# 从集合中删除
nft delete element inet filter blacklist { $2 }
# 从文件中删除
sed -i "/^$2$/d" "$BLACKLIST_FILE"
echo "✅ 已解除拉黑: $2"
;;
list)
echo "=== 当前黑名单 ==="
nft list set inet filter blacklist 2>/dev/null || echo "黑名单为空"
;;
restore)
# 从文件恢复黑名单(用于开机自动加载)
if [ -f "$BLACKLIST_FILE" ]; then
nft add set inet filter blacklist { type ipv4_addr \; flags interval \; } 2>/dev/null
nft insert rule inet filter input ip saddr @blacklist drop 2>/dev/null
while read -r ip; do
[ -z "$ip" ] && continue
nft add element inet filter blacklist { $ip } 2>/dev/null
done < "$BLACKLIST_FILE"
echo "✅ 黑名单已恢复"
fi
;;
*)
echo "用法: $0 {add|remove|list|restore} [IP]"
echo ""
echo "示例:"
echo " $0 add 1.2.3.4 # 拉黑单个IP"
echo " $0 add 1.2.3.0/24 # 拉黑IP段"
echo " $0 remove 1.2.3.4 # 解除拉黑"
echo " $0 list # 查看黑名单"
exit 1
;;
esac
EOF
chmod +x /usr/local/bin/manage_blacklist.sh
使用方法
# 拉黑单个 IP
manage_blacklist.sh add 1.2.3.4
# 拉黑 IP 段
manage_blacklist.sh add 1.2.3.0/24
# 拉黑多个(逐个添加)
manage_blacklist.sh add 5.6.7.8
manage_blacklist.sh add 9.10.11.12
# 查看黑名单
manage_blacklist.sh list
# 解除拉黑
manage_blacklist.sh remove 1.2.3.4
创建一个开机启动服务:
cat > /etc/systemd/system/nftables-blacklist.service << 'EOF'
[Unit]
Description=Restore NFTables Blacklist
After=nftables.service
Requires=nftables.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/manage_blacklist.sh restore
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable nftables-blacklist.service
完结