在传统云服务器管理中,远程登录通常依赖:

  • SSH 密钥
  • Bastion Host
  • 公网 IP

但在安全要求较高的环境中,这些组件往往带来新的风险:

  • SSH 密钥难以集中审计
  • 堡垒机成为高价值攻击目标
  • 公网暴露扩大攻击面

借助 AWS Systems Manager 的 Session Manager,我们可以实现一种更安全的登录模式:

  • 不需要公网 IP
  • 不需要 SSH 密钥
  • 所有操作自动审计
  • 会话日志可使用 AWS KMS 加密

最终效果

登录命令:

1
aws ssm start-session --target i-xxxxxxxx

登录后:

  • 无 SSH
  • 无 Bastion
  • 所有操作被记录
  • 会话日志可加密存储

整体架构图

QQ_1772245984422

数据流说明

  1. 用户通过 aws-cli 发起 Session 请求
  2. Session Manager 建立 TLS 控制通道
  3. 实例中的 SSM Agent 建立反向连接
  4. 会话日志输出到
    • Amazon CloudWatch
    • Amazon S3
  5. 日志使用 KMS 加密存储

前提条件

实例必须满足:

  • 已启用 Amazon EC2
  • 安装 SSM Agent(Amazon Linux 默认已安装)
  • 具备 IAM Role
  • 能访问 SSM endpoint(公网或 VPC Endpoint)

创建 KMS Key

进入控制台:

1
KMS → Create Key

Clipboard_Screenshot_1772241474

建议配置:

Key typeSymmetric
UsageEncrypt/Decrypt
Aliasalias/ssm-session-key

此 key 用于:

  • 会话加密
  • CloudWatch 日志加密
  • S3 日志加密

为 EC2 配置 IAM Role

要让实例能够被 Session Manager 管理,本质上需要让实例具备两类权限:

  1. AWS Systems Manager 建立控制通道
  2. 使用 AWS KMS 对会话数据解密

因此 IAM Role 是整个架构中最关键的一环。

创建实例角色

进入:

1
IAM → Roles → Create role

选择:

1
2
Trusted entity type: AWS service
Use case: EC2

这一步的作用是允许 Amazon EC2 实例“扮演”这个角色。

Clipboard_Screenshot_1772241874

附加基础 SSM 权限

添加 AWS 官方托管策略:

1
AmazonSSMManagedInstanceCore

该策略已经包含:

  • 注册实例到 SSM
  • 建立控制通道
  • 接收会话指令
  • 上报实例信息

如果没有这个策略,实例将不会出现在 SSM 管理列表中。

Clipboard_Screenshot_1772241906

Clipboard_Screenshot_1772241977

添加 KMS 会话解密权限(关键)

如果你启用了 Session Manager KMS 加密,则必须允许实例使用密钥。

QQ_1772242175739

创建一个内联策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowKMSForSessionManager",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
      ],
      "Resource": "arn:aws:kms:REGION:ACCOUNT:key/KEY-ID"
    }
  ]
}

Clipboard_Screenshot_1772242284

QQ_1772242329006

说明:

权限作用
kms:Decrypt解密会话数据
kms:GenerateDataKey为会话生成数据密钥

没有这两个权限时,常见报错是:

1
AccessDeniedException: KMS access denied

(可选)允许写入 CloudWatch 日志

如果启用了 Session 日志记录,还需要日志权限:

1
2
3
4
5
6
7
8
{
  "Effect": "Allow",
  "Action": [
    "logs:CreateLogStream",
    "logs:PutLogEvents"
  ],
  "Resource": "*"
}

若日志写入失败,Session 会正常,但不会产生审计记录。

将 Role 绑定到 EC2

进入:

1
EC2 → Instances → 选择实例

操作:

1
Actions → Security → Modify IAM Role

选择你创建的 Role。

QQ_1772242388228

QQ_1772242412561

QQ_1772242466498

⚠️ 注意:

  • 修改后通常 需重启实例,否则角色不会生效

验证实例是否成功接管

本地执行:

1
aws ssm describe-instance-information

QQ_1772243941325 如果能看到实例 ID,说明:

  • IAM Role 正常
  • Agent 正常
  • 网络正常
  • 权限完整

最小权限模型建议(生产环境)

在生产环境中建议:

  • 不要直接使用 * Resource
  • 限制为具体 KMS Key
  • 限制为具体 Log Group
  • 使用条件限制来源 VPC / IAM Principal

这样可以避免:

  • 横向密钥滥用
  • 非预期日志写入
  • 权限漂移

启用 Session Manager KMS 加密

进入:

1
Systems Manager → Session Manager → Preferences

开启:

1
☑ Enable KMS encryption

选择:

1
alias/ssm-session-key

保存。

QQ_1772242820092

此后:

  • 会话在 TLS 之外再加一层 KMS 加密
  • 交互数据受密钥管控

本地准备 aws-cli

1
aws ssm start-session --target i-xxxxxxxx

如果 KMS 已启用,会看到:

1
This session is encrypted using AWS KMS.

说明:

  • TLS 加密已启用

  • KMS 会话加密生效

  • 日志记录成功

    QQ_1772244971183

    QQ_1772245022110

    QQ_1772245083008

安全收益

使用 Session Manager + KMS 后:

能力状态
无需 SSH
无需公网 IP
命令审计
日志加密
统一密钥管理
零信任访问模型

本质上,这套架构实现了:

基于身份与审计的远程访问,而非基于网络边界

推荐用于:

  • 金融 / 政务云
  • 合规要求高的企业
  • 零信任网络架构
  • 不允许 SSH key 的组织

更多拓展内容

CloudTrail vs CloudWatch 的区别

最简单的一句话区分:

CloudTrail 记录“谁调用了 AWS API” CloudWatch 记录“系统运行了什么”

AWS CloudTrail:API 审计日志

CloudTrail 记录的是:

  • 谁调用了 AWS API
  • 什么时候调用
  • 调用了什么资源
  • 是否成功

例如:

行为CloudTrail 是否记录
用户执行 aws ssm start-session
用户 Attach IAM Role
用户删除 EC2
用户在服务器执行 rm -rf

CloudTrail 关注的是:

云控制面的操作

也就是“管理动作”。

Amazon CloudWatch:系统与应用日志

CloudWatch 记录的是:

  • EC2 系统日志
  • 应用日志
  • Session Manager 命令日志
  • metrics

例如:

行为CloudWatch 是否记录
用户登录 Session
执行 sudo yum update✅(若开启 session logging)
应用写入日志
用户调用 AWS API❌(这是 CloudTrail 的职责)

CloudWatch 关注的是:

资源运行时发生了什么

也就是“行为日志”。

对比项CloudTrailCloudWatch
记录对象API 调用系统行为
关注层面控制面数据面
记录登录操作记录开始会话记录执行命令
审计用途合规 / 安全审计运维 / 故障排查

Session Manager 登录用户的权限如何控制?

这是最关键的设计问题。

要理解一点:

Session Manager 不是 SSH 登录 它本质上是 通过 IAM 控制登录权限

权限控制分成两层:


第一层:谁可以登录实例

控制点:IAM 用户 / Role 权限

通过策略控制谁可以调用:

1
ssm:StartSession

示例策略:

1
2
3
4
5
6
7
8
{
  "Effect": "Allow",
  "Action": "ssm:StartSession",
  "Resource": [
    "arn:aws:ec2:REGION:ACCOUNT:instance/i-123456",
    "arn:aws:ssm:*:*:document/AWS-StartInteractiveCommand"
  ]
}

第二层:登录后拥有 Linux 什么权限

这一层 IAM 不控制 而是由 实例内部的操作系统 决定。

Session Manager 默认登录用户:

AMI默认用户
Amazon Linuxssm-user
Ubuntussm-user
WindowsAdministrator

如何给 Session 登录用户 sudo 权限

方法一(推荐):使用 ssm-user + sudo

在实例执行:

1
sudo usermod -aG wheel ssm-user

或 Ubuntu:

1
sudo usermod -aG sudo ssm-user

然后测试:

1
sudo whoami

返回 root 即成功。

这是 AWS 官方推荐方式。

方法二:通过 Session 文档指定用户

你可以让 Session 直接以 root 启动:

创建自定义 SSM Document:

1
2
3
4
5
6
7
8
9
{
  "schemaVersion": "1.0",
  "description": "Start root session",
  "sessionType": "Standard_Stream",
  "inputs": {
    "runAsEnabled": true,
    "runAsDefaultUser": "root"
  }
}

然后用户必须通过该 Document 登录。

这种方式适合:

  • 审计要求高
  • 想明确区分 root 登录

如何做企业级权限模型(推荐架构)

生产环境通常这样设计:

IAM 控制“谁能登录”

角色权限
DevOps可登录所有实例
开发人员只能登录测试实例
审计人员只读日志

OS 控制“登录后能干嘛”

用户权限
ssm-user普通运维
ssm-adminsudo
root仅紧急使用

CloudTrail + CloudWatch 双审计

审计类型工具
谁登录了实例CloudTrail
登录后执行了什么CloudWatch Session Logs