Developers IOで発生したブログ障害について(2022年12月2日PM発生)
re:Invemt2022の re:Play 開催中、 2022年12月2日 13:15 ~17:30 (日本時間) に発生していた、DevelopersIOのブログ障害について共有させていただきます。
公式ツイート
【お知らせ】現在 #DevelopersIO の記事ページの表示不具合が発生し、現在確認・修正を進めております。ご迷惑おかけしますが今しばらくお待ちください
— クラスメソッド (@classmethod) December 2, 2022
事象内容
- 個別記事、記事一覧ページを有効でURLで開くと、「404」案内ページが表示される状態でした。
正常応答率の変化
対応時系列(JST)
- 13:15 障害発生
- 13:30 社内報告をうけ、調査に着手
- 15:00 Lambda関数で発生していたエラーを特定
- 15:30 実行環境交換、 キャッシュクリア
- 16:45 エラー回避のパッチ完成
- 17:15 パッチを評価後、デプロイ
- 17:30 復旧確認
原因
不要な Authorization ヘッダー
WordPress をヘッドレスCMSとして 公開済みの記事データを参照、HTMLを生成する SSR (Server Side Rendering)用の Lambda関数で、 不要な Authorization ヘッダーが付与されていました。
export const getPost### = async (slug: string) => { const response = await axiosInstance.get<Post[]>(`${endpoint}`, { auth: config.auth })
当設定は、SSR利用の初期段階で、Basic認証で保護された検証環境を利用するためのものでした。
WordPressのアプリケーションパスワード設定
正規CMS利用者(執筆者)が、自身の権限で WordPress APIを実行する事を意図して、アプリケーションパスワード が新規に登録されました。
アプリケーションパスワードを設定したユーザーが存在しない WordPress は、 無効な Authorization ヘッダー が リクエストヘッダー に含まれている場合でも、認証を必須としない WordPress のAPIを利用可能でした。
- アプリケーションパスワード設定前
$ curl -u user:password https://example.com/wp-json/wp/v2/statuses/ -s | jq . { "publish": { "name": "公開済み", "public": true, "queryable": true, "slug": "publish", "date_floating": false, "_links": { "archives": [ { "href": "https://example.com/wp-json/wp/v2/posts" } ] } } }
アプリケーションパスワードが設定後のWordPress は、 リクエストヘッダーに Authorization ヘッダーが存在する場合、その値を評価する様になり、 認証エラー(401)が発生するようになりました。
- アプリケーションパスワード設定後
$ curl -u user:password https://example.com/wp-json/wp/v2/statuses/ -s | jq . { "code": "invalid_username", "message": "<strong>エラー</strong>: 不明なユーザー名です。もう一度確認するか、メールアドレスを入力してください。", "data": { "status": 401 } }
対策
今回、暫定対策として、以下を行いました。
- Lambda関数の修正。 無効な Authorization ヘッダーの付与撤去。
- 認証失敗により生成されたネガティブキャッシュデータの削除
まとめ
想定外の障害でしたが、社内各方面からの支援により半日程度で復旧ができました。 ご協力頂いた方々、この場を借りてお礼させていただきます。
今回明らかになった各種テスト不足や、エラーハンドリングなどの課題については、逐次改善を図りたいと思います。
根本対策としては、類似の障害が発生した場合でもサービス影響を極小化できる仕組みの実現。 Amazon S3を筆頭とする非機能要件に優れたサービス、より疎結合に活用する方向で検討を進めていきたいと思います。