LoginSignup
5
4

More than 5 years have passed since last update.

AWS LambdaにSSL証明書の有効期限を確認して通知するSlackボットを作成した

Last updated at Posted at 2017-06-07

はじめに

現在、私がプライベートで持っているサーバのSSL証明書は Let's Encrypt で設定します。
Let's Encrypt は証明書の期限についてはメールでお知らせしてくれますが、メールだと他のメールと埋もれて確認漏れが起こっていたりしていました。

自動で更新したらええやん! というようなご指摘はあるかと思いますが、今回はそれは無視で

環境

ローカル

  • Python 3.6
  • macOS Sierra 10.12.4

AWS

  • Lambda
    • Python 3.6
  • CloudWatch

リポジトリ

準備

Apps & integrationsBots を設定しておいてください

Bots___ひやかしプロジェクト_Slack.png

ライブラリ

requirements.txt
appdirs==1.4.3
packaging==16.8
pyparsing==2.2.0
requests==2.13.0
six==1.10.0
slacker==0.9.42

サンプルソース

bot.py
from slacker import Slacker
import datetime
import socket
import ssl
import slack_settings # 同ディレクトリに slack_settings.py を配置


slack = Slacker(slack_settings.SLACK_API_TOKEN)


def ssl_valid_time_remaining(hostname):
    expires = ssl_expiry_datetime(hostname)
    return expires - datetime.datetime.utcnow()


def ssl_expires_in(hostname, buffer_days=7):  # 7日前で期限分岐
    remaining = ssl_valid_time_remaining(hostname)
    if remaining < datetime.timedelta(days=0):
        raise AlreadyExpired("Cert expired %s days ago" % remaining.days)
    elif remaining < datetime.timedelta(days=buffer_days):
        return True
    else:
        return False


def ssl_expiry_datetime(hostname):
    ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'
    context = ssl.create_default_context()

    conn = context.wrap_socket(
            socket.socket(socket.AF_INET),
            server_hostname=hostname,
    )

    conn.settimeout(3.0)
    conn.connect((hostname, 443))
    ssl_info = conn.getpeercert()
    return datetime.datetime.strptime(ssl_info['notAfter'], ssl_date_fmt)  # ssl_info['notAfter'] が証明書の期限


def post_slack(hostname):
    message = '@channel https://' + hostname + ' '
    if ssl_expires_in(hostname):
        message += 'そろそろヤバイ'
    else:
        message += 'はまだ期限内' 

    # ここら辺のメソッドはslackerパッケージを使用
    slack.chat.post_message(
            '#expiration',
            message,
            as_user=True,
            link_names=True
    )


def execute(event, context):
    post_slack('<YOUR DOMAIN>')
slack_setting.py
SLACK_API_TOKEN = ''

ローカルで実行

$ python bot.py

スクリーンショット_2017-06-07_17_21_48.png

今回もまた 渡辺曜 さんにお知らせ係を担当していただきました。

Lambdaの設定

Lambda_Management_Console.png

  1. トリガーの設定 Lambda_Management_Console.png 各自好きなように設定。自分は cron で月〜金のAM2時に通知される設定を選択しています。
  2. 関数の名前は適当に入力
  3. ランタイムPython 3.6 を選択
  4. ソースコードアップロードは下で説明
  5. ハンドラbot.execute を入力
  6. ロール等は各自設定

外部ライブラリの反映

ローカル環境では以下コマンド等でなんとかなりますが、

ローカル環境
$ pip install -r requirements.txt

AWS Lambda上ではライブラリが認識されないので外部ライブラリごとアップロードする必要があります。

外部ライブラリをプロジェクトディレクトリに保存
$ pip install <LIBRARY_NAME> -t .

という感じにやればプロジェクトディレクトリに保存されます。
しかし、1つ1つやるのが面倒なので私は以下でしました。

$ pip freeze > requirements.txt  # requirements.txt がなければ
$ pip install -r requirements.txt -t .

あとはzipに圧縮してアップロードする

$ zip -r bot.zip *  # bot.zip は好きな名前

プロジェクトディレクトリに bot.zip ができているので .ZIPファイルをアップロード を選択して bot.zip をアップロードする

スクリーンショット 2017-06-07 17.41.57.png

うまく設定できれいれば設定した時間にSlackに通知がくるはず!
私の環境では先述通り 月〜金 AM2時 に渡辺曜さんがお知らせしてくれます!!

5
4
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
5
4