1.はじめに
SREエンジニアのkakepiです
10/25(月)に弊社の管理している全てのサーバに対してデプロイできない問題が発生いたしました。
本記事は当時の状況と、判明した原因、対応策について記載したいと思います。
AWSサービスがいくつか登場し、それらの知識が若干必要かもしれませんがご了承ください🙏
2.背景
10/25(月)の朝方アプリケーションエンジニアからデプロイできないという問い合わせがありました
その後も各方面からデプロイできないという問い合わせが相次ぐという状況でした
前提として、弊社のデプロイはJenkinsサーバからデプロイ対象のサーバに対してssh接続し、ごにょごにょするのですが
Jenkinsの実行ログを見るとssh接続ができず、エラーになっていることがわかりました(Net::SSH::AuthenticationFailed: Authentication failed)
さらに接続できていない原因を探ると接続時ユーザの公開鍵(authorized_keys)が存在していないことがわかりました。
3.原因特定
公開鍵が存在しなくなった原因を探っていきました
公開鍵はansibleの実装によって作成しています。直近公開鍵まわりのansibleの変更はなかったものの、まずはここを疑い
任意のサーバに対してansibleを実行しましたが、問題なく公開鍵は生成されていました。
次にAWSのサービス周りを疑いました
前提知識として、弊社のサーバ群はAutoscalingを利用しており、そこではLaunchTemplateを使ってImageBuilderによって生成されるAMIを指定します。
さらに、ImageBuilderによってAMIを生成する作業は毎日行なっており、バージョン管理も可能となっています。
そこで、前のバージョンのAMIを起動してみるなどを試してみると、バージョンによっては公開鍵が存在していたので
特定のバージョン以降から公開鍵が存在していないということがわかりました。
ImageBuilerを含めたAWSリソースまわりも直近変更していなかったので、
ここまでくるともうお手上げで、何らかの変更がAWS側にあったに違いないという仮説を立てて問い合わせを行い
暫定対応としてAMI起動後にもう一度公開鍵を生成するという処理を加えて一旦解決しました。
3.問い合わせ結果
数日して問い合わせ結果が返ってきました。以下原文ママ
EC2 Image Builder では最近、インスタンスで実行されるクリーンアッププロセスにいくつかの変更を加えました。
クリーンアッププロセスの一環として、サービスはすべてのユーザー (root と ec2-user 以外を含む) の ssh キーを削除するようになりました。
これは、Ubuntu、SUSE などを含むすべてのオペレーティングシステムの出力イメージのセキュリティを向上させるために行われます。
もし承認されたSSHキーを保持する必要がある場合、コンポーネントを介してワーキングディレクトリにファイルskip_cleanup_ssh_filesを作成するよう設定してください。これによってクリーンアッププロセスでは、インスタンスからのSSHキーのクリーンアップがスキップされます。
簡単にいうと、 最近の変更によって現状すべてのユーザーの authorized_keys が削除される仕様になった という回答でした。。
さらには
ご参照されているドキュメントとは現在の動作が異なっており、担当部署にてドキュメントの更新に取り組んでいる状況でございます。
とのことでした。それはわからない泣
4.対応策
対応策は問い合わせ結果に記載されていた内容のままで
ワーキングディレクトリというImagebuilderで指定する項目(その名の通り生成するAMIに対してファイルを生成するなどの処理するときに使うディレクトリ)でそこに中身が空の skip_cleanup_ssh_files と名のファイルを生成しておけば良いみたいです。
5.さいごに
障害発覚から原因特定〜暫定対応〜問い合わせまでのプロセス自体は、割とスムーズにできたのではないかと思います。
しかしながら、公開鍵を使ってsshするなど割と最近のベストプラクティスには沿っていない仕組みを構築していると
こういった形で影響を受けることも知ったので、構築の際には十分に気をつけたいところです。
AWS Well-Architectedのベストプラクティスの沿っていないと結構バッサリと切り捨てられる印象を持ちましたw
また、AWSに問い合わせてみると、回答は早いですし内容も丁寧なので
原因特定に悩んだら割とスピーディに問い合わせてしまうなど、今後も積極的も活用させていただこうと思います。