はじめに
AWSのEC2インスタンスに接続する際、今まではEC2インスタンス作成時にssh鍵を作成し鍵を用いてssh接続していたが、鍵の管理が面倒であり、鍵の紛失等によるセキュリティ面の懸念があった。
このため、ssh接続を禁止し、Session Managerを用いてEC2に接続することとする。
また、Session Managerを使用することで、セキュリティグループにてssh(ポート22番)の許可設定も不要になる。
前提として、EC2のOSはAmazon Linux 2
を採用している。
準備
Session Managerを使用するには、EC2上に専用のアプリssm-agent
をインストールし、適切なロールをアタッチする必要がある。
Systems ManagerのHost Managementの「作成」ボタンを押す(下記画面)ことで、選択したリージョンのEC2にssm-agent
が自動でインストールされ(プロセスとしてamazon-ssm-agent
とssm-agent-worker
の2つが起動する)、ssm-user
アカウントが作成される。今回はこれを利用した。
EC2には自動で作成されたAmazonSSMRoleForInstancesQuickSetup
ロールが付与される。ロールを変更する場合には、EC2コンソールから可能(下記画面)。
Session Managerを使用するIAMアカウントには適切なポリシー設定が必要になる。今回は、下記のポリシーを作成し、IAMアカウントにこのポリシーを適用した。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ssm:GetConnectionStatus",
"ssm:StartSession"
],
"Resource": [
"arn:aws:ssm:<region>:*:document/*",
"arn:aws:ec2:<region>:<account id>:instance/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ssm:DescribeInstanceInformation",
"Resource": "*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": [
"ssm:ResumeSession",
"ssm:TerminateSession"
],
"Resource": "arn:aws:ssm:*:*:session/${aws:username}-*"
}
]
}
接続
Session ManagerによるEC2への接続は、EC2コンソールや社内のPCから可能。EC2コンソールではブラウザ内での接続、開発PCではaws-cli
コマンドを利用しての接続となる。
EC2コンソールから
EC2コンソールからは、接続したいEC2を選択後、「接続」ボタンを押すことで接続可能(下記画面参照)。
下図のようにブラウザから接続できる。ssm-user
でログインされ、sudo
コマンドは利用可能となっている。
社内PCから
社内のPCから接続する場合は、AWSのコマンドラインツールaws-cli
が必要で、少しの設定が必要になってくる。
aws-cli
は適宜インストールする。また、別途session-manager-plugin
が必要とのことなので、こちらもインストールしておく。
AWS CLI の最新バージョンをインストールまたは更新します。
(オプション) AWS CLI 用の Session Manager プラグインをインストールする - AWS Systems Manager
(筆者のmacOSでは、aws-cli
をbrew
にてインストールしたが、session-manager-plugin
は別途インストールの必要はなかった。)
セッショントークンの取得
社内のポリシーとして、各IAMアカウントにはMFA(多要素認証)を設定しているため、AWSにアクセスするためにはまずセッショントークンを取得し、これを使用する必要がある。
セッショントークン取得のためには、各IAMアカウントのアクセスキー(AccessKeyId
とSecretAccessKey
)が必要なため、払い出しておく。このアクセスキーをdefault
プロファイルとして利用するには、下記のコマンドを実行。
$ aws configure
AWS Access Key ID [******************00]:
AWS Secret Access Key [******************AA]:
Default region name [ap-northeast-1]:
Default output format [json]:
下記のコマンドを実行すると、AWSにアクセスするための一時的なセッショントークンが払い出される。
<account id>
には「012345678901」などのオーナーアカウントのIDを、<iam username>
には、「yamada.taro」などの各IAMアカウントに割り当てられているユーザー名を、<token code>
には「123456」などのAuthenticatorなどの2段階認証アプリが払い出したトークンコードを指定する。
このセッショントークンの期限はデフォルトで43,200秒(12時間)となっており、--duration-seconds
オプションで最大129,600秒(36時間)まで指定可能(最小は900秒(15分))。
$ aws sts get-session-token --serial-number arn:aws:iam::<account id>:mfa/<iam username> --token-code <token code>
{
"Credentials": {
"AccessKeyId": "...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "2022-10-03T21:08:46+00:00"
}
}
取得したAccessKeyId
SecretAccessKey
SessionToken
を使用して、Session Manager経由でEC2に接続することになる。
これらの値を環境変数やらAWSプロファイルにセットする必要があるが、手動で行うのは面倒なので自動化する。mfa
プロファイルに自動でセットするコマンドを記す。
下記はmacOSで動作するコマンド。デフォルトシェルであるzsh
を使用している。コマンドを実行すると入力待ち状態になるので、Authenticatorなどのトークンコードを入力する。jq
コマンドは別途インストールが必要。
$ aws sts get-session-token --serial-number arn:aws:iam::<account id>:mfa/<iam username> --token-code "$(read v; echo $v)" | jq -r '.Credentials | to_entries[] | [.key, .value] | join(" ")' | sed "s/AccessKeyId/aws_access_key_id/;s/SecretAccessKey/aws_secret_access_key/;s/SessionToken/aws_session_token/; s/^/aws configure set --profile mfa /" | zsh
下記はWindowsで動作するコマンド。PowerShell
で実行する。コマンドを実行すると入力待ち状態になるので、Authenticatorなどのトークンコードを入力する。
PS > $json = (aws sts get-session-token --serial-number arn:aws:iam::<account id>:mfa/<iam username> --token-code "$(Read-Host token-code)" | ConvertFrom-Json); aws configure set aws_access_key_id $json.Credentials.AccessKeyId --profile mfa; aws configure set aws_secret_access_key $json.Credentials.SecretAccessKey --profile mfa; aws configure set aws_session_token $json.Credentials.SessionToken --profile mfa
接続
上述で自動セットされたmfa
プロファイルを用いて、Session Manager経由でEC2接続するには、下記コマンドを実行する。
<instance id>
には、「i-123456789012」などのEC2のインスタンスIDを指定する。
$ aws ssm start-session --target i-<instance id> --profile mfa
Starting session with SessionId: yamada.taro-12345678901234567
sh-4.2$
以上で、ssm-user
でログイン、接続される。sudo
コマンドは利用可能となっている。
sshセッション接続(主にファイル転送のため)
Session Manager経由して、EC2上のsshd
に接続することも可能であり、ファイル転送する際にはssh接続してscp
を利用する。この場合、EC2上でsshdが稼働している必要がある。
ただし、EC2上のsshdは、localhost
からの接続のみを許可していればよく、セキュリティグループの設定は必要ない。
また、ssh接続するにはssh鍵が必要にはなる。が、従来のように各EC2用に鍵を払い出すのではなく、Session Manager経由のssh接続のために、鍵を1つ用意しておいたのでいいかもしれない。
ssh接続には、ssh設定のProxyCommand
を利用する。.ssh/config
に以下のように記述する。
# EC2 instances via Session Manager
Host i-*
ProxyCommand sh -c “aws ssm start-session --profile mfa --target %h --document-name AWS-StartSSHSession --parameters ‘portNumber=%p’”
ステップ 8: (オプション) Session Manager を通して SSH 接続のアクセス許可を有効にして制御する - AWS Systems Manager
下記のようなコマンドで、ssh接続やscp
によるファイル転送が可能となる。
$ ssh -i via_ssm.pem ec2-user@i-123456789012
$ scp -i via_ssm.pem ec2-user@i-123456789012:~/hoge.log ./
さいごに
ssh鍵管理など煩雑な処理から解放されるはず。。
ポリシー設定により様々な制限も可能なので、今後試してみます。