茜の鯖缶日誌

SSL/TLSサーバ証明書の期限切れについて

Author Avatar
hota 5月 12, 2019

2019-05-12 4時頃から14時過ぎ(JST)にかけての約10時間、 mstdn.maud.io が使用していたSSL/TLSサーバ証明書(以下、「SSL証明書」)の有効期限が切れていたため、正常にアクセスできない状態にありました。現在、問題は解消しています。

原因と事象

  • 2019-05-12 04:00 JST を有効期限とするSSL証明書が使用されたまま当該時刻を迎えたことによる問題です。
  • 多くのブラウザ/連合先サーバ/アプリケーションでは有効期限の切れたSSL証明書について、信頼性を確認できないものとして扱い、警告を表示して接続を取りやめます。
    • この際、ユーザはこのような警告を無視すべきでは ありません
    • 一部のサードパーティ製Mastodonクライアントでは警告なく利用を継続できたという報告があります。
      • その間、連合先のサーバとは通信できないのでたぶんローカルタイムライン以外は時が止まってたと思うんですが、それはそれとして安全上よろしくないのでは…

SSL証明書について

  • このサーバでは Let’s Encrypt にて発行されるSSL証明書を使用しており、週に一度、有効期限が30日を切ったSSL証明書について更新を行うように cron で設定していました。
    • また、有効期限が30日を切ったSSL証明書については10日ごとに Let’s Encrypt Expiry Bot によるメール通知が発行時に指定したメールアドレスに対して行われます。
      • 今回、これを通知するメールは一切届いていませんでした。
    • 問題発生前の最新の証明書はこの自動更新によって 2019-04-13 に発行されており、有効期限は 2019-07-12 のはずでした。
      • このサーバに対して発行された全ての証明書は変更履歴の公開を義務付けられている(ここで説明すると長くなるので省略しますが、興味がある方は Certificate Transparency について調べてください)ため、 ここ などからそのログを探すことができます。
  • crontab には letsencrypt certonly --webroot -w /path/to/mastodon/public -d mstdn.maud.io && systemctl restart nginx のように記述されており、過去1年以上にわたって更新の反映は問題なく行われていました。
    • だいぶ前に書いたものなので、より簡単な --nginx オプションでなく --webroot を使ったままでしたが、発行は行われていたのでこれ自体は原因ではないでしょう。
  • 結局、何らかの原因で発行された最新の証明書が正しくロードされずに古い方の証明書の有効期限に至った、というのが実際のところです。

解決策

サービス再開

  • たぶん nginx -s reload でも直ってたかもしれないんですが、一応証明書を再発行しました。
  • より便利な DNS-01 方式と、Cloudflareプラグインを用いたTXTレコードの更新と承認の自動化を採用します。
certbot renew --dns-cloudflare --dns-cloudflare-credentials /path/to/cloudflare.ini --force-renewal --dry-run
  • ドキュメントは certbot-dns-cloudflare にあって、Cloudflareのログイン情報(メールアドレスとアクセストークン)を書いて読ませると次回以降は普通に certbot renew だけでよい。今回は既に発行された証明書があるので止められるんですが、--force-renewal でそれを無視して再発行します。
  • --dry-run オプションをつけて問題がないことを確認できたら、オプションは外して実際に発行します。
  • 発行できたら nginx -s reload でおわり。

再発防止策

  • MackerelURL外形監視 ではSSL証明書の有効期限を監視し、残り日数に応じてアラートを発報できる…っぽいんですが、有償プランのみだったので諦めました。個人が1台から使うには高い……
    • 直接は関係ないけれど、無料プランで見られるメトリックが直近24時間までなの、もうちょっと長い目で見たい項目がいくらかあり、監視についてそろそろ様々な方向を検討すべきかなあ……と思ってた矢先のできごとだったので個人的にはだいぶ堪えましたね……
  • さくらのクラウド のシンプル監視にも SSL証明書有効期限アラート機能 があって、こちらは監視対象のドメイン1つにつき 月額21円 (日額1円)から利用できるようなので、今回はこちらを採用しました。
    • アカウントの登録メールアドレスのほかに、Slack/Discordチャンネルへの通知を有効にしました
    • 有効残日数のしきい値は 21日 (週一での自動更新が正しく反映まで行われていれば最短で30日切った時点から遅くとも23日前には更新が走っているはずなので…)に設定してみました。
  • これでいきなり証明書の有効期限が切れていた…という今回のような事象は防げるはずです。

さいごに

今回の問題で長時間にわたりサービスが事実上停止したこと、再開後もしばらく再取得に伴いタイムラインの時系列が適切でなかったり、連合先サーバでの再試行が増加するなど、少なくない影響が発生したことをここにお詫びします。前述した再発防止策などを元に、安定したサービス提供に努めます。

話は変わって当ブログの次回予告ですが、この前日にようやくサービス開始以来2年強のメディアファイルを引っさげて無事にオブジェクトストレージへの移行を完了させたので、なんかその話を書くつもりです。