Telegram Bot 通知系統實作
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 發送訊息。
我的 TOKEN 和 CHAT_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,這個文件裡面是用來處理使用者驗證。
上面這是我的最終設定,第一行的重點是 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,要把 md0 和 sda 改成自己的 RAID 和硬碟編號。
但如果腳本有問題,也不會有訊息讓你除錯,所以有點吃運氣,我就改了滿多次的。
小結
這次一口氣做完兩個部分,真的滿有成就感的,也多學到很多技術。
Telegram Bot 能做的事真的很多,這只是一個小應用而已,未來我應該會讓更多項目也加入 Telegram Bot,真的很方便。