面對來自國外的惡意掃描、暴力破解、DDoS 攻擊,透過 iptables 實施「僅允許中國大陸 IP 存取,其餘預設拒絕」的白名單策略,能大幅降低攻擊面。本文提供完整實施流程:獲取國內 IP 段、生成規則腳本、持久化與效能優化。
白名單模式: 預設 DROP ALL,僅 ACCEPT 國內 IP 段。
優點:規則明確、誤攔截可控。
缺點:規則數量大 (約 5000-8000 條),需優化匹配效能。
https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest (權威、每日更新)cn.txt (CIDR 格式)https://github.com/17mon/china_ip_list 等get_cn_ip.sh#!/bin/bash
# 從 APNIC 解析中國 IPv4 CIDR
URL="https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest"
OUT="/etc/iptables/china_ip.cidr"
mkdir -p /etc/iptables
curl -s "$URL" | awk -F'|' '$2=="CN" && $3=="ipv4" {printf "%s/%d\n", $4, 32-log($5)/log(2)}' > "$OUT"
echo "Updated $(wc -l < "$OUT") CIDR entries at $(date)" | logger -t update-china-ip
加入 crontab 每週更新:0 3 * * 0 /usr/local/sbin/get_cn_ip.sh
直接插入 5000+ 條 -A INPUT -s CIDR -j ACCEPT 會導致匹配緩慢。採用 ipset 集合匹配,O(1) 複雜度。
# RHEL/CentOS
yum install ipset iptables-services
# Ubuntu/Debian
apt install ipset iptables-persistent
build_firewall.sh#!/bin/bash
IPSET_NAME="china_ip"
CIDR_FILE="/etc/iptables/china_ip.cidr"
IPTABLES="/sbin/iptables"
IPSET="/sbin/ipset"
# 1. 建立/重置 ipset
$IPSET destroy $IPSET_NAME 2>/dev/null
$IPSET create $IPSET_NAME hash:net family inet hashsize 16384 maxelem 65536
# 2. 批次載入 CIDR
while read -r cidr; do
$IPSET add $IPSET_NAME $cidr
done < "$CIDR_FILE"
# 3. 設定 iptables 規則鏈
$IPTABLES -F INPUT
$IPTABLES -P INPUT DROP
# 允許本地回環
$IPTABLES -A INPUT -i lo -j ACCEPT
# 允許已建立/相關連線
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允許國內 IP (核心規則)
$IPTABLES -A INPUT -m set --match-set $IPSET_NAME src -j ACCEPT
# 允許必要服務埠 (SSH、HTTP、HTTPS 等) - 視業務調整
$IPTABLES -A INPUT -p tcp -m multiport --dports 22,80,443 -m set --match-set $IPSET_NAME src -j ACCEPT
# 記錄被拒絕封包 (可選,注意日誌量)
# $IPTABLES -A INPUT -j LOG --log-prefix "IPT_DROP: " --log-level 4
echo "Firewall rules applied at $(date)" | logger -t firewall
# 儲存規則
service iptables save
# 或
iptables-save > /etc/sysconfig/iptables
# 儲存 ipset
ipset save > /etc/sysconfig/ipset
# 啟用服務
systemctl enable iptables ipset
# 安裝時會詢問是否儲存當前規則,選 Yes
# 手動儲存
netfilter-persistent save
# ipset 持久化需自行處理 (systemd service)
cat > /etc/systemd/system/ipset-restore.service <<'EOF'
[Unit]
Description=Restore ipset sets
Before=netfilter-persistent.service
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/sbin/ipset restore < /etc/ipset.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
ipset save > /etc/ipset.rules
systemctl enable ipset-restore
| 優化項 | 說明 |
|---|---|
| 使用 ipset hash:net | CIDR 級匹配,單規則覆蓋整個網段,規則數從萬級降至 1 條 |
| 調整 hashsize/maxelem | 預設 1024/65536,中國 IP 段約 5000 條,設 16384/65536 避免擴容開銷 |
| 規則順序優化 | 高頻匹配 (lo、ESTABLISHED) 前置,白名單匹配後置 |
| 關閉不必要的 LOG | 高流量下 LOG 會嚴重拖慢轉發,改用 ulogd 或流量鏡像分析 |
| 考慮 nftables 遷移 | 新版核心原生支援集合,語法更現代,效能更優 |
# 允許特定國外 IP (如 CDN 回源 IP、合作夥伴 IP)
ipset create partner_ip hash:ip
ipset add partner_ip 1.2.3.4
ipset add partner_ip 5.6.7.8
$IPTABLES -A INPUT -m set --match-set partner_ip src -j ACCEPT
# 允許特定埠全球存取 (如全球 API 端點)
$IPTABLES -A INPUT -p tcp --dport 8443 -j ACCEPT
# 查看規則
iptables -nvL INPUT --line-numbers
# 查看 ipset 內容
ipset list china_ip | head -20
# 即時監控封包匹配
watch -n1 'iptables -nvL INPUT | grep -E "pkts|bytes|china_ip"'
# 測試國外 IP 是否被拒 (需國外跳板機)
# curl -I https:// # 應超時或連線重置
-A INPUT -s <你的當前IP> -j ACCEPT。透過 ipset + iptables 白名單策略,配合自動化更新與持久化,可構建高效、可維運的地理位置存取控制防線。