Skip to main content

Telegram Bot 通知系統實作

· 6 min read

Telegram 台灣用的人應該也不少,裡面我最喜歡的功能是 Bot,因為申請很方便,不用一分鐘就能開一個機器人,而且他們會有伺服器 7/24 掛著,直接發 HTTP 就能用了。

再者他們的 API 文檔也都寫的很清楚。Webhook 還可以結合 Cloudflare Worker,用起來非常的舒服,完全不用架設任何東西。

之前我就一直想要把這個機器人結合我的 Linux 登入還有 RAID,但不確定為什麼登入通知一直不太穩定,今天就下定決心一次做完所有東西。

Telegram Bot 申請

直接看官方的教學,這部分不難。

簡單來說就是要加一個叫 BotFather 的帳號,接著就點點點,幫機器人取個名字,之後就能拿到 TOKEN 了,不會要你的任何資料。

有了這個 TOKEN 就能去參考 API 文檔,最基本的 URL 長這樣 https://api.telegram.org/bot<TOKEN>/,後面接操作,最後看是要用 GET 還是 POST 發送就行了。

腳本

最重要的腳本是下面這份,用來操作 Telegram Bot 發送訊息。

我的 TOKENCHAT_ID 是寫死在一個設定檔,運行的時候再讀取。

#/bin/sh

if [ ! $1 ]; then
echo "Message is required"
exit 1
fi

. /root/.config/tg-bot.env

curl -X POST \
-H "Content-Type: application/json" \
-d "{\"chat_id\": \"$CHAT_ID\", \"text\": \"$1\"}" \
"https://api.telegram.org/bot$TOKEN/sendMessage"

有了這個腳本之後要發訊息就直接呼叫就行了。

PAM 模組

和 Linux 登入有關的東西都會掛在 PAM 上面,PAM 其實不是一個軟體,是一套組件。包含改密碼、密碼規則、重試頻率等等的,反正無論想得到或想不到的,只要跟登入有關的都會放在 PAM。

額外補充,PAM 的組件其實也能自己寫,像 ecryptfs、fscrypt 這種會用到使用者登入功能的就會有自己的 PAM 組件,用來讀使用者輸入的密碼。

這次要編輯的檔案是 /etc/pam.d/common-auth,這個文件裡面是用來處理使用者驗證。

common-auth 文件內容

上面這是我的最終設定,第一行的重點是 success=2 這行,用來標示如果密碼正確要跳過接下來幾行,像現在的設定就是會跳過兩行。而被跳過的兩行就是登入失敗要執行的組件。

第二行和第四行是新增的內容,pam_exec.so 的功能就是去執行後面接的檔案,像這裡是去跑後面我寫的腳本。

第二行是發出登入失敗的通知,而第四行是發出登入成功的通知。

登入成功的腳本長下面這樣,主要程式碼要像我這樣設計才能防止阻塞,不然登入的時候還要等 API 呼叫的時間,體驗會很差。

有三個變數分別是 $PAM_RHOST$PAM_USER$PAM_SERVICE,它們代表的是連線的 IP、試圖登入的使用者、要登入的服務(如 ssh)

#!/bin/sh

(
MSG="[$(date '+%Y-%m-%d %H:%M:%S')]"
[ -n "$PAM_RHOST" ] && MSG="$MSG [$PAM_RHOST]"
[ -n "$PAM_USER" ] && MSG="$MSG [$PAM_USER]"
[ -n "$PAM_SERVICE" ] && MSG="$MSG [$PAM_SERVICE]"

MSG="$MSG Login successfully"

/usr/sbin/send-message-to-tg-bot.sh "$MSG"
) > /dev/null 2>&1 &
exit 0

登入失敗就只是改個字而已,這部分不在贅述。

在測試的過程中一定會遇到 BUG,要除錯的方法是去看 /var/log/auth.log 這個檔案,執行錯誤會有記錄。在試的時候多使用 > 把輸出導到某個檔案看哪裡有錯誤。

RAID

我是用 mdadm 組了一個軟 RAID,那自然要動的就是 mdadm,要改的檔案是 /etc/mdadm/mdadm.conf

要做的事也很簡單,只需加入 PROGRAM /usr/sbin/send-mdadm-msg.sh 這行。

我自己的腳本和 PAM 差不多。$1$2$3 分別代表的是通知類型、RAID 編號、出問題的硬碟編號。$3 不一定會有,只有特定情況才會發生。

#!/bin/bash

(
MSG="[$(date '+%Y-%m-%d %H:%M:%S')]"
[ -n "$2" ] && MSG+=" [$2]"
[ -n "$3" ] && MSG+=" [$3]"
[ -n "$1" ] && MSG+=" $1"

/usr/sbin/send-message-to-tg-bot.sh "$MSG"
) > /dev/null 2>&1 &
exit 0

用完之後就可以來測試,用指令 mdadm /dev/md0 --manage --set-faulty /dev/sda,要把 md0sda 改成自己的 RAID 和硬碟編號。

但如果腳本有問題,也不會有訊息讓你除錯,所以有點吃運氣,我就改了滿多次的。

小結

這次一口氣做完兩個部分,真的滿有成就感的,也多學到很多技術。

Telegram Bot 能做的事真的很多,這只是一個小應用而已,未來我應該會讓更多項目也加入 Telegram Bot,真的很方便。