目次
1. SSHキーペア方式の問題点
普段、AWS EC2にはどのようにログインし、管理しているのでしょうか。おそらく多くの方がSSH key pair方式を利用しているのではないでしょうか。しかし、SSH key pair方式には多くのデメリットがあります。
-
セキュリティリスク:
- EC2のセキュリティグループのインバウンドでSSH用22番ポートを開く必要があり、攻撃対象となる可能性が高まる。
- 標準の22番ポートから別のポートに変更したり、特定のIPアドレスからのアクセスのみを許可したり、SSHアクセスをVPN経由に限定したりするなど、いくつかの対策があります。これらによってリスクをある程度緩和できますが、運用が複雑になるのは避けられません。
- 秘密鍵の漏洩リスクがあり、漏洩した場合の影響が大きい。
- 多数のサーバーに分散したキーを特定し、削除するのが難しい。
- 退職者のキーが完全に削除されず、不正アクセスの可能性が残る。メンバーが退職した際に、新たにプライベートキーを作成し、残っているメンバー全員に配布し直し、さらにすべてのEC2インスタンスの公開鍵を更新するという作業は、現実的にはほぼ不可能
- EC2のセキュリティグループのインバウンドでSSH用22番ポートを開く必要があり、攻撃対象となる可能性が高まる。
-
細かなアクセス制御が困難:
- 粒度の低い制御:
- EC2インスタンスの一般的な利用方法では、個別のOSユーザーを作成せず、全ユーザーが同じOSユーザー(例:
ec2-user
)でSSHログインすることが多い - 基本的には全ユーザーが同じキーペアを利用
- キーペアは通常、全てか無しの権限しか提供せず、特定の操作や時間帯に限定した制御が難しい。
- EC2インスタンスの一般的な利用方法では、個別のOSユーザーを作成せず、全ユーザーが同じOSユーザー(例:
- 動的な権限変更の困難さ:一度付与した権限を動的に変更したり、一時的に制限することが容易ではない。
- 粒度の低い制御:
-
踏み台サーバーが必要な場合がある:
- 複雑なネットワーク構成:多層のネットワークでは、プライベートサブネット内のEC2インスタンスに接続する場合、踏み台が必要。
- セキュリティリスクの増大:踏み台サーバー自体が攻撃対象となり、追加のセキュリティ対策が必要。
- 運用コストの増加:踏み台サーバーの管理・監視・更新に追加のリソースが必要。
-
監査とコンプライアンス
- セッションの記録や監査が困難:
- アクティビティの可視性不足:SSH接続中の具体的な操作内容を記録・監視することが標準では困難
- アクセス履歴の不完全性:誰がいつどのサーバーにアクセスしたかの完全な記録を維持するのが難しい
- .historyファイルは実行されたコマンドのみを記録し、コマンドの出力や対話的なセッションの詳細は記録しません。
- ユーザーが自身の
.history
ファイルを編集したり削除したりすることが可能です。 -
.history
ファイルはセッション終了時に更新されるため、リアルタイムでの監視ができません。 - タイムスタンプ、接続元IPアドレス、セッション時間などの重要な情報が記録されません。
- セッションの記録や監査が困難:
2. 目標
SSHからの脱却を図り、SSHキーペアを使用したEC2へのログイン方法を完全に廃止し、AWS System Manager
のSession Manager
を活用してEC2インスタンスにアクセスする運用体制へ移行する。これにより、以下のような利点を持つ新しい運用環境の実現を目指す。
- セキュアな接続の確立
- インバウンドポートの開放が不要
- SSHキーの管理が不要
- 踏み台サーバーなくてもプライベートサブネット内のインスタンスにもアクセス可能
- パブリックIPアドレスの管理が不要
- 監査可能な詳細なログ記録の実現
- IAMポリシーを使用して、誰がどのインスタンスにアクセスできるかを詳細に制御可能
この移行により、セキュリティの向上と運用負荷の軽減を同時に達成し、より効率的で安全なインフラ管理を実現する。
- SSHある世界
- SSHない世界
3. 事前準備
3.1 SSMエージェントのインストール
- EC2に
Session Manager
経由で接続するには、SSMエージェントの準備と、EC2からSession Manager
への通信を許可するIAMロールの設定が必要です。 - EC2インスタンスにインストールされたSSMエージェントが
Session Manager
と連携し、SSMエージェントからSession Manager
への接続を確立します。これにより、Session Manager
側からEC2を管理・接続できるようになります。 -
AWSが提供する比較的新しいマシンイメージ(AMI)を使用している場合、SSMエージェントはすでに実装済みであり、特別な作業は不要
3.2 IAMロールの準備
EC2インスタンスからSession Manager
への通信を可能にするため、EC2インスタンスにIAMロールを付与し、Session Manager
への接続を許可する必要があります。
AWSが事前に用意しているIAMポリシーAmazonSSMManagedInstanceCore
には、Session Manager
に必要な権限が含まれています。このポリシーを使用してIAMロールを作成し、作成したロールをEC2インスタンスにアタッチします。
4. Systems Manager
のSession Manager
でEC2へ接続
先にEC2のネットワーク構成的にSession Manager
に接続できる状態になっている前提で進めます。
4.1 EC2のマネジメントコンソールから接続
-
EC2ダッシュボードより接続を行いたいEC2を選択し、
Connect
→Session Manager
タブのConnect
ボタンを押下
-
表示されているシェル画面に自由にコマンド実行
sh-5.2$ exec /bin/bash [ssm-user@ip-10-0-20-223 bin]$ timestamp=$(date '+%Y-%m-%dT%H:%M:%SZ') [ssm-user@ip-10-0-20-223 bin]$ echo $timestamp 2024-08-28T14:54:48Z
4.2 Systems Managerのコンソール画面から接続
Systems Manager
ダッシュボード画面のSession Manage
→Session
タブからStart Session
で接続したいEC2を選択し、Start session
を押下しても接続できます。
4.3 ローカルPCでAWS CLIから接続
ローカルPCからSession Manager
で接続するためにはaws ssm start-session
コマンドで接続したいEC2のインスタンスIDを指定して実行することでSession Manager
経由でEC2に接続することができます。
-
先にこちらのドキュメントを参考し、必要な
Session Manager plugin
をインストール$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac_arm64/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip" $ unzip sessionmanager-bundle.zip $ sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin $ session-manager-plugin --version 1.2.650.0
-
aws ssm start-session
コマンドでEC2に接続$ aws ssm start-session --target i-03dbcf6d7c0264b47 Starting session with SessionId: Dan-6mcz4l2zzjq75pmidle6o3pcva sh-5.2$ exec /bin/bash [ssm-user@ip-10-0-20-223 bin]$ timestamp=$(date '+%Y-%m-%dT%H:%M:%SZ') [ssm-user@ip-10-0-20-223 bin]$ echo $timestamp 2024-08-28T15:22:13Z
5. 構成パターン
5.1 パブリックサブネットにあるEC2に接続するパターン
EC2が直接グローバルIPアドレスを持っているパブリックサブネットに所属している場合、EC2はインターネット経由でSession Manager
と連携できるため、EC2でSSMエージェントが動作していれば特に何もせずともSession Manager
経由で接続可能です。
5.2 プライベートサブネットにあるEC2に接続するパターン(NAT Gatewayなし)
インターネットに接続していないプライベートサブネット内のEC2インスタンスに接続する場合、EC2からSession Manager
への接続経路がないため、そのままではSession Manager
と連携できません。そこで、Session Manager
との接続を確立するためのVPCエンドポイント
を作成する必要があります。
VPCエンドポイントを作成することで、通常はAWSのグローバルネットワーク経由で行うSession Manager
との接続を、内部のプライベートネットワークから直接確立することが可能になります。
簡単に言えば、該当のプライベートネットワークにSession Manager
サービスと直接接続する仮想ネットワークインターフェース(ENI)を作成することで、内部からSession Manager
に接続できるようにします。
5.2.1 事前準備
-
ネットワークインターフェース(
ENI
)用セキュリティグループの作成-
VPCエンドポイントを作成する前に、
ENI
用セキュリティグループを作成しておきます -
インバウンドルールで以下を許容するルールを作成
- タイプ:HTTPS(443) ⇒
Session Manager
との通信は443ポートで行われるため - ソース:
- プライベートサブネットのCIDRブロック:該当プライベートサブネット配下のすべてのECS2インスタンスがこのENIに対して送信可能
- EC2インスタンスのセキュリティグループのID:このセキュリティグループがattachされているすべてのEC2インスタンスがこのENIにたいして送信可能
- アウトバウンドではなくインバウンドの443ポートを指定する理由:
- タイプ:HTTPS(443) ⇒
-
アウトバウンドルール:デフォルトのまま(すべてのトラフィックを許可)
-
-
VPCエンドポイントの作成
サービスとしては以下のサービスを指定する必要があり、まとめて選択するようなことはできないことから、最大で以下六個のVPCエンドポイントを作成します。
サービス名 | 必須有無 | 説明 |
---|---|---|
com.amazonaws.*region*.ec2messages |
必須 | |
com.amazonaws.*region*.ssm |
必須 | |
com.amazonaws.*region*.ssmmessages |
必須 | |
com.amazonaws.*region*.logs |
オプション |
CloudWatch Logs へログ転送する場合に必要 |
com.amazonaws.*region*.s3 |
オプション |
S3 へログ転送する場合に必要 |
com.amazonaws.*region*.kms |
オプション |
暗号化オプション を使う場合に必要 |
VPC
エンドポイントの設定は以下のように設定:
項目 | 設定 | 備考 |
---|---|---|
サービスカテゴリ | AWSのサービス | |
サービス | ※上記のサービスを指定 | |
VPC | ※VPCエンドポイントを作成するVPCを指定 | |
DNS名を有効化 | チェック | DNSが有効でないと作成に失敗するため、指定する |
サブネット | EC2が存在するプライベートサブネットを指定 | |
セキュリティグループ | session_manager_sg | 先程作成したセキュリティグループを指定 |
上記VPC
エンドポイントを作成することで、EC2
からSession Manager
へ接続できるようになります。
EC2
からSession Manager
へ接続する際にはDNS
で内部に作られたENIのアドレスを問い合わせてVPC
エンドポイント経由で接続することになるため、特にルーティング等は不要です。
今回は以下4つのエンドポイントに対して実施します。
com.amazonaws.ap-northeast-1.ssm
com.amazonaws.ap-northeast-1.ec2messages
com.amazonaws.ap-northeast-1.ssmmessages
-
com.amazonaws.ap-northeast-1.s3
- エンドポイントのタイプとして
Gateway
とInterface
が選択可能ですが、今回はGateway
を選択
- エンドポイントのタイプとして
まずはcom.amazonaws.region.ssm
のVPCエンドポイントを作成してみる
-
サービスカテゴリの
AWS services
を選択、サービス名の検索ボックスにssm
と入力し、com.amazonaws.ap-northeast-1.ssm
を選択
-
エンドポイントを作成するVPCを選択
「プライベートDNS名を有効にする」オプションにチェックを入れます(デフォルトはチェック入っている)。これにより、標準のAWSのSSMエンドポイントがVPCエンドポイントにリダイレクトされます。
-
サブネット選択
- エンドポイントを作成するプライベートサブネットを選択します。
- 複数のアベイラビリティーゾーンにまたがるサブネットを選択することをお勧めします。
- 選択されるサブネットごとに新しい
ENI
が自動的に作成される
5.2.2 Systems ManagerのVPCエンドポイントでEC2にアクセスしてみる
sh-5.2$ exec /bin/bash
[ssm-user@ip-10-0-30-163 bin]$ timestamp=$(date '+%Y-%m-%dT%H:%M:%SZ')
[ssm-user@ip-10-0-30-163 bin]$ echo $timestamp
2024-08-28T16:22:23Z
5.2.3 仕組みの解説
-
インターフェースVPCエンドポイントの正体はENIだ
- インターフェース型エンドポイントは
Elastic Network Interface (ENI)
を介することで、インターネットを経由せずにAWSのプライベートネットワーク経由で直接AWSサービスにアクセスできる - ENIは、物理的な環境における
Network Interface Card (NIC)
に相当します。VPC内のリソースとAWSサービス間の通信を仲介する役割を果たします。 - インターフェース型エンドポイントを作成する時に、VPC内1つ以上のプライベートサブネットを選択し、選択したサブネット上にそれぞれ
ENI
が作成されます。
生成されるENIのリスト:
- ENIにプライベートIPアドレスを割り当て、VPC内(プライベートサブネット内)からAWSのプライベートネットワーク経由で直接AWSサービスにアクセスできる
- インターフェース型エンドポイントは
-
セキュリティ:
- トラフィックはAWSのプライベートネットワーク内に留まるため、インターネットを経由しません。
- ENIに対してセキュリティグループを使用してアクセス制御が可能
-
DNS解決:
-
プライベートDNS名を使用してサービスにアクセス可能で、既存のアプリケーションの設定変更しなくても済む
-
インターフェースVPCエンドポイントには、主に以下の3種類のDNS名が存在:
- リージョンDNS名
- エンドポイント全体を表し、関連するすべてのAZのIPアドレスに解決されます。
-
AZごとのDNS名
- 特定のAZ内のエンドポイントのIPアドレスに解決されます。
- プライベートDNS名(オプション)
-
普通は
ssm.ap-northeast-1.amazonaws.com
のような標準のAWSサービスエンドポイント名はpublic IPに名前解決される。 - エンドポイントの作成時に「プライベートDNS名を有効にする」オプションを選択する場合は、標準のAWSサービスエンドポイント名がVPCエンドポイントのプライベートIPアドレス(つまり
ENI
のIP)に解決されます。 - この機能を使うためにはVPCでは
Enable DNS hostnames
とEnable DNS resolution
が有効になっている必要があります。(VPC作成する時に、こちらの2つの項目はデフォルトではチェックされる)
-
普通は
- リージョンDNS名
-
これらのDNS名は、エンドポイントの作成時に自動的に生成され、AWS管理のプライベートホストゾーンに登録され、ホストゾーンはユーザーには直接見えない形で管理。
-
プライベートDNS名を有効にすると、VPC内のリソースは標準のAWSサービスエンドポイント名を使用してサービスにアクセスでき、アプリケーションの設定変更が不要になります。
-
-
DNS名を解決してみる:
- private subnetにあるEC2に
System Manager
(Session Manager
)経由でログインした上で以下のコマンドを実行- 3つのDNSとも同じ
10.0.30.93
(ENIのプライベートIP)に名前解決された。 - 10.0.0.2#53経由で名前解決されていることが分かる
# 1. リージョンDNS名 $ nslookup vpce-0d4404df16ee7c94f-rptn23x5.ssm.ap-northeast-1.vpce.amazonaws.com Server: 10.0.0.2 Address: 10.0.0.2#53 Non-authoritative answer: Name: vpce-0d4404df16ee7c94f-rptn23x5.ssm.ap-northeast-1.vpce.amazonaws.com Address: 10.0.30.93 ⇒ ENIのプライベートIPだ # 2. AZごとのDNS名 $ nslookup vpce-0d4404df16ee7c94f-rptn23x5-ap-northeast-1a.ssm.ap-northeast-1.vpce.amazonaws.com Server: 10.0.0.2 Address: 10.0.0.2#53 Non-authoritative answer: Name: vpce-0d4404df16ee7c94f-rptn23x5-ap-northeast-1a.ssm.ap-northeast-1.vpce.amazonaws.com Address: 10.0.30.93 ⇒ ENIのプライベートIPだ # 3. プライベートDNS名 $ nslookup ssm.ap-northeast-1.amazonaws.com Server: 10.0.0.2 Address: 10.0.0.2#53 Non-authoritative answer: Name: ssm.ap-northeast-1.amazonaws.com Address: 10.0.30.93 ⇒ ENIのプライベートIPだ
- 3つのDNSとも同じ
- DNS名前解決の流れ:
参考記事:
5.2.4 VPNエンドポイントを利用する時に既存アプリケーションへの影響
-
プライベートDNSを有効にすることで、既存のアプリケーションに対して修正を加える必要はありません。
インターフェース型VPCエンドポイントを作成する際に、プライベートDNS名を有効にする
オプションを選択します。このオプションを有効にすると、AWSサービスの公開エンドポイントのDNS名を使用しながら、VPCエンドポイント経由でプライベート接続を利用できるようになります。結果として、アプリケーションのコードを変更することなく、VPCエンドポイントを介してAWSサービスにアクセスすることが可能になります。 -
AWSのSDKやCLIを使用している場合、デフォルトのエンドポイントを使用したままで(
--endpoint-url
を指定する必要はありません)、トラフィックは自動的にVPCエンドポイントを経由します。
6. SSH key pairとSession Managerの比較
項目 | SSH key pair | Systems Manager Session Manager |
---|---|---|
セキュリティ | 鍵の管理が必要、漏洩リスクあり | 鍵管理不要、IAMベースのアクセス制御 |
ネットワーク設定 | インバウンドSSHポートの開放が必要 | インバウンドポートの開放不要 |
踏み台サーバー | - プライベートサブネットアクセス時に必要 - 踏み台サーバー自体はpublic subnetに配置 |
不要 |
アクセス制御 | 鍵の配布・管理で制御 | IAMポリシーで細かく制御可能 |
監査とログ | 限定的 | CloudTrail、CloudWatchと連携可能 |
クライアントツール | 標準SSHクライアント | ・AWS CLI(Session Managerプラグイン) ・ブラウザベースのコンソールも利用可能 |
プロトコル対応 | SSH、SCP、SFTP | 独自プロトコル(SSH対応も可能) |
セットアップ複雑さ | 比較的シンプル | IAM、VPCエンドポイントの設定が必要 |
運用コスト | 鍵の管理コストが高い | 初期設定後の運用コストは低い |
スケーラビリティ | 大規模環境での管理が困難 | 大規模環境でも一元管理が容易 |
コンプライアンス | 鍵管理のポリシーが必要 | IAMポリシーで一元管理可能 |
多要素認証 | 追加設定が必要 | IAMと連携して容易に実装可能 |