寫了個 Script,用來把監控送來的 IP 清單,丟到 FortiGate 及 Cloudflare 黑名單,大致是

監控系統會統計 nginx 連線 IP 及連線數量,當 IP 連線數量超過闕值,就透過 webhook 去 Trigger Gitlab CI 運行 Script。

Script 內容主要是將接收到的 IP,組成 Cloudflare 需要的格式對 FortiGate、Cloudflare 做操作。

$TRIGGER_PAYLOAD 是 Gitlab CI 接收 Webhook 內容後固定的變數,需要用 cat 來顯示。

labels.remote 是 nginx 紀錄遠端 IP 的欄位,儲存到 Log Server後,監控取出該欄位有大量連線就送過來

#!/bin/bash
ipList=$(cat $TRIGGER_PAYLOAD | jq -r ".alerts[].labels.remote")
if [ -z $ipList ]; then
  echo "No IP found"
  exit 0
fi

postData=""
for ip in $ipList; do
  object="{\"ip\":\"$ip\"},"
  postData+="$object"
  blockByFortigate
done
blockByCloudflare

連線到 FortiGate 執行封鎖命令

blockByFortigate() {
  sshpass -p "$FORTIGATE_PASSWORD" ssh -o StrictHostKeyChecking=no "$FORTIGATE_USER@$IP" diagnose user quarantine add src4 $ip 315360000 admin
}

調用 Cloudflare API 加入封鎖清單

blockByCloudflare() {
  curl --location "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rules/lists/$LIST_ID/items" \
  --header "X-Auth-Email: $EMAIL" \
  --header "X-Auth-Key: $CLOUDFLARE_AUTH_KEY" \
  --header 'Content-Type: application/json' \
  --data "[${postData:0:-1}]"
}

完整 Script 內容

#!/bin/bash
ipList=$(cat $TRIGGER_PAYLOAD | jq -r ".alerts[].labels.remote")
if [ -z $ipList ]; then
  echo "No IP found"
  exit 0
fi

blockByFortigate() {
  sshpass -p "$FORTIGATE_PASSWORD" ssh -o StrictHostKeyChecking=no "$FORTIGATE_USER@$IP" diagnose user quarantine add src4 $ip 315360000 admin
}

blockByCloudflare() {
  curl --location "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rules/lists/$LIST_ID/items" \
  --header "X-Auth-Email: $EMAIL" \
  --header "X-Auth-Key: $CLOUDFLARE_AUTH_KEY" \
  --header 'Content-Type: application/json' \
  --data "[${postData:0:-1}]"
}

postData=""
for ip in $ipList; do
  object="{\"ip\":\"$ip\"},"
  postData+="$object"
  blockByFortigate
done
blockByCloudflare

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *