[How to] SSH to Elastic [an] Beanstalk instance には非常に良い質問がありますが、私が気付いたのは、この方法では1つのSSHキーしか追加できないということです。
インスタンスに複数のSSHキーを追加するにはどうすればよいですか?新しいインスタンスに複数のキーを自動的に追加する方法はありますか?
いいえ、ElasticBeanstalkは単一のキーペアのみをサポートします。 SSHキーをauthorized_keys
ファイルに手動で追加できますが、これらはElasticBeanstalkツールには認識されません。
.ebextensions/authorized_keys.config
という名前のファイルを作成することは、それを行う別の方法です。
files:
/home/ec2-user/.ssh/authorized_keys:
mode: "000400"
owner: ec2-user
group: ec2-user
content: |
ssh-rsa AAAB3N...QcGskx keyname
ssh-rsa BBRdt5...LguTtp another-key
ファイルauthorized_keys.config
の名前は任意です。
Rhunwicksとrch850の回答を組み合わせて、AWSコンソールで設定したものを保持しながらSSHキーを追加するクリーンな方法を次に示します。
files:
/home/ec2-user/.ssh/extra_authorized_keys:
mode: "000400"
owner: ec2-user
group: ec2-user
content: |
ssh-rsa AAAB3N...QcGskx keyname
ssh-rsa BBRdt5...LguTtp another-key
commands:
01_append_keys:
cwd: /home/ec2-user/.ssh/
command: sort -u extra_authorized_keys authorized_keys -o authorized_keys
99_rm_extra_keys:
cwd: /home/ec2-user/.ssh/
command: rm extra_authorized_keys
ご了承ください eb ssh
は、秘密鍵ファイルがAWSコンソールで定義された秘密鍵と同じ名前である場合にのみ機能します。
Jim Flanaganの回答に続いて、アプリケーションのソースディレクトリに次の内容で.ebextensions/app.config
を作成することにより、すべてのインスタンスにキーを追加できます。
commands:
copy_ssh_key_userA:
command: echo "ssh-rsa AAAB3N...QcGskx userA" >> /home/ec2-user/.ssh/authorized_keys
copy_ssh_key_userB:
command: echo "ssh-rsa BBRdt5...LguTtp userB" >> /home/ec2-user/.ssh/authorized_keys
これを実現する1つの方法は、使用する追加のキーペアの公開キーを〜ec2-user/.ssh/authorized_keysに追加するユーザーデータスクリプトを作成し、そのユーザーデータを使用してインスタンスを起動することです。 :
#!
echo ssh-rsa AAAB3N...QcGskx keyname >> ~ec2-user/.ssh/authorized_keys
echo ssh-rsa BBRdt5...LguTtp another-key >> ~ec2-user/.ssh/authorized_keys
IAMでグループを作成します。 beanstalk-access
のように呼んでください。 SSHアクセスが必要なユーザーをIAMのそのグループに追加します。また、パブリックsshキーをIAM Security credentials
に追加します。
以下のデプロイメントスクリプトは、jq
( jq公式チュートリアル )と呼ばれる便利なLinuxツールを使用してAWS CLIからJSONデータを解析するため、.ebextensionsに追加する必要があります。
packages:
yum:
jq: []
次のBASHデプロイメントスクリプトを.ebextensionsに追加します。
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/980_beanstalk_ssh.sh":
mode: "000755"
owner: ec2-user
group: ec2-user
content: |
#!/bin/bash
rm -f /home/ec2-user/.ssh/authorized_keys
users=$(aws iam get-group --group-name beanstalk-access | jq '.["Users"] | [.[].UserName]')
readarray -t users_array < <(jq -r '.[]' <<<"$users")
declare -p users_array
for i in "${users_array[@]}"
do
user_keys=$(aws iam list-ssh-public-keys --user-name $i)
keys=$(echo $user_keys | jq '.["SSHPublicKeys"] | [.[].SSHPublicKeyId]')
readarray -t keys_array < <(jq -r '.[]' <<<"$keys")
declare -p keys_array
for j in "${keys_array[@]}"
do
ssh_public_key=$(aws iam get-ssh-public-key --encoding SSH --user-name $i --ssh-public-key-id $j | jq '.["SSHPublicKey"] .SSHPublicKeyBody' | tr -d \")
echo $ssh_public_key >> /home/ec2-user/.ssh/authorized_keys
done
done
chmod 600 /home/ec2-user/.ssh/authorized_keys
chown ec2-user:ec2-user /home/ec2-user/.ssh/authorized_keys
残念ながら、これはYAMLであるため、コードをインデントして読みやすくすることはできません。しかし、何が起こっているのかを分析してみましょう。
(すぐ下のコードスニペット内)デフォルトのSSHキーファイルを削除して、この展開スクリプトにそのリストを完全に制御できるようにします。
rm -f /home/ec2-user/.ssh/authorized_keys
(すぐ下のコードスニペット)AWS CLIを使用して、beanstalk-access
グループのユーザーのリストを取得し、そのJSONリストをjq
にパイプして、そのリストのみを抽出します`$ usersの。
users=$(aws iam get-group --group-name beanstalk-access | jq '.["Users"] | [.[].UserName]')
(すぐ下のコードスニペット)ここでは、そのJSON $users
リストをBASH配列に変換し、それを$users_array
と呼んでいます。
readarray -t users_array <<(jq -r '。[]' <<< "$ users")declare -p users_array
(すぐ下のコードスニペット内)ユーザーの配列をループし始めます。
for i in "${users_array[@]}"
do
(すぐ下のコードスニペット内)これはおそらく1行で実行できますが、beanstalk-access
グループの各ユーザーに関連付けられているSSHキーのリストを取得しています。まだBASH配列に変換されておらず、JSONリストのままです。
user_keys=$(aws iam list-ssh-public-keys --user-name $i)
keys=$(echo $user_keys | jq '.["SSHPublicKeys"] | [.[].SSHPublicKeyId]')
(すぐ下のコードスニペット内)これで、各ユーザーのSSHキーのJSONリストがBASH配列に変換されます。
readarray -t keys_array < <(jq -r '.[]' <<<"$keys")
declare -p keys_array
(すぐ下のコードスニペット内)これで、そのJSONリストがBASH配列に変換されます。
readarray -t keys_array < <(jq -r '.[]' <<<"$keys")
declare -p keys_array
(すぐ下のコードスニペット内)次に、各ユーザーのSSHキーの配列をループします。
for j in "${keys_array[@]}"
do
(すぐ下のコードスニペット内)各ユーザーの各SSHキーをauthorized_keys
ファイルに追加しています。
ssh_public_key=$(aws iam get-ssh-public-key --encoding SSH --user-name $i --ssh-public-key-id $j | jq '.["SSHPublicKey"] .SSHPublicKeyBody' | tr -d \")
echo $ssh_public_key >> /home/ec2-user/.ssh/authorized_keys
(すぐ下のコードスニペット内)$users_array
ループと$users_keys
ループの両方を閉じます。
done
done
(すぐ下のコードスニペット内)authorized_keys
ファイルに元の権限と同じ権限を付与します。
chmod 600 /home/ec2-user/.ssh/authorized_keys
chown ec2-user:ec2-user /home/ec2-user/.ssh/authorized_keys
Elastic Beanstalk EC2インスタンスがパブリックサブネットにある場合は、次を使用してSSHで接続できます。
ssh ec2-user@ip-address -i /path/to/private/key
Elastic Beanstalk EC2インスタンスがプライベートサブネットにある場合(クラウドセキュリティのベストプラクティスの場合)、EC2インスタンスへのすべてのSSHアクセスをトンネリングするためのゲートウェイとして機能する「要塞サーバー」EC2インスタンスが必要になります。 ssh agent forwarding
またはssh proxy commands
を調べて、SSHトンネリングを実行する方法を理解してください。
それらをIAMbeanstalk-access
グループに追加してデプロイを実行するだけで、そのスクリプトがそれらをElasticBeanstalkインスタンスに追加します。
echo
を実行してキーをGitに保存する代わりに、AWSのIAMユーザーに公開キーをアップロードすることができます。
commands:
copy_ssh_key_userA:
command: rm -f /home/ec2-user/.ssh/authorized_keys;aws iam list-users --query "Users[].[UserName]" --output text | while read User; do aws iam list-ssh-public-keys --user-name "$User" --query "SSHPublicKeys[?Status == 'Active'].[SSHPublicKeyId]" --output text | while read KeyId; do aws iam get-ssh-public-key --user-name "$User" --ssh-public-key-id "$KeyId" --encoding SSH --query "SSHPublicKey.SSHPublicKeyBody" --output text >> /home/ec2-user/.ssh/authorized_keys; done; done;