経緯
- Python パッケージ https://github.com/scrapinghub/slackbot を使って、EC2インスタンス上でSlackのチャットボットを起動し利用していました。
- しかし、2023年3月14日の夜あたりから、突然
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1125)
というエラーを出し起動しなくなってしまいました。 - Slack が https://status.slack.com/2023-03/9011b8a984a74042 のとおり Incident を報告してくれていますが、解決策はこの記事を書いている現時点(3月18日0時)では提供されていませんでした。
-
SSL: CERTIFICATE_VERIFY_FAILED
に関してウェブ上で調べて、再び動くようにすることができたので、その方法を共有します。
解決策
WEBSOCKET_CLIENT_CA_BUNDLE=$(python -c "import ssl;print(ssl.get_default_verify_paths().openssl_cafile)")
のように環境変数に設定した上でSlackbotを起動させれば、エラーがなくなりました。
なぜこれで起動するようになるのか?
- slackbot は内部で https://github.com/websocket-client/websocket-client を利用している
- websocket-client は独自のルート証明書をバンドルして提供しているらしい(参考)
- 3月14日頃にSlack側でSSL証明書の更新が行われ、何らかの理由によりそれが websocket-clientがバンドルしている独自のルート証明書では検証できなくなったのではないか?
-
python -c "import ssl;print(ssl.get_default_verify_paths().openssl_cafile)"
を実行すると、サーバーのOpenSSLにハードコードされたcafileのパスを取得することができる - それを
WEBSOCKET_CLIENT_CA_BUNDLE
に指定することで、 websocket-client が(独自のルート証明書ではなく)OpenSSLのcafileを見るようになる - OpenSSLの方ではSlackのSSL証明書の検証に成功するのでこれで解決する
ということだと思っています(たぶん)
上記解決策に至るまでにやっていたこと
(もしかしたらこの作業も影響しているのかもしれないので、念のため共有しておきます)
- slackbotのバージョンを1.0.4から最新の1.0.5にアップデート
-
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-expired-certificate/ を参考に
sudo yum update ca-certificates
を実行してCA証明書を更新(その後念のためreboot実施)