去年六月間發現我管的 penguin 主機速度變得超慢。 查了一下 log 檔, 發現有 e-mail harvester (e-mail 收割機) 在騷擾。 於是學會用基本的 iptables 指令防禦。 整理筆記分享如下。
[2016/4/4: 改推薦 「用 iptables 對付惡意幫派網頁爬蟲」 跟 fail2ban 這兩篇 ]
一、 警報
一開始只是注意到機器變很慢。 到了 5/25 整部機器就當掉了。 不過因為沒什麼人在用 ^_^||| 所以隔了好幾天我才發現並於 6/7 把它開機起來。 開起來之後還是很慢。 於是查看一下 /var/log。 看到 /var/log/apache2 底下的 log 檔時我驚呆了... 哇... 我的 penguin 機竟然那麼受歡迎 (捧臉傻笑) 流量估計達每週幾十萬人次!
-rw-r----- 1 root root 1357972 2014-07-06 06:43 access.log.45.gz -rw-r----- 1 root root 1511748 2014-06-29 06:33 access.log.46.gz -rw-r----- 1 root root 23056343 2014-06-22 06:41 access.log.47.gz -rw-r----- 1 root root 21078913 2014-06-15 06:39 access.log.48.gz -rw-r----- 1 root root 1463705 2014-06-08 06:33 access.log.49.gz -rw-r----- 1 root root 21 2014-06-07 20:33 access.log.50.gz -rw-r----- 1 root root 15504971 2014-05-25 06:29 access.log.51.gz -rw-r----- 1 root root 18780626 2014-05-18 06:38 access.log.52.gz
趕快看一下我的粉絲都來自哪裡: (請拿 真實資料的一小部分 來當做以下的 access.log 資料檔做實驗)
sed 's/ .*//' access.log | sort | uniq -c | sort -n
咦, 很多 IP 來自相同的子網域? 換個查詢方式, 把相同子網域的 IP 放在一起統計:
perl -ne 'print "$1*\n" if m#^((\d+\.){3})#' access.log | sort | uniq -c | sort -n
根本都是 220.181.108.* 跟 123.125.71.* 這兩個網域在幫我衝 (沒有用的) 流量! 這兩隻 (可能根本是同一隻) 機器人自稱是 Baiduspider; 但 上網一查, 發現它根本與百渡無關, 就只是惡質的 e-mail 收割機。
二、 可能對策
Apache2 設定檔的 deny 指令 可以直接阻止某些 IP。 另外, mod_evasive 模組可以把 「太頻繁造訪本站」 的網站暫時或永久封鎖掉。 使用 mod_evasive 的好處是: 只要設定一次, 從此以後就不怕類似的騷擾。
不過, 等到 apache2 看到收割機請求的時候, 它都已經浪費掉我的系統的一些運算資源了。 這樣不划算。 最好是每當從網卡上面看到它, 就直接丟掉。 於是貴哥終於第一次要學一點點 iptables 了!
三、 iptables 過濾封包
我需要的只是很簡單的、 類似 這一篇 所介紹的過濾條件。 另外還需要 iptables persistent 套件把成功手動設定的規則存起來, 以便重開機時系統會自動載入這些規則。
iptables -L iptables-save > ~/iptables-backup iptables -A INPUT -s 123.125.71.0/24 -j DROP iptables -A INPUT -s 220.181.108.0/24 -j DROP iptables -A INPUT -s 218.30.103.0/24 -j DROP iptables -L
以上指令查看 iptables 現有的規則、 備份現有規則、 設定規則阻斷騷擾、 再次查看 iptables 新的狀態。 (第三個 ip 是這幾天新發現並防堵起來的 惱人 ip。)
如果看來 OK, 就用
iptables-persistent 把它變成永久設定。
先安裝 iptables-persistent 套件。
以後每次把 iptables 改到一個滿意的地步時, 就下
iptables-save > /etc/iptables/rules.v4
把目前的設定存起來, 下次重開機時
iptables-persistent 就會自動從那裡讀回目前的設定。
iptables 有好幾個 tables, 每個 table 又有好幾條 chains。 像貴哥這樣的初學者只會用到預設的 filter table, 其中最常用來抵擋攻擊的就是 INPUT chain。 上面的指令翻成白話文就是: 把這條規則加到 (-A, append 的意思) INPUT 這條 chain 的最後面, 凡是遇到來源 (-s, source 的意思) 是 123.125.71.* 的 IP, 就直接跳到 (-j, jump 的意思) DROP 動作 (丟棄封包)。
如果下錯指令, 想刪除某幾條規則, 可以用
iptables -L INPUT --line-numbers
列出每條規則的代號,
然後用 iptables -D INPUT 42
刪除第 42 號規則。 注意: 原先的 43
號規則會向前遞補成 42 號, 依此類推。
鳥哥的文章 好長; geek stuff 跟 ArchLinux 的 wiki 兩篇好像很適合入門, 以後有空再來讀。
6/21 設定完成之後, 流量馬上降下來, 如最上面的流量統計圖。 (現在再回頭看, 6/27 之後又有開始出現怪怪的流量; 不過放了將近一年直到這兩天才發現...) 原來我的 penguin 機並沒有想像中那麼紅 ^_^ 。
附錄、 繪圖指令
[2016/6/12 更新: 原來 log 檔裡面的資料並不必然完全按照時間順序出現! 好吧,那就必須把月份從文字改成數字, 然後多經過一道排序手續。 以下指令、 traffic.gpt、 traffic.txt 皆已更新。 感覺不出視覺差別。] 本文流量統計圖的製作指令如下:
- 產生 「次數 時間」 統計文字檔:
perl -ne 'print "$2 $1 $3\n" if m#\[(\d+)/(\w+)/201\d:(\d+)#' /var/log/apache2/access.log | date -f - '+%m/%d:%H' | sort | uniq -c > traffic.txt
。 請參考我根據真實資料所產生的 traffic.txt。 - 把
traffic.gpt 裡面的
set xrange ...
那一句改成你的實際資料範圍。 - 進入
gnuplot 並執行
load traffic.gpt
就會產生 traffic.svg 圖檔。
其中 「以日期格式顯示 X 軸」 的設定方式, 參考的是 這一篇。
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。