2019-05-12 4時頃から14時過ぎ(JST)にかけての約10時間、 mstdn.maud.io が使用していたSSL/TLSサーバ証明書(以下、「SSL証明書」)の有効期限が切れていたため、正常にアクセスできない状態にありました。現在、問題は解消しています。
原因と事象
2019-05-12 04:00 JST
を有効期限とするSSL証明書が使用されたまま当該時刻を迎えたことによる問題です。- 多くのブラウザ/連合先サーバ/アプリケーションでは有効期限の切れたSSL証明書について、信頼性を確認できないものとして扱い、警告を表示して接続を取りやめます。
- この際、ユーザはこのような警告を無視すべきでは ありません 。
- 一部のサードパーティ製Mastodonクライアントでは警告なく利用を継続できたという報告があります。
- その間、連合先のサーバとは通信できないのでたぶんローカルタイムライン以外は時が止まってたと思うんですが、それはそれとして安全上よろしくないのでは…
- 追記: Android版Tootdonで利用を継続できていた件について、報告・対策が行われたようです
SSL証明書について
- このサーバでは Let’s Encrypt にて発行されるSSL証明書を使用しており、週に一度、有効期限が30日を切ったSSL証明書について更新を行うように
cron
で設定していました。- また、有効期限が30日を切ったSSL証明書については10日ごとに Let’s Encrypt Expiry Bot によるメール通知が発行時に指定したメールアドレスに対して行われます。
- 今回、これを通知するメールは一切届いていませんでした。
- 問題発生前の最新の証明書はこの自動更新によって
2019-04-13
に発行されており、有効期限は2019-07-12
のはずでした。- このサーバに対して発行された全ての証明書は変更履歴の公開を義務付けられている(ここで説明すると長くなるので省略しますが、興味がある方は Certificate Transparency について調べてください)ため、 ここ などからそのログを探すことができます。
- また、有効期限が30日を切ったSSL証明書については10日ごとに Let’s Encrypt Expiry Bot によるメール通知が発行時に指定したメールアドレスに対して行われます。
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
でおわり。
再発防止策
- Mackerel の URL外形監視 ではSSL証明書の有効期限を監視し、残り日数に応じてアラートを発報できる…っぽいんですが、有償プランのみだったので諦めました。個人が1台から使うには高い……
- 直接は関係ないけれど、無料プランで見られるメトリックが直近24時間までなの、もうちょっと長い目で見たい項目がいくらかあり、監視についてそろそろ様々な方向を検討すべきかなあ……と思ってた矢先のできごとだったので個人的にはだいぶ堪えましたね……
- さくらのクラウド のシンプル監視にも SSL証明書有効期限アラート機能 があって、こちらは監視対象のドメイン1つにつき 月額21円 (日額1円)から利用できるようなので、今回はこちらを採用しました。
- アカウントの登録メールアドレスのほかに、Slack/Discordチャンネルへの通知を有効にしました
- 有効残日数のしきい値は 21日 (週一での自動更新が正しく反映まで行われていれば最短で30日切った時点から遅くとも23日前には更新が走っているはずなので…)に設定してみました。
- これでいきなり証明書の有効期限が切れていた…という今回のような事象は防げるはずです。
さいごに
今回の問題で長時間にわたりサービスが事実上停止したこと、再開後もしばらく再取得に伴いタイムラインの時系列が適切でなかったり、連合先サーバでの再試行が増加するなど、少なくない影響が発生したことをここにお詫びします。前述した再発防止策などを元に、安定したサービス提供に努めます。
話は変わって当ブログの次回予告ですが、この前日にようやくサービス開始以来2年強のメディアファイルを引っさげて無事にオブジェクトストレージへの移行を完了させたので、なんかその話を書くつもりです。