管理一个远程机器最常规的做法是 SSH(Unix/Linux, Mac) 或 PowerShell/RDP(Windows),这就要求远端机器要开通相应的访问端口及打开防火墙,配置好登陆用的用户名密码或 SSH Key。当选择一个 EC2 实例的时候,可以点击 "Connect" 按,它提供有三种连接选择:
- EC2 Instance Connect: 要求 EC2 配置了 SSH Key, 启动了 sshd 并开启了 ssh 的 Security Group,还要在实例上安装了
ec2-instance-connect
(如安装命令 sudo yum install ec2-instance-connect) - Session Manager: 这就是我们本文要讲述的,sshd 不用启动,Security Group 只要求能往连接外部的 443 端口,SSH Key 不需要
- SSH client: 客户端 SSH 到 EC2 实例,需要打开 sshd 其 22 号端口接受连接的 Security Group,用 SSH Key 或 AMI 中的用户名和密码,或配置加入了域后使用域帐号验证登陆
AWS 的 Session Manager 提供了通过浏览器或 AWS CLI 来访问 EC2 实例,甚至是本地机房的机器或虚拟机(需 advanced-instances tier 的支持),不再依赖于 SSH。
Session Manager 概要
Session Manager 决定谁能不能访问是由 IAM 访问策略来控制的。可通过本地端口转发,会话中的操作日志可记录下来作为审计,会话的开始或结束可设置发送消息到 Amazon EventBridge 或 SQS。日志或会话通读可由 KMS key 进行加密码。
支持 Session Manager 访问的 EC2 的基本条件就是要运行 SSM Agent。SSM Agent 在自身版本升级中陆续的增加了各种功能的支持,如用 KMS Key 加密,端口转发和 SSH 会话,日志功能等,总之安装最新版本就没错,当前版本
SSM Agent 会创建一个叫作 ssm-user
的用户,它具有根用户或超级管理员的权限。要能在 EC2 上启动 SSM Agent 的话,IAM Role 最简单的配置上加上 AmazonSSMManagedInstanceCore 这个策略,或者根据需求参照着 Adding Session Manager permissions to an existing instance profile 来添加所需的权限。
Session Manger 控制台,到 https://console.aws.amazon.com/systems-manager/, 点 Start session, 从列表中选择启动了 SSM Agent 的 EC2 实例
或在 EC2 的实例界面 https://console.aws.amazon.com/ec2/,选择一个 EC2 实例,点击上方的 Connect 按钮,如果访实例已启动 SSM Agent, 则可在下一界面选择用 Session Manager 来连接。
AWS CLI 启动 ssm: aws ssm start-session --target i-0c0072d1212832d20 -- 需给 AWS CLI 安装 Session Manager 插件
前面是在别人帮你配置好了 EC2 支持 Session Manager 的情况下我们可用的各种连接方式,下面自己来动手怎么配置一个能支持 Session Manager 连接的 EC2 实例。
Session Manager 连接 EC2 实例
以 Amazon ECS-Optimized Amazon Linux 2 AMI(2.0.20210121) 镜像版本为例,可参考 Manually install SSM Agent on EC2 instances for Linux
首先需要创建一个启动 EC2 的 role, 并附上 AmazonSSMManagedInstanceCore 策略,可命名为 es2_role_with_ssm_agent。启动一个 EC2 实例,选取 Amazon ECS-Optimized Amazon Linux 2 AMI 镜像。Security Group 的要求是只要能访问外部机器的 443 端口就行。
待到 EC2 实例创建后就可以选择它,并点击 Connect
按钮, Session Manager 中的 Connect 按钮就会变得可用,连接就进到了 Bash 的命令行下。登陆用户为 ssm-user
, 具有最高级的权限。
登陆后,验证几个事实
这里列出 EC2 实例能被 Session Manager 连接管理的基本条件:
- EC2 IAM role 要求附着了 AmazonSSMManagedInstanceCore 这个策略,或手工添加了相应的权限,这个角度会用来创建具有根用户权限的
ssm-user
, Session Manager 将采用这个用户登陆。 - Security Group 要求 EC2 能连接外部的 443 端口,比如 0.0.0.0:443,Session Manager 的通信方式是 EC2 用某个 IP 的 443 端口作为代理,所以不需要 SSH 服务
- EC2 上必须启动 ssmagent, 列进程时会看到
/usr/bin/amazon-ssm-agent
和/usr/bin/ssm-agent-worker
两个驻留进程。每登入进来一个用户创建一个ssm-session-worker
进程
注:如果 EC2 的 role 没有 AmazonSSMManagedInstanceCore 策略的相应权限也能启动 ssmagent, 但无法创建 ssm-user
,这时候 Session Manager
也会认为这个 EC2 实例是可连接的,实际却无法连接。
前面我们选择的 AMI Amazon ECS-Optimized Amazon Linux 2 AMI(2.0.20210121) 已经内置了自动启动 ssmagent,但没有 AmazonSSMManagedInstanceCore 策略权限就无法创建 ssm-user
这个用户。
假如选择的 AMI 没有内置启动 ssmagent,以 Amazon Linux 2 为例,就需要把在 EC2 的 userdata 中加上下面的行
sudo yum install -y https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
自己随便选择一个区域的 s3 链接就行,并不要求 us-east-1 的 EC2 只能下载 us-east-1 的 rpm 包。不同的 Linux 发行版本安装方式略有不同
装完后 ssm-agent 应该是自动启动的
连接 Session Manager 的其他方式
前面直接找到 EC2 实例进行 Session Manager 连接,也可进到 Session Manager 的控制台选择启动了 ssmagent 的 EC2 实例发起连接,它们都是 Web 的方式连接会话的。下面是其他几种方式。
本地启动 AWS CLI session
本地除安装了 AWS CLI 外,需安装 Session Manager Plugin((Optional) Install the Session Manager plugin for the AWS CLI, 找好自己的平台来安装)。完后只要指定 EC2 实例的 ID 就能连接,而无需 IP 地址。
$ aws ssm start-session --target i-0c0072d1212832d20
Starting session with SessionId: yanbin@example.com-0f3cabb8dd1bf0bb4
sh-4.2$ hostname
p-172-31-60-8.ec2.internal
这种方式显得很专业,与 Web 的 Session Manager 连接 EC2 实例一样,看似 SSH, 其实根本不需要 EC2 主机上启动 sshd 服务。但是必须在本地配置好连接 AWS 的 profile, 或 session key 和 secret key。如果没有安装 Session Manager Plugin 的话,运行 aws ssm start-session 时会提示
SessionManagerPlugin is not found. Please refer to SessionManager Documentation here: http://docs.aws.amazon.com/console/systems-manager/session-manager-plugin-not-found
本地验证关闭 SSH 服务后也能用 Session Manager 进行连接
$ telnet 10.255.57.211 22
Trying 10.255.57.211...
$ aws ssm start-session --target i-0c0072d1212832d20
Starting session with SessionId: yabqiu@gmail.com-06065c404df8b1cbe
sh-4.2$ sudo service sshd status
openssh-daemon is stopped
sh-4.2$ netstat -na|grep :22
sh-4.2$
再次用 Session Manager 进行连接
$ aws ssm start-session --target i-0c0072d1212832d20
Starting session with SessionId: yanbin@example.com-0f3cabb8dd1bf0bb4
sh-4.2$ hostname
p-172-31-60-8.ec2.internal
再进一步探究 Session Manager 是如何通信的,分别到 EC2 实例和运行 aws ssm start-session
的本地机器查看网络连接情况
于是很容易得到下面的连接过程
这就能理解为什么 Session Manager 不需要 SSH 及打开相应的 22 号端口了
客户端 SSH over session manager
参考 Step 8: (Optional) Enable SSH connections through Session Manager
在客户端配置文件 ~/.ssh/config 中加上
# SSH over Session Manager
host i-* mi-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
不过现在需要 EC2 实例打开 sshd 服务,但仍然不需要为 22 开启防火墙
客户端执行
ssh -i ~/path/my-key-pair.pem ec2-user@i-0c0072d1212832d20
......
[ec2-user@ab-0aff39d3 ~]$
scp 也行,用 scp -i /path/my-key-pair.pem test.txt ec2-user@i-0c0072d1212832d20
这种方式与上面唯一不同之处就是 EC2 上的 ssmagent 与 EC2 本机的 SSH 服务进行通信,而不是直接与本地的 shell 交互。
连接图
端口转发服务
有点像 SSH Tunnel(ssh -A -L :56789:10.255.57.64:80), 我们也能利用 Session Manager 进行端口转发,命令如下:
aws ssm start-session \
--target instance-id \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["80"], "localPortNumber":["56789"]}'
访问 http://localhost:56789 就能访问到远端 EC2 的 80 端口。
关于 Session Manager 的 documents 的用法请参考 AWS System Manager documents。
本文链接 https://yanbin.blog/aws-session-manager-ec2-instance/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
[…] aws ecs execute-command 直指容器本身。参考本人写过的一篇 AWS Session Manager 管理 EC2 实例,连接过程中唯一的不同就是容器中也运行了一个 SSM Agent, […]
[…] aws ecs execute-command 直指容器本身。参考本人写过的一篇 AWS Session Manager 管理 EC2 实例,连接过程中唯一的不同就是容器中也运行了一个 SSM Agent, […]
[…] AWS SSM 连接到 Windows EC2 实例的 PowerShell,Linux 可参考 AWS Session Manager 管理 EC2 实例。连接 Windows 的 Session Manager 也类似,两个基本条件,SSM Agent + 有 […]