因為webmin是網頁版,而且功能很多。
有時候我只是要看fail2ban到底有工作那些設定,以及封鎖那些數量。
原始套件指令的方式很不好用,要查已開啟的服務項目和去看個別服務封鎖誰。
因為這幾天在搞GDC的虛擬機,那今天想到問AI大概是魔法指令用對了。
問到我想要的方式呈現,順便記錄下來。
要安裝jp套件:
sudo apt-get install jq
好了以後就能這樣下指令來輔助顯示。
## 這樣的語法是全部服務都列出:
sudo fail2ban-client banned | tr "'" '"' | jq '.[] | to_entries[] | {service: .key, count: (.value | length), ips: .value}'
## 這樣的語法是只列出有封鎖IP的服務清單:
sudo fail2ban-client banned | tr "'" '"' | jq '.[] | to_entries[] | {service: .key, count: (.value | length), ips: .value} | select(.count > 1)'
那如果想要用crontab或是乾脆放在cron.daily的.sh檔案:
sudo touch fail2ban_report.sh
sudo chmod +x fail2ban_report.sh
sudo nano fail2ban_report.sh
檔案的內容可以這樣編輯:
#!/bin/bash
# 設定收件人信箱
RECIPIENT_EMAIL="your_email@example.com"
# 取得當前日期,格式為 YYYY-MM-DD
TODAY_DATE=$(date "+%Y-%m-%d")
# 設定郵件主旨,加入當前日期
EMAIL_SUBJECT="[${TODAY_DATE}] Fail2ban IP 已封鎖通知"
# 設定郵件內文
EMAIL_BODY="偵測到伺服器有新的 IP 封鎖狀況:\n\n"
HAS_BANNED_IP=false
# 獲取 Fail2ban 封鎖狀態,並將輸出轉換為 JSON
JSON_OUTPUT=$(sudo fail2ban-client banned | tr "'" '"' | jq -c '.[] | to_entries[] | {service: .key, count: (.value | length), ips: .value}')
# 逐一處理每個服務的 JSON 輸出
while read -r line; do
# 使用 jq 篩選出 count > 0 的服務
if echo "$line" | jq -e '.count > 0' >/dev/null; then
# 如果有封鎖,設定標記為 true
HAS_BANNED_IP=true
# 提取服務名稱、封鎖數量和 IP 清單
SERVICE=$(echo "$line" | jq -r '.service')
COUNT=$(echo "$line" | jq -r '.count')
IPS=$(echo "$line" | jq -r '.ips | .[]')
# 建立該服務的報告內容
EMAIL_BODY+="服務:$SERVICE\n"
EMAIL_BODY+="封鎖數量:$COUNT\n"
EMAIL_BODY+="被封鎖的 IP:\n"
for ip in $IPS; do
EMAIL_BODY+="- $ip\n"
done
EMAIL_BODY+="\n"
fi
done <<< "$JSON_OUTPUT"
# 如果有任何服務有 IP 被封鎖,則發送郵件
if [ "$HAS_BANNED_IP" = true ]; then
# 檢查系統是否安裝 mail 命令,如果沒有則使用 sendmail
if command -v mail &> /dev/null; then
echo -e "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT" "$RECIPIENT_EMAIL"
elif command -v sendmail &> /dev/null; then
(
echo "Subject: $EMAIL_SUBJECT"
echo ""
echo -e "$EMAIL_BODY"
) | sendmail "$RECIPIENT_EMAIL"
else
echo "錯誤: 系統沒有安裝 mail 或 sendmail,無法發送郵件。"
fi
fi
修改完成後,執行fail2ban_report.sh,看有沒有收到報告的信件。
沒問題就看要編輯在crontab呼叫,或是放到/etc/cron.daily/目錄下使用。