LoginSignup
1
0

IBM Cloud Code Engineを利用してCISの送信元IPアドレス変更をメール通知する

Last updated at Posted at 2023-11-17

はじめに

IBM Cloud CodeEngineを利用してCISの送信元IPアドレス変更を定期的にメール通知する方法を紹介します。

コンテナ実行環境サービスであるサーバーレスCode Engineのジョブを用いて定期実行する例です。
image.png

スクリプト(bash)で実行した例を下記記事で紹介しておりますのでご参照ください。

IBM Cloud CISの送信元IPアドレス変更を検知する
https://qiita.com/aktech/items/f6cf0a9771c26c117825

IBM Cloud Functionsを利用した例を下記記事で紹介していますが、2023/10/26 Cloud Functionsは非推奨の発表がされています。

IBM Cloud Functionsを利用してCISの送信元IPアドレス変更をSlackへ通知する
https://qiita.com/aktech/items/85334f23b4e071249ad8

IBM Cloud Functions 非推奨の概要
https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-dep-overview

主な手順

1. Code Engineにデプロイするコンテナのアクションの作成
2. GitHubへPush
3. Code Engine用のレジストリの準備
4. Code Engine プロジェクトの作成
5. Code Engine シークレットの作成
6. Code Engine ジョブの作成
7. Code Engine ジョブの実行
8. Code Engine ログ監視
9. Code Engine イベント設定(定期実行)

image.png

1. Code Engineにデプロイするコンテナのアクションの作成

今回は実行環境にPythonを利用

用意する物

・Dockerfile
・cis-ip-check.py

Dockerfile
FROM python:slim
ADD ./cis-ip-check.py /root/cis-ip-check.py
WORKDIR /root
RUN apt update
RUN pip install sdcclient
RUN pip install sendgrid
CMD ["python","/root/cis-ip-check.py"]
cis-ip-check.py
import os
import json
import requests
from requests.exceptions import Timeout
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

# Secect the value (0 = False, 1 = True)
MAIL_CUSTOM = os.getenv('MAIL_CUSTOM')
MAIL_SEND_EVERY_TIME = os.getenv('MAIL_SEND_EVERY_TIME')
MAIL_TO_ADDRESS_HIDE = os.getenv('MAIL_TO_ADDRESS_HIDE')

if MAIL_CUSTOM == "1":
   MAIL_SUBJECT = os.getenv('MAIL_SUBJECT')
   MAIL_BODY_HTML = os.getenv('MAIL_BODY_HTML')
   MAIL_BODY_TEXT = os.getenv('MAIL_BODY_TEXT')
   MAIL_SUBJECT_NOT_CHANGED = os.getenv('MAIL_SUBJECT_NOT_CHANGED')
   MAIL_BODY_HTML_NOT_CHANGED = os.getenv('MAIL_BODY_HTML_NOT_CHANGED')
   MAIL_BODY_TEXT_NOT_CHANGED = os.getenv('MAIL_BODY_TEXT_NOT_CHANGED')
else:
   MAIL_SUBJECT = "CIS IPS Changed."
   MAIL_BODY_HTML = "<strong>CIS IPS has been changed.</strong><br>Please check your access-lists."
   MAIL_BODY_TEXT = "CIS IPS has been changed.\nPlease check your access-lists.\nThis is a text mail."
   MAIL_SUBJECT_NOT_CHANGED = "CIS IPS not Changed."
   MAIL_BODY_HTML_NOT_CHANGED = "This is a user-edited mail."
   MAIL_BODY_TEXT_NOT_CHANGED = "This is a user-edited mail.\nThis is a text mail."

if MAIL_TO_ADDRESS_HIDE == "1":
   address_hide = True
else:
   address_hide = False

MAIL_ADDRESS_TO = [m.strip() for m in os.getenv('MAIL_ADDRESS_TO').split(',')]
print(MAIL_ADDRESS_TO)

print("MAIL_ADDRESS_FROM : ",os.getenv('MAIL_ADDRESS_FROM'))
print("MAIL_ADDRESS_TO : ",os.getenv('MAIL_ADDRESS_TO'))

print("MAIL_CUSTOM : ",MAIL_CUSTOM)
print("MAIL_SEND_EVERY_TIME : ",MAIL_SEND_EVERY_TIME)
print("MAIL_TO_ADDRESS_HIDE : ",MAIL_TO_ADDRESS_HIDE,address_hide)
   
message = Mail(
    from_email=os.getenv('MAIL_ADDRESS_FROM'),
    to_emails=MAIL_ADDRESS_TO,
    subject=MAIL_SUBJECT,
    html_content=MAIL_BODY_HTML,
    plain_text_content=MAIL_BODY_TEXT,
    is_multiple=address_hide)
    
message_not_changed = Mail(
    from_email=os.getenv('MAIL_ADDRESS_FROM'),
    to_emails=MAIL_ADDRESS_TO,
    subject=MAIL_SUBJECT_NOT_CHANGED,
    html_content=MAIL_BODY_HTML_NOT_CHANGED,
    plain_text_content=MAIL_BODY_TEXT_NOT_CHANGED,
    is_multiple=address_hide)

try:
  url = "https://api.cis.cloud.ibm.com/v1/ips"
  r = requests.get(url, timeout=3.0)
  
  if r.status_code != 200:
     print("status_code from cis-ips was not 200.")
  
  elif r.json()["result"]["etag"] == os.getenv('ETAG'):
     print("There is no difference.")
     if MAIL_SEND_EVERY_TIME == "1":
         sg = SendGridAPIClient(os.getenv('SENDGRID_API_KEY'))
         response = sg.send(message_not_changed)
         print(response.status_code)
         print(response.body)
         print(response.headers)
  
  else:
     print("There is difference. CIS IPS has been changed.")
     sg = SendGridAPIClient(os.getenv('SENDGRID_API_KEY'))
     response = sg.send(message)
     print(response.status_code)
     print(response.body)
     print(response.headers)
  
except Timeout:
  print("timeout.")
  pass

環境変数はCode Engineのシークレットとして登録

ジョブ動作概要

・CIS (Cloudflare) の送信元アドレス情報を公開しているURL(API)へアクセス
・応答のETAGが異なる場合は変更ありと判断
・変更がある場合にメール送付
・オプション指定(シークレット)により変更がない場合でもメール送付
・変更がある場合のメール内容はカスタマイズ可能(Subject/Bodyはシークレットに事前登録)
・変更がない場合のメール内容はカスタマイズ可能(Subject/Bodyはシークレットに事前登録)
・宛先(TO)は複数指定可能
・オプション指定(シークレット)により複数指定した場合に他アドレスを隠す
・コードの編集は行わず、Code Engine シークレット入力によりオプション変更
・URL(API)からの応答がTimeout(3秒)した場合は"timeout"という文字列をログ出力
(※Timeout時に再送したり、メール送付を希望の場合はコード修正をご検討ください)

2. GitHubへPush

上記ファイルをGitHubへpushする(手順は省略)

GitHub URLに公開(public)しています
https://github.com/akd8/ibmcloud-cis-ip-check.git

3. Code Engine用のレジストリの準備

Code Engine用にContainer Registoryの名前空間を作成する

項目 入力内容
リソースグループ rg-xxx
名前 cr-code-engine

4. Code Engine プロジェクトの作成

項目 入力内容
ロケーション 東京(jp-tok)
大阪(jp-osa)
リソースグループ rg-xxx
名前 CodeEngine

5. Code Engine シークレットの作成

プロジェクト > シークレットおよびConfigmap > 作成

image.png

項目 入力内容
タイプ シークレット
名前 cisipcheck

シークレット

キー 値(入力例) 説明
ETAG 38f79d050aa027e3be3865e495dcc9bc 最新のETAGを入力(変更があれば更新する)
SENDGRID_API_KEY Sendgridを利用するユーザのAPI KEY
API KEYの入手方法は参考URL
MAIL_ADDRESS_FROM xxx@test.com 送信元アドレスを指定(Sendgridを利用するユーザメールアドレス)
MAIL_ADDRESS_TO aaa@test.com,bbb@test.com,ccc@test.com 複数宛先を指定する場合は「,」区切りで指定
MAIL_CUSTOM 0 or 1 1の場合はシークレットに設定したSubject/Bodyを応答する
MAIL_SEND_EVERY_TIME 0 or 1 1の場合はETAGに変更がなくともメールする
MAIL_TO_ADDRESS_HIDE 0 or 1 1の場合はTOに複数指定しても送信時に他のアドレスを隠す
MAIL_SUBJECT CIS IPS Changed. メールタイトル文面
MAIL_BODY_HTML This is a user-edited mail.<br>You can edit this mail. メール文面(HTML形式)
MAIL_BODY_TEXT This is a user-edited mail.\nYou can edit this mail.\nThis is a text mail. メール文章(TEXT形式)
MAIL_SUBJECT_NOT_CHANGED CIS IPS not Changed. ETAGに変更がない場合のメールタイトル文面
MAIL_BODY_HTML_NOT_CHANGED ETAGに変更がない場合のメール文面(HTML形式)
MAIL_BODY_TEXT_NOT_CHANGED ETAGに変更がない場合のメール文章(TEXT形式)

6. Code Engine ジョブの作成

一般

項目 入力内容
名前 ce-job-cis-ip-check

実行するコードの選択

項目 入力内容
実行するコードの選択 ソース・コード
コード・リポジトリー URL https://github.com/akd8/ibmcloud-cis-ip-check.git
コード・リポジトリー・アクセス なし
ブランチ名 main
コンテキスト・ディレクトリー 指定なし(ブランク)
Dockerfile Dockerfile
タイムアウト 10m
ブランチ名 main
ビルド用のリソース 小 (0.5 vCPU / 2GB)
レジストリー・サーバー private.jp1.icr.io(IBM レジストリー東京)
もしくは、private.jp2.icr.io(IBM レジストリー大阪)
レジストリー・アクセス・シークレット ce-cisip-ras
名前空間 cr-code-engine
リポジトリー (イメージ名) codeengine-ce1.git-xx(名前は任意)
ビルド用のリソース 小 (0.5 vCPU / 2GB)

リソースおよびスケーリング

項目 入力内容
インスタンス数 1
インスタインス・リソース 0.125個のvCPU / 0.25 GB
一時ストレージ(GB) 0.4
ジョブの再試行回数 3
ジョブ・タイムアウト (秒) 7200

環境変数(オプション)

項目 入力内容
シークレット cisipcheck

上記値を入力して「作成」を実施すると、githubのコンテナ・アクション情報を元にしてコンテナイメージがレジストリに作成され、ビルドが完了する。

7. Code Engine ジョブの実行

作成したジョブ画面右上の「ジョブの実行依頼」より単発でのジョブ実行が可能

image.png

ジョブの実行依頼

項目 入力内容
インスタンスの数 1

8. Code Engine ログ監視

ジョブ画面の「ロギングの起動」より、IBM Log Analysis with LogDNA (事前に要作成) を起動する

自動的に「_platform:'Code Engine' label.Project:'CodeEngine' app:ce-job-cis-ip-check」(例)のようなフィルタリングされた画面が表示される。

Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 ['aaa@test.com', 'bbb@test.com', 'ccc@test.com']
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 MAIL_ADDRESS_FROM :  xxx@test.com
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 MAIL_ADDRESS_TO :  aaa@test.com, bbb@test.com, ccc@test.com
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 MAIL_CUSTOM :  0
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 MAIL_SEND_EVERY_TIME :  0
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 MAIL_TO_ADDRESS_HIDE :  0 False
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 There is no difference.
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 202
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 b''
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 Server: nginx
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 Date: Thu, 16 Nov 2023 04:31:15 GMT
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 Content-Length: 0
Nov 16 13:31:25 Code Engine ce-job-cis-ip-check-jobrun-12xyz-0-0 Connection: close

9. Code Engine イベント設定(定期実行)

イベント・サブスクリプションの作成

image.png

定期実行する間隔を指定する(下記は毎分の実行の例)

image.png

作成したジョブを選択する

image.png

実行されたジョブの時刻と状況(成功/失敗)は、ジョブの「ジョブ実行」タブから確認可能

参考URL

IBM Cloudのメール配信サービス(SendGrid)を使ってNode.js、Pythonからメール配信してみた!
https://qiita.com/strada/items/f4e6536b6e973b5ca2e9

Twilio SendGridとPythonでメールを一斉送信する方法
https://sendgrid.kke.co.jp/blog/?p=12510

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0