使用 AWS SSM 的 SSH 日志记录和会话管理
已发表: 2022-03-11设置自定义工具或脚本以在 Linux 上保留 SSH 日志可能很乏味且容易出错。
工程师可以使用rootsh 、 screen或其他实用程序来记录用户活动,但如果用户权限设置不正确,熟练的用户可以删除审计日志以掩盖他们的踪迹。 另一种选择是在内核级别设置日志记录,但所需的专业知识并不常见。
值得庆幸的是,有一种方法可以记录用户活动,甚至无需编写单个 Linux 命令! 我们需要这些服务:
- EC2
- IAM(身份和访问管理)
- KMS(密钥管理服务)
- CloudWatch Logs(和/或 S3)
- AWS 系统管理器(以前称为 SSM)
让我们看看如何设置它们。
EC2 和 IAM
启动 EC2 实例通常相当容易,但在启动期间必须完成一项关键任务:我们需要将 IAM 角色附加到我们的实例,否则我们将无法实现本文末尾详述的预期结果文章。
我们与 EC2 实例关联的 IAM 角色必须具有内置的AmazonSSMManagedInstanceCore策略,以及此策略(附加为内联或客户管理):
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:DescribeLogGroups", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] }除了 IAM 角色,我们通常使用这个 EC2 实例配置:
- 操作系统是 Amazon Linux 2,因为默认情况下它安装了 AWS Systems Manager 代理(SSM 代理)。 (Ubuntu 发行版也是如此,这也是一种选择。)
- 实例类型是 t3.micro(但任何类型都可以)。
- AWS 分配给 VPC 的默认安全组将起作用,因为我们不需要为此练习打开 SSH 端口。
我们可以开始设置 KMS,而无需等待 EC2 实例启动。
知识管理系统
如果我们希望传送到 CloudWatch 的所有会话日志都以加密方式存储,我们需要一个 KMS 密钥。 让我们转到 KMS 服务并创建一个密钥。
我们建议分配一个管理员,以便 AWS 账户根用户以外的用户可以管理密钥,但如果其他人不需要访问,我们可以跳过第 3 步。
在这里,我们选择了 IAM 用户“admin”作为密钥管理员,但我们可以自由选择任何用户或角色。 我们还可以选择禁用管理员的密钥删除权限。
我们不会将任何用户分配给此密钥,因为我们希望此密钥仅供 CloudWatch Logs 服务用于 SSH 日志加密和解密操作。
在 Review 页面上,我们需要更改 KMS 生成的密钥策略,因为它不包括 CloudWatch Logs 使用密钥的权限。 我们将用此策略替换它:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow access for Key Administrators", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:user/USERNAME" }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:TagResource", "kms:UntagResource", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" }, { "Sid": "Allow access to CloudWatch Log", "Effect": "Allow", "Principal": { "Service": "logs.REGION.amazonaws.com" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "*", "Condition": { "ArnLike": { "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:REGION:ACCOUNT_ID:*" } } } ] }确保替换所有占位符:
-
ACCOUNT_ID成为我们的 AWS 账户 ID。 -
USERNAME成为在步骤 3 中选择的管理员用户名。如果我们选择退出该步骤,则在此处删除第二个语句块(带有"Sid": "Allow access for Key Administrators")。 -
REGION成为我们将服务部署到的区域标识符代码(例如us-west-1)。
有了这个,KMS 准备好了。
CloudWatch 日志组
接下来,我们需要一个 CloudWatch Log 组(和/或一个 S3 存储桶——见下文),SSM 代理可以在其中发送 SSH 会话日志。 让我们创建它。
请注意 KMS 密钥 ARN 字段:在 KMS 部分的第 5 步中创建密钥后,AWS 会在此处为我们提供所需的值。
(如果我们之前没有将正确的策略与我们的 KMS 密钥相关联,允许 CloudWatch Logs 服务使用该密钥,此时我们将收到与 KMS 密钥相关的错误。)
将 SSH 日志存储在 S3 存储桶中
为了使用 S3 存储活动日志而不是 CloudWatch Logs,我们需要将这些权限作为单独的策略添加到我们的 EC2 实例配置文件(或手动将它们与我们可能需要关联的其他权限组合):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::BUCKET_NAME/*" }, { "Effect": "Allow", "Action": [ "s3:GetEncryptionConfiguration" ], "Resource": "*" }, { "Effect": "Allow", "Action": "kms:GenerateDataKey", "Resource": "*" } ] } 在上面的代码段中,请务必替换BUCKET_NAME占位符。

既然我们已经设置了存储日志的位置(CloudWatch Logs、S3 存储桶或两者兼而有之),我们就可以利用 SSH 会话了。
AWS Systems Manager 会话管理器
这是最后一个关键步骤,我们在其中配置对 Linux 机器的安全访问以进行 SSH 会话监控和日志记录。 我们将从会话管理器仪表板开始。
在仪表板上,单击右上角“开始会话”框中的白色“配置首选项”按钮以启用会话日志记录。
在 Preferences 页面上,我们将找到多个可以探索的部分,但我们的重点将是将 SSH 会话日志流式传输到 CloudWatch 或 S3,以使我们能够快速查看 Linux 机器中发生的情况。
在“CloudWatch 日志记录”部分之后,有一个“S3 日志记录”部分,我们可以在其中选择存储桶。
配置 SSH 日志记录后,我们可以通过 SSH 连接到我们的 Linux 机器并执行一些命令来查看活动是否被捕获。
所以,让我们开始一个会话。 在同一页面上,我们将找到一个“会话”选项卡,我们可以在其中开始会话。 单击“开始会话”按钮将为我们提供一个 EC2 机器列表,我们可以在这些机器上启动会话:
如果我们没有在列表中看到我们的 EC2 Linux 实例,我们应该检查它是否处于运行状态并具有与它相关联的 IAM 权限,如前所述。
处理 SSM 代理“不支持流式日志”错误
如果我们收到错误消息说安装在我们的 EC2 机器上的 SSM 代理版本不支持流式 CloudWatch 日志,请不要担心。 有一种无痛的方法可以解决这个问题。
要更新 SSM 代理,我们需要导航到AWS Systems Manager服务左侧面板中的Run Command 。
到达那里后,我们可以单击橙色的“运行命令”按钮,进入一个新页面,我们可以在其中填写一些参数。
我们首先从列表中选择AWS-UpdateSSMAgent 。
选择后,我们将向下滚动,直到看到“目标”部分。 在那里,我们需要选择要更新 SSM 代理的 EC2 实例,然后在最后点击“运行”按钮。 这会将我们发送到可以监控更新进度的页面。
代理更新不应超过五分钟。 一旦完成,我们应该能够在会话管理器中创建一个会话。
此时,我们应该启动了一个 SSH 会话。
执行几个命令后,让我们导航到 CloudWatch Logs 日志组(或我们的 S3 存储桶,未显示)并确认正在记录活动。
我们现在有了一个启用静态加密的设置,记录在我们的 Linux 机器中触发的每个命令。
事实上,每个命令都可能超出我们的预期:会话期间提供或生成的任何秘密都将记录在 CloudWatch 或 S3 中,任何拥有所需权限的人都可以看到。 为了防止这种情况,我们可以使用stty -echo; read passwd; stty echo; stty -echo; read passwd; stty echo; 对于我们需要在会话期间提供的每个秘密。
一个很棒的 SSM/SSH AWS 日志记录解决方案,有一些小注意事项
会话管理器是一个有用的工具,可以在无需打开端口 22 的情况下远程访问我们在 AWS 中的虚拟机。事实上,如果我们使用端口转发或直接 SSH 连接,我们无法以这种方式生成 SSH 日志,因为会话管理器文档说明。
尽管如此,将会话管理器与会话记录相结合是控制和监视虚拟机内活动的强大解决方案。 此外,我们不收取使用 Session Manager 服务的费用。 我们只需为我们的 EC2 实例和 CloudWatch Logs 或用于存储日志的 S3 存储桶付费。
对于喜欢视频教程的读者,我在 YouTube 上更彻底地介绍了一个非常相似的过程。
进一步阅读 Toptal 工程博客:
- 案例研究:为什么我将 AWS 云基础设施用于我的产品
