萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux 高效封鎖海量惡意 IP:ipset + iptables/nftables 實戰部署指南

痛點:iptables 線性匹配的效能崩潰

當封鎖名單增長到成百上千條 iptables -A INPUT -s x.x.x.x -j DROP 規則時,核心需**線性遍歷**每條規則 (O(N)),導致封包處理延遲飆升、CPU 佔用率激增,甚至引發軟中斷風暴。ipset 利用哈希表/位圖實現 O(1) 常數時間查找,完美解決此問題。

ipset 核心概念與集合類型

類型適用場景支援功能
hash:ip單個 IP 地址 (IPv4/IPv6)極快查找、動態增刪、計數器、超時自動過期
hash:netCIDR 網段 (如 192.168.1.0/24)同上,自動合併重疊網段 (需核心 3.8+)
hash:ip,portIP+埠組合精細封鎖特定服務埠
hash:net,port網段+埠
bitmap:ip小範圍連續 IPv4 (如 /24 內)記憶體極省 (位圖),速度最快
list:set集合的集合 (多層級管理)分類管理 (如: cn_blacklist, brute_force, scanner)

部署實戰:建立與掛載黑名單集合

1. 安裝工具

# Debian/Ubuntu
apt update && apt install -y ipset iptables
# RHEL/CentOS/Fedora
dnf/yum install -y ipset iptables
# 現代系統建議改用 nftables (原生支援 set)
dnf install nftables

2. 建立黑名單集合 (hash:net 推薦,支援 CIDR)

# 建立名為 "blacklist" 的集合,最大 100 萬條目
ipset create blacklist hash:net maxelem 1000000

# 可選:啟用計數器 (統計命中次數) 和超時自動清理 (秒)
ipset create blacklist hash:net maxelem 1000000 counters timeout 86400

3. 批量導入 IP/網段

# 手動單條添加
ipset add blacklist 1.2.3.4
ipset add blacklist 5.6.0.0/16

# 批量從文件導入 (格式: add blacklist 1.2.3.4/32)
ipset restore < blacklist.txt

# 從威脅情報源自動生成 (示例: FireHOL level1)
curl -s "https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset" | \
  sed 's/^/add blacklist /' | ipset restore

4. 掛載至防火牆 (單條規則匹配百萬 IP)

# iptables 方式 (傳統)
iptables -I INPUT -m set --match-set blacklist src -j DROP
# 指定協議/埠: -p tcp --dport 22,80,443

# nftables 方式 (現代、原生、高效) - 推薦
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; }
nft add set inet filter blacklist { type ipv4_addr \; flags interval \; }  # interval 自動合併 CIDR
nft add rule inet filter input ip saddr @blacklist drop

# 導入數據到 nft set
nft -f - <

5. 持久化 (重啟生效)

# ipset 持久化
ipset save blacklist > /etc/ipset/blacklist.set
# 建立 systemd 服務或加入啟動腳本: ipset restore < /etc/ipset/blacklist.set

# iptables 持久化
iptables-save > /etc/iptables/rules.v4  # Debian/Ubuntu: apt install iptables-persistent
# 或 systemctl enable iptables (RHEL)

# nftables 持久化 (原生)
nft list ruleset > /etc/nftables.conf
systemctl enable nftables

自動化威脅情報更新腳本

#!/bin/bash
# /usr/local/bin/update-blacklist.sh
SET_NAME="blacklist"
URLS=(
  "https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset"
  "https://lists.blocklist.de/lists/all.txt"
  "https://rules.emergingthreats.net/blockrules/compromised-ips.txt"
)

TMP_FILE=$(mktemp)
echo "create $SET_NAME hash:net maxelem 2000000 counters timeout 2592000" > "$TMP_FILE" # 30天過期

for url in "${URLS[@]}"; do
  curl -sL "$url" | grep -E '^[0-9]{1,3}(\.[0-9]{1,3}){3}(/[0-9]{1,2})?$' | \
    sed "s/^/add $SET_NAME /" >> "$TMP_FILE"
done

# 原子性替換: 建立臨時集合 -> 交換名稱 -> 刪除舊集合
ipset create tmp_blacklist hash:net maxelem 2000000 counters timeout 2592000
ipset restore -f "$TMP_FILE" -exist  # -exist 忽略重複
ipset swap tmp_blacklist "$SET_NAME"
ipset destroy tmp_blacklist
rm -f "$TMP_FILE"

logger "IP黑名單更新完成: $(ipset list $SET_NAME | grep 'Number of entries' | awk '{print $4}') 條目"

加入 crontab -e 定時執行 (如每 6 小時):0 */6 * * * /usr/local/bin/update-blacklist.sh

監控與驗證

# 查看集合統計
ipset list blacklist | head -20
# Number of entries: 125430
# References: 1

# 即時監控命中 (需啟用 counters)
watch -n 1 'ipset list blacklist | grep -A1 "Number of entries"'

# 測試封鎖生效
ipset test blacklist 1.2.3.4  # 1.2.3.4 is in set blacklist.
# 實際連接測試 (從受信任 IP 發起)
curl -I https://your_server_ip

白名單機制 (防止誤封管理 IP)

# 建立白名單集合
ipset create whitelist hash:ip
ipset add whitelist 203.0.113.50  # 管理員辦公室 IP

# iptables: 白名單規則放在黑名單之前 (優先級更高)
iptables -I INPUT -m set --match-set whitelist src -j ACCEPT
iptables -I INPUT -m set --match-set blacklist src -j DROP

# nftables: 規則順序決定優先級
nft add rule inet filter input ip saddr @whitelist accept
nft add rule inet filter input ip saddr @blacklist drop

總結

ipset + iptables/nftables 是 Linux 主機層面應對海量 IP 封鎖的標準解決方案。關鍵要點:選擇 hash:net 支援 CIDR、啟用 counters 監控、使用 timeout 自動清理舊條目、採用 swap 原子更新避免競態、構建自動化威脅情報餵養管線、務必配置白名單防誤封。對於 >10Gbps 體積型攻擊,仍需依賴上游運營商/雲廠商清洗。

copyright © 萬盛學電腦網 all rights reserved