🐟

Mackerelで自宅のグローバルIPが変わるのを監視する方法 (1)

5 min read

このエントリは @sogaoh の Mackerel Ambassador としての記事 その9です。
(一覧は こちら

自宅のグローバルIP、けっこう頻繁に変わりませんか?自分はここ2ヶ月で2回変わりました。その前はかなり安定的に変わらずだったのですが。
そういうものだとわかってはいても、そのときに対応が必要なことがいくつかあって、後手に回るのが嫌なので、グローバルIPが変わったことを検知するようにして運用を始めました。
この記事ではその手法をご紹介したいと思います。

基本となるスクリプト

メトリクスとして持たせるには数値化しないとだよな、と考えて、「IPアドレス 数値化」で検索などしました。
とりあえず数値化さえできればよかったので、いくつか見つけた中の2つの情報 [1] をベースに以下3つのスクリプトを作りました。

[スクリプト在中] 1つ目が数値化、2つ目がIPアドレスに戻す、3つ目が一体型(検算用)、です。
ip2int.sh

#!/bin/bash
LANG=C
PATH=/bin:/usr/bin
if [ $# -ne 1 ]
then
  echo "Usage: $0 [IPAddress]"
  exit 1
fi
O1=$( awk -F\. '{printf"%d",$1}' <<< "$1" )
O2=$( awk -F\. '{printf"%d",$2}' <<< "$1" )
O3=$( awk -F\. '{printf"%d",$3}' <<< "$1" )
O4=$( awk -F\. '{printf"%d",$4}' <<< "$1" )
echo "$(( ( ${O1} << 24 ) + ( ${O2} << 16 ) + ( ${O3} << 8 ) + ${O4} ))"
int2ip.sh

#!/bin/bash
LANG=C
PATH=/bin:/usr/bin
if [ $# -ne 1 ]
then
  echo "Usage: $0 [Int (<- IPAddress)]"
  exit 1
fi

echo "$(($1>>24)).$(($1>>16&255)).$(($1>>8&255)).$(($1&255))"
_ip2int2ip.sh

#!/bin/bash

IP_INT=$(./ip2int.sh $(curl -s ifconfig.io))
echo $IP_INT
./int2ip.sh $IP_INT

この節で伝えたいことの1つが、3つ目のスクリプトにさりげなく登場しているのですが、 curl -s ifconfig.io でグローバルIPが取れる、ということです。他にもグローバルIPを確認するサイトがちらほらありますが、CLI でこのコマンドを打つか、ブラウザで ifconfig.io をリクエストするか、が手早いと思っています。

スクリプトを定期実行させる仕組み

やってみるとわかるのですが、わかりにくいとは思うものの、IPアドレスの数値化ができたので、これを Mackerel のサービスメトリックとして投稿するように、スクリプトに少し手を加えます。

[スクリプト在中] IPアドレスを数値化してメトリック投稿する用
ip2metric.sh

#!/bin/bash
LANG=C
PATH=/bin:/usr/bin
#if [ $# -ne 1 ]
#then
#  echo "Usage: $0 [IPAddress]"
#  exit 1
#fi

IP=$(curl -s ifconfig.io)

O1=$( awk -F\. '{printf"%d",$1}' <<< "$IP" )
O2=$( awk -F\. '{printf"%d",$2}' <<< "$IP" )
O3=$( awk -F\. '{printf"%d",$3}' <<< "$IP" )
O4=$( awk -F\. '{printf"%d",$4}' <<< "$IP" )
#echo "$(( ( ${O1} << 24 ) + ( ${O2} << 16 ) + ( ${O3} << 8 ) + ${O4} ))"

VALUE="$(( ( ${O1} << 24 ) + ( ${O2} << 16 ) + ( ${O3} << 8 ) + ${O4} ))"
SECONDS=`date '+%s'`
NAME='global_ip.ip2int'

echo -e "${NAME}\t${VALUE}\t${SECONDS}"

これを定期実行する方法はいろいろあると思うのですが、自宅にすでにあって稼働している手法を利用することにしました。sardine を利用して Mackerel のサービスメトリック化する方法です。[2]
スクリプトを配置して、config にそのスクリプトを定期的に叩く設定を追記して、systemctl restart sardine-agent すれば・・・期待通りIPアドレスの採取が始まりました。


global_ip-ip2int

なお、スクリプトと設定の設置は先日手動で済んでいますが、Ansible で再セットアップする可能性を見込んで、既存の Playbook にこの機構のスクリプトと設定を追加しておきました。[3]

https://github.com/sogaoh/mackerel-practice/tree/master/raspi-01

変わったことを通知する方法 (1)

メトリックとして投稿ができたら、次はグローバルIPが変わったことの検知と通知を仕込みます。
数値化したIPが変わったことがわかればいいので、値の変化をつかまえて通知すれば良いわけです。・・・とここで1つ困ったことがわかりました。。閾値条件の不等号の向きを逆にはできないのです。一瞬頭を抱えましたが、IPアドレスを int に変換したが現状より大きくなった場合は critical、小さくなった場合は warning で通知するように設定することで自己解決(?)しました。

検知テストの足跡

また、こうしているうちに(?)、公式の terraform-provider-mackerel がリリースされたので、設定をコード化しておこうと思いドキュメントを見たところ、素晴らしいことに import できるようでした。

https://registry.terraform.io/providers/mackerelio-labs/mackerel/latest/docs/resources/monitor#import

そうして import しつつ、コード化しておいたのがこちらになります。

https://github.com/sogaoh/mackerel-practice/tree/master/terraform-provider/monitor/service_metric

以上、自宅のグローバルIPが変わるのを監視する (1) でした。
(2) では、チェック監視での方法を、plugin を自作してやってみたい、と思っています。

脚注
  1. IPアドレスを10進数に変換するスクリプト ip2int.sh | pooh.gr.jpbash — LinuxとOS XでローカルマシンのプライマリIPアドレスを取得する方法 ↩︎

  2. サービスメトリック投稿手段として sardine を採用 in Pubs/Mackerel Ambassador (sogaoh) blogs/RaspberryPiからSpeedtestCLIの結果をMackerelサービスメトリックに投稿する (2) - esa-pages.io ↩︎

  3. 差分のみ : https://github.com/sogaoh/mackerel-practice/commit/d959fb6b46cecd9379a539f8e0932654be5dbdc8 ↩︎