雲主機建好 LAMP 之後,接下來最重要的是建立 L3 及 L4 防火牆規則,把一些爬蟲、代理池與高風險國家 IP 區段封鎖,減輕硬碟的 I/O 壓力。
不然每隔幾秒就來一次請求,就算 L7 應用層有高階防爬蟲機制,還是會消耗雲主機的算力。
當然最好是在路由端用硬體防火牆清洗,但因為是雲主機沒有實體路由,因此改用 Linux kernel 層級的黑名單系統 ipset 也能達到 L3 與 L4 清洗效果,讓 Apache/PHP 完全碰不到,不吃 CPU、不吃 I/O。
經過實際執行、爆肝測試後,去除所有失敗方法,以下為正確建立ipset 黑名單的方法:
1、建立 ipset
sudo ipset create blacklist hash:ip
如果看到:
ipset v7.x.x: Set cannot be created: already exists
代表曾經建立過,需要 destroy。
如果返回:
Command 'ipset' not found, but can be installed with: apt install ipset
表示 Linux 初始環境沒有預裝 ipset,輸入以下指令安裝:
sudo apt update
sudo apt install ipset -y
完成後驗證:
ipset list
如果返回:
ipset v7.x.x: The set with the given name does not exist
表示 ipset 已成功安裝(但還沒建立 blacklist)。
2、建立一份「只有網段」的列表檔
輸入指令建立
sudo nano /root/blacklist.txt
貼上以下內容(改成您自己的IP名單)
1.0.1.0/24
1.0.2.0/23
1.0.8.0/21
1.0.32.0/19
(略…)
Ctrl+O 儲存 → Enter 確認 → Ctrl+X 返回。注意:一定要用 nano 建立,避免 BOM/CRLF 問題。
3、建立自動載入腳本
輸入指令建立
sudo nano /usr/local/bin/ipset-load.sh
貼入以下腳本
#!/bin/bash
貼入以下代碼
[Unit]
Description=Load IP blacklist into ipset
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/ipset-load.sh
[Install]
WantedBy=multi-user.target
儲存後啟用
sudo systemctl daemon-reload
sudo systemctl enable ipset-blacklist.service
5、立刻手動啟動一次(等於自動執行效果)
sudo systemctl start ipset-blacklist.service
輸入檢查:
sudo ipset list blacklist | head
sudo iptables -L INPUT -n --line-numbers | head
應該會看到:
blacklist 有 xxxx+ 筆iptables 第一行 有 DROP match-set blacklist
這樣就完成 ipset 黑名單建立。
6、重開機測試(最關鍵)
sudo reboot
重啟後檢查:
sudo ipset list blacklist | head
sudo iptables -L INPUT -n --line-numbers
若依然能看到:
blacklist xxxx+ 筆
iptables 第一行 DROP
就表示 Linux 開機會自動載入 blacklist.txt。
7、增加封鎖 IP 規則(只需要這些步驟)
新增的黑名單就會即時生效,由 ipset 在 Kernel 層封鎖。
以上是我昨天爆肝整理出來的流程,踩雷踩到懷疑人生,但最後成功把 .htaccess 黑名單升級到 Linux kernel 黑名單,大幅降低 Apache / PHP / I/O 壓力。
有需要的朋友參考看看。
工作心得撰寫:徐嘉裕 Neil hsu
不然每隔幾秒就來一次請求,就算 L7 應用層有高階防爬蟲機制,還是會消耗雲主機的算力。
當然最好是在路由端用硬體防火牆清洗,但因為是雲主機沒有實體路由,因此改用 Linux kernel 層級的黑名單系統 ipset 也能達到 L3 與 L4 清洗效果,讓 Apache/PHP 完全碰不到,不吃 CPU、不吃 I/O。
經過實際執行、爆肝測試後,去除所有失敗方法,以下為正確建立ipset 黑名單的方法:
1、建立 ipset
sudo ipset create blacklist hash:ip
如果看到:
ipset v7.x.x: Set cannot be created: already exists
代表曾經建立過,需要 destroy。
如果返回:
Command 'ipset' not found, but can be installed with: apt install ipset
表示 Linux 初始環境沒有預裝 ipset,輸入以下指令安裝:
sudo apt update
sudo apt install ipset -y
完成後驗證:
ipset list
如果返回:
ipset v7.x.x: The set with the given name does not exist
表示 ipset 已成功安裝(但還沒建立 blacklist)。
2、建立一份「只有網段」的列表檔
輸入指令建立
sudo nano /root/blacklist.txt
貼上以下內容(改成您自己的IP名單)
1.0.1.0/24
1.0.2.0/23
1.0.8.0/21
1.0.32.0/19
(略…)
Ctrl+O 儲存 → Enter 確認 → Ctrl+X 返回。注意:一定要用 nano 建立,避免 BOM/CRLF 問題。
3、建立自動載入腳本
輸入指令建立
sudo nano /usr/local/bin/ipset-load.sh
貼入以下腳本
#!/bin/bash
# 建立 blacklist(若存在就忽略)
ipset create blacklist hash:net family inet hashsize 131072 maxelem 1000000 -exist
# 清空舊內容(不論是否存在)
ipset flush blacklist
# 從純文字逐行加入
while read net; do
[[ -z "$net" ]] && continue # 空行跳過
[[ "$net" =~ ^# ]] && continue # 註解跳過
ipset add blacklist "$net" -exist
done < /root/blacklist.txt
# 確保 iptables DROP 規則存在
iptables -C INPUT -m set --match-set blacklist src -j DROP 2>/dev/null
if [ $? -ne 0 ]; then
iptables -I INPUT -m set --match-set blacklist src -j DROP
fi
儲存後賦予可執行權限:
sudo chmod +x /usr/local/bin/ipset-load.sh
4、建立 systemd 服務(開機自動跑)
輸入指令建立
sudo nano /etc/systemd/system/ipset-blacklist.service
ipset create blacklist hash:net family inet hashsize 131072 maxelem 1000000 -exist
# 清空舊內容(不論是否存在)
ipset flush blacklist
# 從純文字逐行加入
while read net; do
[[ -z "$net" ]] && continue # 空行跳過
[[ "$net" =~ ^# ]] && continue # 註解跳過
ipset add blacklist "$net" -exist
done < /root/blacklist.txt
# 確保 iptables DROP 規則存在
iptables -C INPUT -m set --match-set blacklist src -j DROP 2>/dev/null
if [ $? -ne 0 ]; then
iptables -I INPUT -m set --match-set blacklist src -j DROP
fi
儲存後賦予可執行權限:
sudo chmod +x /usr/local/bin/ipset-load.sh
4、建立 systemd 服務(開機自動跑)
輸入指令建立
sudo nano /etc/systemd/system/ipset-blacklist.service
貼入以下代碼
[Unit]
Description=Load IP blacklist into ipset
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/ipset-load.sh
[Install]
WantedBy=multi-user.target
儲存後啟用
sudo systemctl daemon-reload
sudo systemctl enable ipset-blacklist.service
5、立刻手動啟動一次(等於自動執行效果)
sudo systemctl start ipset-blacklist.service
輸入檢查:
sudo ipset list blacklist | head
sudo iptables -L INPUT -n --line-numbers | head
應該會看到:
blacklist 有 xxxx+ 筆iptables 第一行 有 DROP match-set blacklist
這樣就完成 ipset 黑名單建立。
6、重開機測試(最關鍵)
sudo reboot
重啟後檢查:
sudo ipset list blacklist | head
sudo iptables -L INPUT -n --line-numbers
若依然能看到:
blacklist xxxx+ 筆
iptables 第一行 DROP
就表示 Linux 開機會自動載入 blacklist.txt。
7、增加封鎖 IP 規則(只需要這些步驟)
編輯黑名單:
sudo nano /root/blacklist.txt
加入新增封鎖IP:
45.72.0.0/16
103.100.0.0/20
重新載入:
sudo systemctl restart ipset-blacklist.service
sudo nano /root/blacklist.txt
加入新增封鎖IP:
45.72.0.0/16
103.100.0.0/20
重新載入:
sudo systemctl restart ipset-blacklist.service
新增的黑名單就會即時生效,由 ipset 在 Kernel 層封鎖。
以上是我昨天爆肝整理出來的流程,踩雷踩到懷疑人生,但最後成功把 .htaccess 黑名單升級到 Linux kernel 黑名單,大幅降低 Apache / PHP / I/O 壓力。
有需要的朋友參考看看。
工作心得撰寫:徐嘉裕 Neil hsu
留言
張貼留言