MX レコードの切り替えを監視して通知する

### はじめに

この記事はシスコシステムズ合同会社の有志による Advent Calendar 2021 (2枚目) の 10 日目として投稿しています。
🎄今年のカレンダーはこちら
https://qiita.com/advent-calendar/2021/cisco
https://qiita.com/advent-calendar/2021/cisco2

🎅過去のカレンダーはこちら
https://qiita.com/advent-calendar/2017/cisco
https://qiita.com/advent-calendar/2018/cisco
https://qiita.com/advent-calendar/2019/cisco
https://qiita.com/advent-calendar/2020/cisco
https://qiita.com/advent-calendar/2020/cisco2

### この記事でお伝えすること

あるドメインの MX レコードが更新されたら Mac の通知センターにお知らせするスクリプトを作成したのでサンプルを共有します。ちょっと応用して Webex Teams にも通知してみます。

### 背景

昨年から今年にかけて、[メールセキュリティゲートウェイ製品](https://www.cisco.com/c/ja_jp/products/security/email-security/index.html)の設計/導入支援の案件に携わる機会が多かったのですが、一番大変だったことが海外のお客様の MX レコード切り替え時の待機業務[^1]でした。

メールセキュリティ製品の移行時にほぼ必ず発生する[^2] MX レコードの切り替え作業はお客様管理の DNS サーバで実施されるため、ベンダーとしてはなかなかタイミングがわかりません。海外のお客様[^3]であれば日本時間では夜間や早朝、もしかすると休日になってしまうこともあります[^4]。

[^1]: 弊社は待機時間中もお賃金が出ます。もちろん基本フルリモートです。
[^2]: [Cisco Cloud Mailbox Defense (CMD)](https://www.cisco.com/c/ja_jp/products/security/cloud-mailbox-defense/index.html#~stickynav=1) は煩わしい MX レコード変更作業は不要、メールフローを変更せずに導入可能な新しいメールセキュリティソリューションです。
[^3]: 弊社は海外のお客様とも働く機会の多いグローバルで刺激のある職場です。
[^4]: 弊社は法定時間外労働や法定休日労働が発生した場合割増賃金が発生します。

切り替えが発生したタイミング、その後の正常性の確認や問題の確認をなるべくリアルタイムに実施できれば、落ち着いて業務をこなせるとともに、夜間や早朝といった貴重な時間を有意義に過ごすことができそうです🍵

### MX レコードとは

[JPRS さんの記事](https://jprs.jp/glossary/index.php?ID=0163
)がわかりやすいです。一言で言うと DNS レコードのうち、メール交換 (mail exchange) のためのリソースタイプです。
>mail exchange（メールサーバー、メールを配送するホスト）を指定するためのリソースレコードです。
MXリソースレコードの特徴として、配送における優先度を指定する「プリファレンス（preference）」があり、「配送先ホスト」ごとに指定されます。プリファレンスによる優先度は数字で示され、配送先が複数ある場合には、より小さなプリファレンスを持つホストが優先されます。これにより、配送するメールサーバーの優先度を指定でき、メールサービスの可用性向上が期待できます。

### 環境
macOS 11
python 3.10

### MX レコードをクエリするスクリプト
```query-mx.sh
echo "example.com" 
mx=$(dig example.com mx +short)
echo ${mx}
```

#### スクリプトの結果の例

```Office365利用中の例.
10 company-com.mail.protection.outlook.com.
```


```弊社のクラウド型メールセキュリティをご利用の場合の例.
10 mx1.hcXXX-XXX.ap.iphmx.com.
20 mx2.hcXXX-XXX.ap.iphmx.com.
```

検知のスクリプトではこの変化を単純に追いかけます。
余談ですが、お客様の MX レコードの情報からいまご利用のメールセキュリティ製品を推測することができます。

### 更新検知&通知のスクリプト
cron で `query-mx-diff.sh` を登録しておき、直近の結果と比較して差分を検知する仕組みです。

```query-mx-diff.sh
#!/bin/bash

date=`date +%s`
sh query-mx.sh > result-$date
if [ -e result-prev ]; then
        cmp result-prev result-$date > diff-$date
        FILESIZE=$(wc -c diff-$date | awk '{print $1}')
        echo $FILESIZE
        if [ $FILESIZE -gt 0 ]; then 
                osascript -e 'display notification "MX Record Changed" with title "ALERT"'
                echo  "* DIFF RESULT *"
                cat diff-$date
                echo
        fi
fi
echo  "* LATEST RESULT *"
cat  result-$date
ln -sf result-$date result-prev
```

#### 通知結果のイメージ

地味です。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437531/f302cde0-5365-4cdb-fa5b-6807a2532e37.png">

### 応用

```
osascript -e 'display notification "MX Record Changed" with title "ALERT"'
```
ここ↑のアクションを変えることで Slack や LINE や Webex Teams へ通知したりといった応用が可能です。

#### 応用例：Webex Teams に投稿する場合

```
python3 post_teams.py
```
みたいに書きます。`post_teams.py` の中身の例は以下です。

```post_teams.py
from requests_toolbelt import MultipartEncoder
import requests

filepath = '/Users/urikura/cat.png'
filetype = 'image/png'
roomId = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
token = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
url = 'https://api.ciscospark.com/v1/messages'

my_fields = {'roomId': roomId,
'text': 'MX レコードが切り替わりました',
'files': ('file.png', open(filepath, 'rb'), filetype)}
m = MultipartEncoder(fields=my_fields)
r = requests.post(url, data=m,
headers={'Content-Type': m.content_type,
'Authorization': 'Bearer ' + token})
```

#### 応用例：Webex Teams 投稿の例

できました😺
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437531/b04697ae-9d83-2ab4-6694-d500eddfec2e.png">

### 最後に

現在シスコシステムズ合同会社ではさまざまな職種で採用中です。
身近な弊社社員までお気軽にお声掛けください🙏
https://jobs.cisco.com/jobs/SearchJobs/?3_109_3=%5B%22214429%22%5D
https://ciscocareers.dejobs.org/jpn/jobs/

### 参照
Mac の通知方法
https://code-maven.com/display-notification-from-the-mac-command-line
Diff の定期モニタリング方法
https://nmap.org/book/ndiff-man-periodic.html
Cisco Webex Teams(旧Cisco Spark)のBot用アカウントの作り方
https://qiita.com/thrzn41/items/672870bb8a6ab2ca44b2