CIS (Cloudflare) の送信元アドレス情報について下記URLで公開されています。
CIS allowlisted IP addresses
https://cloud.ibm.com/docs/cis?topic=cis-cis-allowlisted-ip-addresses
今回はその変更を検知するスクリプト(bash)例を紹介します。
CISの送信元アドレスの変更頻度は少ないことが想定されますが、JSONで公開されているリストは、
下記記事作成時に取得された時点 と 本日(2023/04/27)時点 では若干の差分があるようです。
IBM Cloud Internet Services (CIS) の IP に対して Security Group を Shell で作成する
https://qiita.com/khayama/items/a6fd605cc0247be409e4
CIS の 送信元IP アドレス
$ curl https://api.cis.cloud.ibm.com/v1/ips -s | jq -r .result
{
"ipv4_cidrs": [
"173.245.48.0/20",
"103.21.244.0/22",
"103.22.200.0/22",
"103.31.4.0/22",
"141.101.64.0/18",
"108.162.192.0/18",
"190.93.240.0/20",
"188.114.96.0/20",
"197.234.240.0/22",
"198.41.128.0/17",
"162.158.0.0/15",
"104.16.0.0/13",
"104.24.0.0/14",
"172.64.0.0/13",
"131.0.72.0/22"
],
"ipv6_cidrs": [
"2400:cb00::/32",
"2606:4700::/32",
"2803:f800::/32",
"2405:b500::/32",
"2405:8100::/32",
"2a06:98c0::/29",
"2c0f:f248::/32"
],
"etag": "38f79d050aa027e3be3865e495dcc9bc"
}
CIS の 送信元IP アドレス変更を検知するスクリプト
#!/bin/bash
echo "`date +%Y%m%d_%H:%M:%S` cis-ips.sh start"
CISIPS_URL="https://api.cis.cloud.ibm.com/v1/ips"
CISIPS_TMP=`date +%Y%m%d_%H%M`.json
TIMEOUT="20" # second
curl -w "status_code:%{http_code}\ntime_total:%{time_total}\n" $CISIPS_URL -o $CISIPS_TMP -s > curl-status
STATUS_CODE=`grep status_code curl-status | cut -d ':' -f 2`
TIME_TOTAL=`grep time_total curl-status | cut -d ':' -f 2 | cut -d '.' -f 1`
if [ $STATUS_CODE != 200 ] ; then
echo "HTTP Status Code was $STATUS_CODE."
exit 1
fi
if [ $TIME_TOTAL -gt $TIMEOUT ] ; then
echo "Total time exceeded 20 seconds."
exit 1
fi
if [ ! -e cis-ips.json ] ; then
cp $CISIPS_TMP cis-ips.json
fi
if diff -q $CISIPS_TMP cis-ips.json ; then
# echo "There is no difference."
rm $CISIPS_TMP
else
echo "There is a difference. CIS IPS has been changed."
mv cis-ips.json cis-ips_$CISIPS_TMP
mv $CISIPS_TMP cis-ips.json
fi
echo "`date +%Y%m%d_%H:%M:%S` cis-ips.sh stop"
既存のIPアドレスリスト と ダウンロードしたリスト の差分を検知した場合に、
スクリプトを動作させる監視サーバー側でAleartを上げる設定を追加する必要がある
(上記スクリプト例では、There is no difference.
のメッセージが表示されるのみ)
スクリプトの実行結果
$ sh cis-ips.sh
20230427_15:15:42 cis-ips.sh start
20230427_15:15:47 cis-ips.sh stop
$ sh cis-ips.sh
cis-ips.sh start
Files YYYYmmdd_HHMM.json and cis-ips.json differ
There is a difference. CIS IPS has been changed.
cis-ips.sh stop
スクリプトの定期実行
上記スクリプトをcron等で1週間毎に稼働し、CISの送信元アドレス変更を検知する
# chmod +x cis-ips.sh
# ls -al
total 10
drwxr-xr-x. 2 root root 1024 Apr 27 15:58 .
drwxr-xr-x. 6 root root 1024 Apr 27 14:17 ..
-rw-r--r--. 1 root root 505 Apr 26 20:40 cis-ips.json
-rwxr-xr-x. 1 root root 871 Apr 27 13:19 cis-ips.sh
-rw-r--r--. 1 root root 33 Apr 27 15:58 curl-status
# crontab -e
crontab: installing new crontab
# crontab -l
MAILTO=""
1-59/10 * * * * /usr/bin/diskmonitor
0 */4 * * * /usr/bin/diskwearoutstat
29 22 * * * /usr/bin/updatecheck -a
29 22 24 * * /usr/bin/phonehome_upload
0 */6 * * * /usr/bin/coreexpiration
8 * * * * /usr/bin/copy_rrd save
0 1 * * 7 /home/cis/cis-ips.sh
CISが応答しない場合のエラー処理
CISの送信元IPアドレスリストのURLに何度かアクセスした際に、下記エラー画面が応答された場合があった。
curlコマンドのオプションで、HTTP Status Codeや処理時間を取得することが可能であるため、
エラー処理を実装する。
curl -w "status_code:%{http_code}\ntime_total:%{time_total}\n"
CISからHTTP Status Code 200が応答されなかった場合 は処理を終了する
STATUS_CODE=`grep status_code curl-status | cut -d ':' -f 2`
# curl-statusファイルの中のstatus_codeの行より、「:」区切りの2つ目を抽出
# status_code:200 ⇒ 200 が抽出される
if [ $STATUS_CODE != 200 ] ; then
echo "HTTP Status Code was $STATUS_CODE."
exit 1
fi
処理時間が設定閾値を超えた場合 は処理を終了する
TIMEOUT="20" # second
TIME_TOTAL=`grep time_total curl-status | cut -d ':' -f 2 | cut -d '.' -f 1`
# curl-statusファイルの中のtime_totalの行より、「:」区切りの2つ目、「.」区切りの1つ目を抽出
# time_total:5.066900 ⇒ 5 が抽出される
if [ $TIME_TOTAL -gt $TIMEOUT ] ; then
echo "Total time exceeded 20 seconds."
exit 1
fi
参考URL
IBM Cloud Internet Services (CIS) の IP に対して Security Group を Shell で作成する
https://qiita.com/khayama/items/a6fd605cc0247be409e4
curlでパフォーマンス測定
https://dev.classmethod.jp/articles/curl-benchmark/
【Linux】crontabの設定方法を解説!定期的にジョブを実行させる方法とは?
https://engineer-ninaritai.com/linux-crontab/