Hugo博客公告弹窗

ufw + ipset 防火墙:仅允许大陆与 Cloudflare 访问 80/443

这是一套基于 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

完结

CC BY-NC-SA 4.0 转载请注明
最后更新于 2025-10-31 17:57
clarity统计