目錄
1. 核心命令速查
2. 集合類型
3. 實戰案例:使用 ipset 封禁 IP
案例 1:基礎黑名單封禁(手動添加)
案例 2:自動過期和解封
案例 3:封禁 IP 和端口組合
案例 4:白名單模式
案例 5:自動化封禁(SSH 暴力破解)
案例 6:自動化封禁(Web 服務 CC 攻擊)
案例 7:屏蔽特定國家/地區的 IP 訪問
案例 8:動態域名白名單
4. ipset 規則持久化
方法一:使用ipset-service服務
1. 安裝與配置
2. 手動保存規則
3. 自動持久化配置
方法二:systemd自定義服務
1. 保存當前規則
2. 創建服務文件
3. 啟用服務
方法三:手動恢復(臨時/應急)
1. 導出規則
2. 重啟后恢復
保存 iptables 規則
6. 注意事項
ipset是Linux系統中一個強大的命令行工具,用于創建、維護和管理一組IP地址、端口號、MAC地址、網絡接口或其他網絡元素的集合(set)。它通過與防火墻系統(如iptables或nftables)集成,顯著提升規則管理的效率和性能。以下是基于其核心特性、功能及實戰案例的介紹:
1. 核心命令速查
先通過一個表格快速了解 ipset 的常用命令:
命令示例 | 作用說明 |
---|---|
ipset create blacklist hash:ip | 創建名為?blacklist ,類型為?hash:ip ?的集合 |
ipset add blacklist 192.168.2.100 | 向?blacklist ?集合添加一個 IP |
ipset add blacklist 203.204.205.0/24 | 向?blacklist ?集合添加一個網段 |
ipset del blacklist 192.168.2.100 | 從?blacklist ?集合刪除一個 IP |
ipset list blacklist | 查看?blacklist ?集合的內容 |
ipset list | 查看所有集合 |
ipset flush blacklist | 清空?blacklist ?集合中的所有條目 |
ipset destroy blacklist | 徹底銷毀?blacklist ?集合 |
ipset save blacklist | 導出?blacklist ?集合的內容 |
ipset restore -f ipset.txt | 從文件恢復集合內容 |
2. 集合類型
ipset 支持多種集合類型,以適應不同的匹配需求:
集合類型 | 存儲內容 | 適用場景 |
---|---|---|
hash:ip | 單個 IP 地址 | 封禁或允許特定的主機 |
hash:net | 網絡段(CIDR) | 封禁或允許整個網段 |
hash:ip,port | IP 地址和端口號(如?192.168.8.1,80 ) | 封禁或允許特定 IP 對特定端口的訪問 |
hash:net,port | 網絡段和端口號(如?203.8.100.0/24,443 ) | 封禁或允許特定網段對特定端口的訪問 |
hash:ip,port,ip | IP、端口、IP(三層結構) | 更復雜的匹配條件 |
hash:ip,mark | IP 和數據包標記 | 與 iptables 的 MARK 動作結合使用 |
hash:mac | MAC 地址 | 基于物理地址進行過濾 |
bitmap:ip | IPv4 地址的位圖,范圍固定 | 適用于較小的、連續的 IP 范圍 |
bitmap:port | 端口號的位圖 | 適用于端口范圍 |
list:set | 集合的列表 | 嵌套集合,將多個集合組合成一個更大的集合 |
3. 實戰案例:使用 ipset 封禁 IP
案例 1:基礎黑名單封禁(手動添加)
這是最直接的場景:手動將可疑 IP 加入黑名單并封禁。
# 1. 創建一個名為 `blacklist` 的 IP 集合,類型為 hash:ip
sudo ipset create blacklist hash:ip# 2. 添加一條 iptables 規則,拒絕所有來自 `blacklist` 集合中 IP 的輸入流量
sudo iptables -I INPUT -m set --match-set blacklist src -j DROP# 3. 現在,你可以向黑名單中添加 IP 了
sudo ipset add blacklist 192.168.8.100 # 添加單個 IP
sudo ipset add blacklist 200.10.100.0/24 # 添加整個網段# 4. (可選)檢查 blacklist 集合的內容
sudo ipset list blacklist
效果:所有來自?192.168.8.100
?和?200.10.100.0/24
?網段的流量將被服務器立即丟棄。
案例 2:自動過期和解封
對于臨時封禁(例如 SSH 密碼嘗試失敗多次),可以設置超時(timeout),讓 IP 自動從黑名單中移除。
# 1. 創建名為 `ssh-ban` 的集合,并設置默認超時時間為 1 小時 (3600 秒)
sudo ipset create ssh-ban hash:ip timeout 3600# 2. 設置 iptables 規則,對 SSH (22端口) 的訪問如果來自 `ssh-ban` 集合則拒絕
sudo iptables -I INPUT -p tcp --dport 22 -m set --match-set ssh-ban src -j DROP# 3. 當檢測到惡意嘗試時,添加 IP,并可以指定不同的超時時間
sudo ipset add ssh-ban 192.168.8.200 # 默認 1 小時后解封
sudo ipset add ssh-ban 198.168.100.55 timeout 7200 # 此 IP 2 小時 (7200秒) 后解封
注意:如果創建集合時沒有指定?timeout
?參數,則集合中的條目不會自動過期。
案例 3:封禁 IP 和端口組合
有時需要封禁某個 IP 對特定服務(端口)的訪問,但允許訪問其他服務。
# 1. 創建一個類型為 `hash:ip,port` 的集合,用于存儲 IP 和端口對
sudo ipset create service-abusers hash:ip,port# 2. 設置 iptables 規則,拒絕訪問 `service-abusers` 集合中定義的 IP 和端口組合
sudo iptables -I INPUT -m set --match-set service-abusers src,dst -j DROP# 3. 添加違規的 IP 和端口
sudo ipset add service-abusers 192.0.2.10,80 # 封禁該 IP 訪問 80 端口
sudo ipset add service-abusers 198.51.100.20,443 # 封禁該 IP 訪問 443 端口
sudo ipset add service-abusers 203.0.113.30,udp:53 # 封禁該 IP 訪問 UDP 53 端口
案例 4:白名單模式
ipset 也可以用于創建白名單,只允許特定集合中的 IP 訪問。
# 1. 創建一個名為 `whitelist` 的白名單集合,并添加允許的 IP
sudo ipset create whitelist hash:ip
sudo ipset add whitelist 192.0.2.1
sudo ipset add whitelist 203.0.113.5# 2. 設置 iptables 規則:**非白名單即拒絕**
# 注意這里的 `!` 表示取反
sudo iptables -I INPUT -m set ! --match-set whitelist src -j DROP
應用場景:嚴格限制訪問源,例如數據庫端口、管理后臺等。
案例 5:自動化封禁(SSH 暴力破解)
結合日志分析和 cron 定時任務,實現自動封禁 SSH 暴力破解的 IP。
#!/bin/bash
# 文件名: /root/ban_ssh_abuse.sh
# 監控 /var/log/secure(CentOS/RHEL)或 /var/log/auth.log(Debian/Ubuntu),將多次嘗試失敗的 IP 加入 ipsetLOG_FILE="/var/log/secure"
FAILED_THRESHOLD=5 # 失敗次數閾值
BAN_SET="ssh-ban" # ipset 集合名,需要預先創建好(帶 timeout)# 分析過去一小時的日志,找出失敗次數超過閾值的 IP
grep "Failed password" "$LOG_FILE" | awk -v threshold="$FAILED_THRESHOLD" '
{# 提取 IP 地址(根據你的日志格式調整 awk 字段)if (match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {ip = substr($0, RSTART, RLENGTH)count[ip]++}
}
END {for (ip in count) {if (count[ip] > threshold) {print ip}}
}' | while read -r malicious_ip; do# 將惡意 IP 添加到 ipset 集合中ipset add "$BAN_SET" "$malicious_ip" 2>/dev/null && echo "[$(date)] Banned IP: $malicious_ip"
done
然后,使用?crontab -e
?添加定時任務,每 5 分鐘運行一次此腳本:
*/5 * * * * /root/ban_ssh_abuse.sh
案例 6:自動化封禁(Web 服務 CC 攻擊)
類似地,可以監控 Nginx 或 Apache 日志,封禁請求頻率過高的 IP。
#!/bin/bash
# 文件名: /root/ban_http_abuse.shLOG_FILE="/var/log/nginx/access.log"
REQ_THRESHOLD=1000 # 一分鐘內請求數閾值
BAN_SET="http-ban" # ipset 集合名# 分析上一分鐘的日志,統計每個 IP 的請求數
DATE=$(date -d '1 minute ago' +%d/%b/%Y:%H:%M)
grep "$DATE" "$LOG_FILE" | awk '{print $1}' | sort | uniq -c | sort -nr | \
while read -r count ip; doif [[ "$count" -gt "$REQ_THRESHOLD" ]]; thenipset add "$BAN_SET" "$ip" 2>/dev/null && echo "[$(date)] Banned IP: $ip (Requests: $count)"fi
done
同樣地,設置 cron 任務定時執行(例如每分鐘)。
案例 7:屏蔽特定國家/地區的 IP 訪問
這個需求很常見,可以利用現成的國家 IP 段列表。
-
獲取國家的 IP 段列表:
# 例如下載中國的 IP 段(假設我們要創建白名單) wget -O cn.zone http://www.ipdeny.com/ipblocks/data/countries/cn.zone
-
創建 ipset 集合并導入 IP 段:
# 創建一個 hash:net 類型的集合來存儲網絡段 sudo ipset create cn-whitelist hash:net# 將下載的 IP 段添加到集合中 for i in $(cat cn.zone); dosudo ipset add cn-whitelist "$i" done
-
設置 iptables 規則:
# 示例:只允許來自中國 IP 段的流量訪問 80 和 443 端口 sudo iptables -A INPUT -p tcp --dport 80 -m set --match-set cn-whitelist src -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -m set --match-set cn-whitelist src -j ACCEPT # 然后設置相應的 DROP 規則(務必謹慎,以免鎖自己于服務器之外)
案例 8:動態域名白名單
如果你的服務器需要允許訪問一些域名,但這些域名的 IP 可能會變,可以用腳本定期解析并更新 ipset。
#!/bin/bash
# 文件名: /root/update_dynamic_whitelist.shDOMAIN_LIST="api.example.com some-cdn.com"
WHITELIST_SET="dynamic-whitelist"# 清空集合(或者先創建一個臨時集,然后交換)
sudo ipset flush "$WHITELIST_SET"for domain in $DOMAIN_LIST; do# 解析域名獲取 IPdig +short "$domain" | while read -r ip; doif [[ ! -z "$ip" ]]; thensudo ipset add "$WHITELIST_SET" "$ip"fidone
done
設置 cron 任務定期運行(例如每小時),確保 IP 地址是最新的。
4. ipset 規則持久化
重要提示:默認情況下,ipset 規則和 iptables 規則一樣,重啟后會丟失。必須手動保存和恢復。
方法一:使用ipset-service服務
1. 安裝與配置
# CentOS為例
yum install -y ipset-service ?
systemctl enable ipset ? --now
2. 手動保存規則
ipset save > /etc/ipset.conf # 導出規則至配置文件
3. 自動持久化配置
編輯/etc/sysconfig/ipset-config
,確保以下參數啟用
IPSET_SAVE_ON_STOP="yes" # 停止服務時自動保存
IPSET_SAVE_FILE="/etc/ipset.conf" # 配置文件路徑
方法二:systemd自定義服務
1. 保存當前規則
ipset save > /etc/ipset.conf
2. 創建服務文件
vim /etc/systemd/system/ipset-persistent.service
內容如下:
[Unit]
Description=ipset persistent configuration
Before=network.target [Service]
Type=oneshot
ExecStart=/usr/sbin/ipset restore -f /etc/ipset.conf
ExecStop=/usr/sbin/ipset save -f /etc/ipset.conf
RemainAfterExit=yes [Install]
WantedBy=multi-user.target
3. 啟用服務
systemctl daemon-reload
systemctl enable ipset-persistent --now
方法三:手動恢復(臨時/應急)
1. 導出規則
ipset save > /etc/ipset.conf
2. 重啟后恢復
ipset restore < /etc/ipset.conf
- 自動加載:可將命令加入
/etc/rc.local
(確保文件有執行權限)。
保存 iptables 規則
同樣,別忘了保存和持久化 iptables 規則。
sudo iptables-save > /etc/iptables/rules.v4 # 對于 IPv4
sudo ip6tables-save > /etc/iptables/rules.v6 # 對于 IPv6
# 然后啟用 iptables-persistent 服務,或配置相應機制。
6. 注意事項
-
謹慎操作:錯誤的 iptables 或 ipset 規則可能導致你把自己鎖在服務器外面。務必在本地控制臺或通過一個不會受規則影響的獨立連接(例如管理控制臺)上進行操作。
-
備份規則:在對規則進行重大更改之前,先備份當前的 ipset 和 iptables 規則。
-
性能考慮:對于非常龐大的集合(數十萬條),
hashsize
?和?maxelem
?參數的初始設置會影響性能和內存使用。根據情況調整。 -
組合使用:ipset 通常與 iptables 結合使用,單獨使用 ipset 不會產生任何效果。
-
列表優化:對于大型的 IP 地址段列表,可以使用?
iprange
?這樣的工具來合并相鄰的 IP 范圍,有助于減少 ipset 中的條目數量并提升性能。