こんにちは。タノシムスタジオ@東京オフィスでエンジニアをしている中山です。タノシムスタジオではクラウドプラットフォームとして主にAWSを利用しています。今回は、AWS上のサーバにSessionManagerを使ってSSH接続をする機能について、簡単な使い方と実際にプロジェクトで利用して感じたメリットやデメリットを紹介します。
SessionManagerとは
Session Manager はフルマネージド型 AWS Systems Manager 機能であり、インタラクティブなワンクリックブラウザベースのシェルや AWS CLI を介して、EC2 インスタンス、オンプレミスインスタンス、仮想マシン (VM) を管理できます。Session Manager を使用すると、インバウンドポートを開いたり、踏み台ホストを維持したり、SSH キーを管理したりすることなく、監査可能なインスタンスを安全に管理できます。また、Session Manager を使用すると、マネージドインスタンスへの簡単なワンクリックのクロスプラットフォームアクセスをエンドユーザーに提供しつつ、インスタンスへの制御されたアクセス、厳格なセキュリティプラクティス、完全に監査可能なログ (インスタンスアクセスの詳細を含む) が要求される企業ポリシーに簡単に準拠できます。
公式ドキュメントから引用しました。この機能を使うと、AWSのIAMでサーバへアクセスできるユーザを管理することができます。ユーザ権限の一元化という観点で、IAMに集約できるのが良いですね。どのIAMがサーバへ接続したのかを保存することもできるため、セキュリティの観点からも管理が楽になります。
また、SSHトンネリングがサポートされており、SessionManagerを経由することでSSHポートが空いていなくてもSSHコマンドを利用することができます。その他にも、AWSコンソール上でシェルを実行できるため、ローカルマシンで設定を行わなくてもブラウザ上でサーバを操作できて便利です。
AWS上のサーバへ接続する際に、管理やセキュリティで考えないといけないことを簡単にしてくれるのがSessionManagerと言えます。この機能の使い方を、導入時の設定を交えながら簡単に解説していきます。
SessionManagerの使い方
EC2インスタンスをSessionManagerで接続できる状態にする
まずはAWSコンソール上からSessionManagerでサーバに接続してみましょう。実際の手順は 公式ドキュメントで手厚く解説されているのと、子細に入ると長くなってしまうため、要点に絞って解説します。
EC2インスタンスにSessionManagerで接続するには、以下の条件を満たす必要があります。
- EC2インスタンスにSessionManager接続を許可するIAMインスタンスプロファイルが設定されている
- EC2インスタンスにSSM エージェントのバージョン 2.3.672.0 以降がインストールされている
- Systems ManagerからEC2インスタンスへ接続できるネットワーク経路がある
- EC2インスタンスに接続するユーザにSessionManagerの利用を許可するIAMロールが設定されている
1点目のEC2インスタンスに設定するIAMは、AmazonSSMManagedInstanceCore
というAWS 管理ポリシーが定義されているので、こちらを公式ドキュメント通りに設定するだけで大丈夫です。
2点目は最近のAmazon Linux 2 で立ち上げればインストール済みです。他のOSを利用していたり古めのAMIだとバージョンが古かったりインストールされていない可能性があるため、EC2インスタンスのユーザーデータに下記のような設定を仕込んでおき起動時にバージョンアップが掛かるようにしておくと良いようです。
#!/bin/bash
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent
3点目はインフラ構成によって難易度が変わってきます。インターネットへ公開しているようなEC2インスタンスであれば何もしなくても問題ないですが、PrivateSubnetに立てたEC2はSystemsManagerから接続できないため、PrivateLinkなどを設定してEC2とSystemsManagerの通信を確保する必要があります。
利用しているプロジェクトではPrivateSubnet上にEC2インスタンスが立っているため、この設定を行う必要がありました。公式ドキュメントにも解説があり、AWS PrivateLinkを利用しています。VPC > エンドポイントの項目で、下図のようにEC2インスタンスのあるVPCに指定されたサービスが表示されている状態であれば大丈夫です。
余談ですが、東京リージョンのS3エンドポイントが立っているのは、Amazon Linux の yumリポジトリへPrivateSubnet上のEC2インスタンスからアクセスするためです。
4点目のIAMロールはSSH接続まで見越して、公式ドキュメントの内容に加えてssm:StartSession
ActionのResourceに”arn:aws:ssm:*:*:document/AWS-StartSSHSession”
まで追加すると良いようです。
SSH トンネリングで接続する
EC2インスタンスとSessionManagerが接続できるようになれば、次はSSHトンネリングできるようにローカルマシンを設定しましょう。必要な条件は公式ドキュメントに記載されていますが、以下の通りです。
- ローカルマシンに AWS CLI とSession Manager プラグイン 1.1.23.0 バージョン以降がインストールされている
Session Manager プラグインのインストールはローカルマシンのOSによって異なるので、ドキュメントの記載を参照してください。インストール後、 ~/.ssh/config
に以下のような設定を追加しましょう。
# 汎用的
host i-* mi-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
# 実際の接続に利用
Host test-admin
HostName i-xxxxxxxxxxxxxxxxx
User nakayama
IdentityFile ~/.ssh/ssh-key
ProxyCommand bash -c "aws --profile [target-instance-profile] ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
細かいですが、公式ドキュメントに記載されているような汎用的な設定だと毎回インスタンスIDを入力する必要が出てしまうのでサーバごとにエイリアスを書いています。引数でprofileを指定することでawsのクレデンシャルをサーバごとに切り替えることができるので、複数プロジェクトのクレデンシャルをaws configで設定しているような場合に便利です。弊社のAWSアカウントはプロジェクトごとに開発環境と本番環境が分かれており、profileも異なるのでそれぞれ指定しています。
ここまで準備ができれば、あとはssh test-admin
のようにコマンドを打つだけで指定したEC2インスタンスへSSHできます。
駆け足での解説となりましたが、以上が現在プロジェクトで使用しているSessionManager経由のSSH接続方法です。
利用してみて
良かったところ
IAMロールさえあればAWSコンソール上でサーバへアクセスできるため、SSH鍵やOSユーザを作成したり削除したりという管理の煩雑さから解放されたのが良かったです。IAMが個人ごとに作られていれば、SSH鍵は権限グループごとに使い回すという方針で管理しています。臨時でヘルプをお願いしたメンバーにもIAMを渡してコンソールへ接続してもらえればサーバ操作ができるようになりますし、不要になればIAMを削除するだけで良いのでEC2インスタンスの管理体制を整えやすくなりました。
SessionManager単体だとファイル転送やポート転送ができなかったのですが、SSHトンネリングがサポートされたことで踏み台サーバを立てずに済んだのも良かったです。VPC内のリソースにアクセスする際はEC2インスタンスにSSH接続してから操作すれば良いですし、外にSSHポートが露出しているサーバを置かずに済むのでセキュリティ上の心配点が減りました。
注意点
SessionManagerでコンソールへログインした際のOSユーザはssm-user
というroot権限持ちのユーザになります。SessionManagerのログインユーザ設定はIAMロール側で行えるので、非管理者には弱い権限のユーザでログインするよう設定するなど、運用上はアクセス権限を考慮するべきです。
PrivateSubnet から利用するためにエンドポイントへアクセスできるよう設定しましたが、PrivateLinkを開いていると料金が掛かります。時間当たりと処理データ当たりでの計算になるため、SessionManager経由で実行する操作には気を付ける必要があります。
おわりに
サーバのコンテナ化が進む昨今ですが、まだまだサーバを立てて汎用的な処理を行うことは多いかと思います。そんな時にはSSHポートを開けて操作できるよう設定したくなりますが、ユーザ管理やセキュリティの観点からSessionManagerの利用してみるのはいかがでしょうか。
参考URL
AWS Systems Manager Session Manager
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html