まだ EC2 に SSH で接続してる？マシンへの接続は SSM 化しよう。

# はじめに
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 エージェントをインストールする

:::note
インストール済みの場合はこの手順をスキップできます。

> AWS が提供する Amazon Linux 2 用および Amazon Linux 2023 用 Amazon Machine Images (AMIs) には、デフォルトで AWS Systems Manager エージェント (SSM Agent) がプリインストールされています。
:::

Amazon Linux の場合、以下のコマンドで SSM エージェントをインストールします。

```bash:x86_64
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
```

```bash:ARM64
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] > [フリートマネージャー] > [[デフォルトのホスト管理設定を設定する]](https://ap-northeast-1.console.aws.amazon.com/systems-manager/fleet-manager/dhmc?region=ap-northeast-1) の [デフォルトのホスト管理設定を有効にする] のチェックをオンにし、設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/f29e5842-9174-d0c5-538c-0efc397c0aba.png)

ロールは推奨のもので問題ありません。選択すると自動的にアカウント内に作成されます。

# SSH で直接接続できないように設定する


## 不要なポートを閉鎖する
ここまでで SSM がバイパスしてくれるようになったため、22 ポートは不要になります。
直接 SSH をするのはもうやめましょう。

セキュリティグループで、インバウンド 22 ポートを閉じましょう。ちなみに SSM では SSM Agent の通信のためアウトバウンド 443 ポートが必要です。


:::note warn
**SSH や鍵の設定は引き続き必要です**

使い慣れたローカルからのターミナル接続や、SSH 接続を利用しているツールなどを使用したい場合に備えて、SSH や鍵の設定まで消してしまわないようにしましょう。消してしまうと不便になります。 
:::


:::note warn
また、マシン作成時のキーペアも引き続き大切に保管しておきましょう。もし SSM エージェントが応答しなくなったときなど、ロックアウトされないように必要です。そういったときは一時的に 22 ポートを 特定の IP だけで開放するなどして対処しましょう。
:::

# SSM でインスタンスに接続する

設定ができたので、SSM で EC2 インスタンスに接続してみましょう。

## マネジメントコンソールで接続

AWS マネジメントコンソールから [Systems Manager] > [セッションマネージャー] に移動し、[セッションの開始] をクリックします。

また、EC2 の一覧から [接続] > [セッションマネージャー] を選択することでも接続できます。

ブラウザ上で、シェルが立ち上がれば接続できています。

## SSH over SSM で接続する

SSH の設定ファイルに以下のように追加します。

aws-vault で AWS クレデンシャルを管理している場合の設定例です。

[aws-vault](https://github.com/99designs/aws-vault) と [セッションマネージャーのプラグイン](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/install-plugin-macos-overview.html) が必要です。


```ssh:~/.ssh/config
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 コマンドで接続してみましょう。

```sh
ssh your-hostname
```

この方法で 22 ポートが閉じていても SSM がセッションをバイパスし SSH 接続できます。

SSH 鍵の管理は引き続き必要になりますが、SSM 化していれば、IAM ユーザーで接続管理できているため、ユーザーごとに別の鍵を発行せずとも一定のセキュリティは担保できています。もちろん考え方次第でダブル管理にしたほうがよりセキュアですが、運用との相談になるかと思います。

このシェルコマンドで接続できれば、VSCode や Cursor から接続することもできるはずです。

https://qiita.com/craymaru/items/f126597ed91940226805


:::note warn
上の例の中では、`IdentityFile` をファイルから読み取っていますが、これもパスワードを平文管理しているのと一緒です。今の時代セキュリティ的によくありません。 1Password などの暗号化されたストアを参照するのが理想的です。
```ssh:~/.ssh/config
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 のデーモンが生きていないとエラーになります。エラーはツールに依存するため種類がありますが、以下のように分かりづらいエラーなこともあります。ハマりやすいポイントなので気をつけましょう。
```shell
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

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/agent-install-al2.html

https://dev.classmethod.jp/articles/aws-systems-manager-supports-default-host-management-configuration/

https://developer.1password.com/docs/ssh/agent/advanced/#match-key-with-host