[AWS] 如何透過 Systems Manager(SSM) 來連線 Private EC2
照片來源:AWS Official website
前言
以往我們連接 private subnet 的 private EC2,會是去透過 Bastion host (跳板機)來進行 private EC2 的連線。
但我們真的需要跳板機才能進行連線嗎?今天將帶大家來使用 AWS Systems Manager (SSM)來取代 Bastion host (跳板機) ,並搭配 AWS CLI 和 proxy-command 來直接讓我們在終端機就可以連線到 private EC2,無需走外網,把安全性再提高一個層級。
行前準備
基礎設置
- 需要一個 AWS 帳戶,並且擁有 EC2 和 IAM 服務的使用權限。
- 準備好 VPC 和 VPC endpoints,以及 private subnet。
- 檢查 EC2 instance AMI 是否有順利安裝好
- 是否有安裝 AWS CLI(筆者使用版本是 v2)
- 安裝 aws-ssm-ec2-proxy-command plugin
P.S. VPC endpoints
的設置可以根據我們的需求,搭配下方前置文件的 5、6、7 點來進行設置。
IAM 設定
User(ssm-user)
- STS(Security Token Service)。
- AmazonEC2FullAccess。
- AmazonSSMFullAccess。
筆者這邊將使用者直接加入 AmazonSSMFullAccess
來使用 SSM 服務,但其實可以根據我們的需求,調整需要開放的權限即可,而不用到全開。
Role(ssm-ec2-role)
- AmazonEC2RoleforSSM。
我們將讓 EC2 instance 透過 AmazonEC2RoleforSSM
,讓我們的 EC2 可以被 AWS 套入角色,就可以使 EC2 來使用 SSM 的某些服務了。
透過 AWS CLI 建立 SSM session
當以上設定完成,我們將具備一個可以使用 SSM 的 EC2 instance,我們將使用終端機搭配 AWS CLI 來開啟 session。
根據 aws-ssm-ec2-proxy-command Readme 來設定
來到這邊,我們已經完成一半了,但離要在終端機,使用 ssh 連接機器,還有一項任務要完成。
由 AWS 文件 得知使用 ProxyCommand
來建立 ssh
連線,並和遠端機器搭起連線的橋樑,接下來我們將來完成這項任務。再次提醒,必須在前置作業完成的基礎下,才可以使用這種連線方式。
備註
SSH session 是建立一個 TCP 連線。
ProxyCommand 是SSH client 和 server 搭建連接通道的技術,建立一個通道加在另一個通道之上。因此我們透過 SSH session 來啟動 ProxyCommand 通道,進一步進行連線。
操作文件配置
- 新增
~/.ssh/aws-ssm-ec2-proxy-command.sh
,並貼上以下內容
#!/usr/bin/env sh
######## Source ################################################################
#
# https://github.com/qoomon/aws-ssm-ec2-proxy-command
#
######## Usage #################################################################
# https://github.com/qoomon/aws-ssm-ec2-proxy-command/blob/master/README.md
#
# Install Proxy Command
# - Move this script to ~/.ssh/aws-ssm-ec2-proxy-command.sh
# - Ensure it is executable (chmod +x ~/.ssh/aws-ssm-ec2-proxy-command.sh)
#
# Add following SSH Config Entry to ~/.ssh/config
# host i-* mi-*
# IdentityFile ~/.ssh/id_rsa
# ProxyCommand ~/.ssh/aws-ssm-ec2-proxy-command.sh %h %r %p ~/.ssh/id_rsa.pub
# StrictHostKeyChecking no
#
# Ensure SSM Permissions for Target Instance Profile
# https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-instance-profile.html
#
# Open SSH Connection
# ssh <INSTACEC_USER>@<INSTANCE_ID>
#
# Ensure AWS CLI environemnt variables are set properly
# e.g. AWS_PROFILE='default' ssh ec2-user@i-xxxxxxxxxxxxxxxx
#
# If default region does not match instance region you need to provide it like this
# ssh <INSTACEC_USER>@<INSTANCE_ID>--<INSTANCE_REGION>
#
################################################################################
set -eu
REGION_SEPARATOR='--'
ec2_instance_id="$1"
ssh_user="$2"
ssh_port="$3"
ssh_public_key_path="$4"
ssh_public_key="$(cat "${ssh_public_key_path}")"
if echo "${ec2_instance_id}" | grep -qe "${REGION_SEPARATOR}"
then
export AWS_DEFAULT_REGION="${ec2_instance_id##*${REGION_SEPARATOR}}"
ec2_instance_id="${ec2_instance_id%%${REGION_SEPARATOR}*}"
fi
>/dev/stderr echo "Add public key ${ssh_public_key_path} to instance ${ec2_instance_id} for 60 seconds"
aws ssm send-command \
--instance-ids "${ec2_instance_id}" \
--document-name 'AWS-RunShellScript' \
--comment "Add an SSH public key to authorized_keys for 60 seconds" \
--parameters commands="\"
mkdir -p ~${ssh_user}/.ssh
cd ~${ssh_user}/.ssh || exit 1
authorized_key='${ssh_public_key} ssm-session'
echo \\\"\${authorized_key}\\\" >> authorized_keys
sleep 60
grep -v -F \\\"\${authorized_key}\\\" authorized_keys > .authorized_keys
mv .authorized_keys authorized_keys
\""
>/dev/stderr echo "Start ssm session to instance ${ec2_instance_id}"
aws ssm start-session \
--target "${ec2_instance_id}" \
--document-name 'AWS-StartSSHSession' \
--parameters "portNumber=${ssh_port}"
- 新增
~/.ssh/config
host i-* mi-*
IdentityFile ~/.ssh/id_rsa
ProxyCommand ~/.ssh/aws-ssm-ec2-proxy-command.sh %h %r %p ~/.ssh/id_rsa.pub
StrictHostKeyChecking no
- 新增
~/.aws/config
[default]
region = ap-northeast-1
output = json
- 新增
~/.aws/credentials
[default]
aws_access_key_id = ...
aws_secret_access_key = ...
參閱文件: aws-ssm-ec2-proxy-command
使用 aws configure 來設定 configuration
參閱文件:aws-ssm-ec2-proxy-command
SSH 連線
ssh ec2-user@i-5xrubytest
結語
最後補充和複習:
- 透過 SSM Session Manager 我們可以不需要 Bastion host (跳板機) 以及管理 ssh key。
- 使用 Proxycommand 為我們建立 SSH Tunneling,讓我們更輕鬆及安全進行連線。
- 加上 AWS CLI SSO 驗證登入,讓系統安全性大幅提升。
以上是對 Systems Manager(SSM) 來連線 Private EC2
初步介紹,此篇文章有任何問題歡迎來信與我討論。 最後,希望透過這篇文章,能讓大家更輕鬆及安全進行連線。 謝謝你的閱讀!
想要閱讀更多來自五倍紅寶石軟體開發的技術分享?歡迎訂閱我們的月報,每月將自動幫你送上最新文章。