快速遴選出 NGINX log 裡想擋掉的 IP,並用 ufw 或 TCP Wrapper 擋起來

需要運用 Linux pipeline 的技巧

假設有一種 request 帶有字串『BAD STRING』,你就認定是壞蛋要擋住

那麼第一步遴選出 IP 的步驟應該是

cat /var/log/nginx/access.log | grep 'BAD STRING' | awk '{print $1}'

找出有 『BAD STRING』 的行,然後用 awk 取出第一直欄的資料 (awk 預設以空格做直欄的劃分,進一步了解 awk 可參考菜鳥教程)

這時候 data stream 應該是每個 IP 一行,總共 N 行的資料,現在第二步要把它丟到 ufw 或 TCP Wrapper

先說 ufw,假設 ufw 有運作的情況下,只要用 xargs 把 IP list 變成 ufw 的 輸入參數 即可。

正常要用 ufw 新增一個擋指定 IP 的指令是

sudo ufw deny from [Your IP]

所以,串起來就是

cat /var/log/nginx/access.log | grep 'BAD STRING' | awk '{print $1}' | xargs sudo ufw deny from

很簡單吧!

把上面這行寫到某個 bash,中間 grep ‘BAD STRING’ 把它寫成自己想判斷的 pattern,定時執行,就是個很簡單的小防禦了。

不過呢~ 注意一下,瘋狂執行 sudo ufw deny from 的代價是 CPU 會飆升到 100% 喔! 你要確定這樣沒問題才行 (例如,有的主機架構,有設計自動擴展,當你的CPU持續衝高,就會帶來機器的持續增生,所以請小心,別回頭才發現帳單爆了)

或是,也可用 TCP Wrapper (若想了解一般 TCP Wrapper 使用可參考/etc/hosts.allow 及 /etc/hosts.deny 限制 IP 連線),要把資訊寫到 hosts.allow or hosts.deny ,單行的格式是

# 協定: IP(CIDR格式)
ALL :  192.168.1.1/32
sshd:  192.168.0.0/16 

所以串起來就類似

cat /var/log/nginx/access.log | grep 'BAD STRING' | awk '"ALL: "{print $1}"/32"' >> /etc/hosts.deny 

除了 IP 之外的 ALL : 以及 /32 ,用 awk 把字串接出來,然後 append 到 /etc/hosts.deny 內,存檔後即生效,一樣是一行完成。也一樣可以很方便丟到 bash 內,定時執行~

 

提醒: 這裡記得先用一些測試性質的檔案,確認一些格式,例如換行之類的,都OK後,再寫入正式檔案,較為穩妥。

You Might Also Like

Leave a Reply

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料