はじめに
AWS EC2 インスタンスに開発者が接続する際、従来の方法として SSH を使用することが一般的でした。しかし、AWS Systems Manager (SSM) を使用することで、よりセキュアで管理しやすい接続方法を実現できます。本記事では、SSH から SSM への移行方法について解説します。
SSM とは?
AWS Systems Manager (SSM) は、AWS リソースの管理と運用を簡素化するためのサービスです。SSM を使用することで、EC2 インスタンスに対してエージェントを介してコマンドを実行したり、セッションマネージャーを使用してシェルアクセスを行うことができます。
SSM で接続するメリット
SSH キーの管理が不要になり、IAM ポリシーでアクセスを制御できます。IAM ユーザーだけを管理すればよくなるのです。
監査ログの取得SSM セッションのログを CloudWatch や S3 に保存することで、アクセス履歴を監査できます。ただしややクセが強いログなので、扱いには多少苦労するでしょう。(改善を期待)
また、EC2 にパブリック IP を設定しなくて良くなります。パブリックサブネットに置かなくて良くなるためよりセキュアになります。
前提条件
- EC2 インスタンスに SSM エージェントがインストールされていること
- DHMC または EC2 インスタンスに、適切なロールがアタッチされていること
- DHMC を強く推奨。個別にロールに設定してアタッチするのは管理が面倒です。
導入手順
1. SSM エージェントをインストールする
インストール済みの場合はこの手順をスキップできます。
AWS が提供する Amazon Linux 2 用および Amazon Linux 2023 用 Amazon Machine Images (AMIs) には、デフォルトで AWS Systems Manager エージェント (SSM Agent) がプリインストールされています。
Amazon Linux の場合、以下のコマンドで SSM エージェントをインストールします。
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_arm64/amazon-ssm-agent.rpm
sudo yum install -y amazon-ssm-agent
などでインストールしても良いですが、リポジトリの状況によって最新が入らないことがあるので公式どおり上記の方法を推奨します。
また、パスに windows と含まれていて一瞬アレっと思いますが、Linux 用です。
2. DHMC を設定する
DHMC を有効にします。これを有効にすることで、同一リージョンのすべての EC2 インスタンスに、直にロールをアタッチすることなくフリートマネージャーと通信させることができるようになります。
AWS マネジメントコンソールから [Systems Manager] > [フリートマネージャー] > [デフォルトのホスト管理設定を設定する] の [デフォルトのホスト管理設定を有効にする] のチェックをオンにし、設定します。
ロールは推奨のもので問題ありません。選択すると自動的にアカウント内に作成されます。
SSH で直接接続できないように設定する
不要なポートを閉鎖する
ここまでで SSM がバイパスしてくれるようになったため、22 ポートは不要になります。
直接 SSH をするのはもうやめましょう。
セキュリティグループで、インバウンド 22 ポートを閉じましょう。ちなみに SSM では SSM Agent の通信のためアウトバウンド 443 ポートが必要です。
SSH や鍵の設定は引き続き必要です
使い慣れたローカルからのターミナル接続や、SSH 接続を利用しているツールなどを使用したい場合に備えて、SSH や鍵の設定まで消してしまわないようにしましょう。消してしまうと不便になります。
また、マシン作成時のキーペアも引き続き大切に保管しておきましょう。もし SSM エージェントが応答しなくなったときなど、ロックアウトされないように必要です。そういったときは一時的に 22 ポートを 特定の IP だけで開放するなどして対処しましょう。
SSM でインスタンスに接続する
設定ができたので、SSM で EC2 インスタンスに接続してみましょう。
マネジメントコンソールで接続
AWS マネジメントコンソールから [Systems Manager] > [セッションマネージャー] に移動し、[セッションの開始] をクリックします。
また、EC2 の一覧から [接続] > [セッションマネージャー] を選択することでも接続できます。
ブラウザ上で、シェルが立ち上がれば接続できています。
SSH over SSM で接続する
SSH の設定ファイルに以下のように追加します。
aws-vault で AWS クレデンシャルを管理している場合の設定例です。
aws-vault と セッションマネージャーのプラグイン が必要です。
Host your-hostname
IdentityFile ~/.ssh/id_ecdsa.pem
HostName i-0abadfdf2072ea871
User your-user-name
ProxyCommand sh -c "aws-vault exec your-credencial -- aws ssm start-session --target %h --document-name AWS-StartSSHSession"
ServerAliveInterval 30
TCPKeepAlive yes
設定が終わったら、通常通り ssh コマンドで接続してみましょう。
ssh your-hostname
この方法で 22 ポートが閉じていても SSM がセッションをバイパスし SSH 接続できます。
SSH 鍵の管理は引き続き必要になりますが、SSM 化していれば、IAM ユーザーで接続管理できているため、ユーザーごとに別の鍵を発行せずとも一定のセキュリティは担保できています。もちろん考え方次第でダブル管理にしたほうがよりセキュアですが、運用との相談になるかと思います。
このシェルコマンドで接続できれば、VSCode や Cursor から接続することもできるはずです。
上の例の中では、IdentityFile
をファイルから読み取っていますが、これもパスワードを平文管理しているのと一緒です。今の時代セキュリティ的によくありません。 1Password などの暗号化されたストアを参照するのが理想的です。
Host *
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
IdentitiesOnly yes
Host xxx
IdentityFile ~/.ssh/example_id_rsa.pub # 公開鍵
1Password を使うとき IdentityFile が秘密鍵ではなく公開鍵に変わる理由
IdentityFile
は通常秘密鍵を指定するのが一般的ですが、公開鍵を指定することによって 1Password のエージェントが正確に読み取ってくれるようになります。これを設定していないと、1Password にストアしている鍵が多いとき、対応した鍵が見つかるまでサーバー側にあてがう事になり、サーバー側に設定されたリトライ上限(OpenSSH だとデフォルト 6 回)に達すると鍵が見つからなかったとし、接続をあきらめてしまいます。鍵が見つかるまであてがうのは無駄な処理でもあるので公開鍵を指定しておきましょう。また、ツールによっては非対応なことがあります。1Password の公式ドキュメントにリストがあるので確認しましょう。
https://developer.1password.com/docs/ssh/agent/compatibility
1Password の起動し忘れ
キー取得時に、1Password のデーモンが生きていないとエラーになります。エラーはツールに依存するため種類がありますが、以下のように分かりづらいエラーなこともあります。ハマりやすいポイントなので気をつけましょう。
Load key "/Users/xxx/.ssh/xxx-ed25519.pub": error in libcrypto
user@i-xxxxxxxxxxxxxxxxx: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
まとめ
SSM を使用することで、SSH の従来の管理方法とらわれないセキュアな接続方法を実現できます。これにより、セキュリティの向上や管理の簡素化が期待できます。ぜひ、SSH から SSM への移行を検討してみてください。
Ref