自宅プロバイダがソフトバンク光なのですが、同プロパイダでは固定 IP が用意されておらず、グローバル IP が一定間隔で変化します。ですが、これでは多方面で都合が悪く、例えば SSH の際にいちいち IP を調べたりと何かと面倒でした。
そこで、このグローバル IP を cURL で取得、Slack に通知する Bot を作成して対応しました。
Slack App
Bot を作成する具体的な手順はコチラの方の記事をご参考頂ければと思います。
chat:write by Bot Token Scope
今回は Incoming Webhooks ではなく、Bot Token Scopes 内の chat:write で 通知を許可しました。と言うのも Slack の仕様変更に伴い Webhook URL を各チャンネルごとに発行する必要が出てきたためです。面倒なので Token のスコープ内で通知の Permission を有効化して、各チャンネルに通知できるようにしています。
slack api > Your Apps > 作成した App > OAuth & Permissions > Scopes
ただし、作成した App を通知したいチャンネル側で連携してあげないと not_in_channel
のエラーになります。この原因が分からず手こずりました(汗)
Slack ホーム画面 > App > 作成した App > 詳細 > その他 > チャンネルにこのアプリを連携させる
スクリプト
久々の Shell は辛すぎます。
簡単な処理の流れ
- crontab で一定期間ごとにスクリプトを起動
- IP の遍歴リストを格納している CSV を読み込み
- cURL で 現在のグローバル IP を取得
- IP リストの最後列(直近の IP)と 前ステップで取得した IP を比較
- IP が更新されていれば、Slack に cURL で POST
- 新 IP を IP リストの最後列に追加保存
Shell スクリプト
1#!/bin/bash
2
3FILENAME="ip_list.csv"
4# Bot User OAuth Access Token
5TOKEN="***-***-***-***"
6# 例) CHANNEL="general" (#を含める場合はurlencodeが必須)
7CHANNEL="***"
8
9DATA=`date`
10
11# CSVからIPリストを取得
12ip_list=()
13cat $FILENAME | while read line || [ -n "$line" ]; do
14 ip=`echo ${line} | cut -d , -f 1`
15 ip_list+=($ip)
16done
17
18# 現在のグローバルIPをcURLでGET、IPを比較
19current_ip=`curl -s ifconfig.io`
20if [ $current_ip = $ip_list[-1] ]; then
21 echo "$DATA No chane in global IP."
22 exit
23fi
24
25# SlackにcURLで新IPをPOST
26message="<!channel>%20$current_ip"
27post_url="https://slack.com/api/chat.postMessage?token=${TOKEN}&channel=${CHANNEL}&text=${message}&pretty=1"
28result=`curl -s $post_url`
29if [ `echo $result | jq ".ok"` = "false" ]; then
30 echo "$DATA `echo $result | jq ".error"`"
31 exit
32fi
33
34# 新IPをCSVの最後列に書き込み
35current_date=`date '+%Y/%m/%d(%w)'`
36echo -n "\n$current_ip,$current_date" >> $FILENAME
37echo "$DATA ADD new global IP to list."
IP のリストを格納する CSV
1ip,date
2***.***.***.***,2020/05/19(1)
crontab に スクリプト登録
作成した Shell を crontab に登録して自動化はおおむね完了。
1# exampleはお使いのpathに変更
200 11 * * * /example/monitor.sh >> /example/info.log 2>&1
おわりに
久々に Shell を書きましたが、癖があるなと感じて辛かったです。ですが、Linux 環境であればどこでも展開できますし、共通言語としてはアルファベットレベルで基礎だなと予め実感しています。
また、実は今回作成したスクリプトは常用の MacBook に cron 登録しています。なので、Mac を閉じている間は cron が動かないので本当の意味での自動化には達していません。Raspberry Pi に載せてサーバ化したいのですが、コストが見合っていないと判断して止まっています。
まぁ、昨今のステイホームも合わさってスマートホーム化を久々にやりたいなと思っていますが、クラウドに比べてオンプレは何かと時間が掛かったりするので少し構えてしまいます。