如何使用boto3通过ssm代理将文件发送到EC2实例的scp方式

4

您好,需要通过SSM代理将文件传输到EC2机器。我已成功在EC2实例中安装了SSM-Agent,并且从UI界面中可以通过"session-manager"启动会话,并登录到该EC2机器的shell。

现在我尝试通过boto3自动化此过程,并使用以下代码:

ssm_client = boto3.client('ssm', 'us-west-2') 
resp = client.send_command(
DocumentName="AWS-RunShellScript", # One of AWS' preconfigured documents
Parameters={'commands': ['echo "hello world" >> /tmp/test.txt']},
InstanceIds=['i-xxxxx'],
)

以上工作正常,我能够通过echo命令在远程机器上创建名为test.txt的文件。但我需要通过ssm代理从我的本地机器将文件发送到此远程ec2机器,因此我执行了以下操作,
修改了“/etc/ssh/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'"

在上面的代码中,我尝试使用以下代码启动一个会话,并且这也成功了。

response = ssm_client.start_session(Target='i-04843lr540028e96a')

我现在不确定如何使用此会话响应或使用此 AWS SSM 会话并发送文件。

环境描述: 来源:运行在 EKS 集群中的 pod 目标:EC2 实例(其中运行了 SSM agent) 要传输的文件:重要的私钥,将被 EC2 实例中的某些进程使用,并且对于不同的机器将是不同的

尝试的解决方案:

  • 我可以将文件推送到源中的 S3 中,并执行 SSM boto3 库可以从 S3 中拉取并存储在远程 EC2 实例中
  • 但由于我不想将私钥存储在 S3 中,因此希望可以直接从内存向远程 EC2 实例发送文件

基本上,我想实现的是在这篇 AWS 文档中提到的 scp:https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html#sessions-start-ssh


1
可能更容易将文件“拉入”实例中。例如,如果文件存储在Amazon S3中,则可以在shell脚本中放置aws s3 cp命令。 - John Rotenstein
3个回答

6
如果您已经设置了SSH over SSM,那么您可以使用普通的scp命令,如下所示:
scp file.txt ec2-user@i-04843lr540028e96a

如果无法正常工作,请确保完成以下操作:
  • 在本地安装Session Manager插件
  • 在实例和本地拥有您的密钥对(您需要在ssh配置或通过-i开关定义它)
  • 在实例上安装SSM代理程序(Amazon Linux 2默认安装)
  • 附加在实例上允许使用Session Manager的实例角色(需要在启动时存在,如果刚刚附加,请重新启动)

参考:https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html

如果您需要更多详细信息,请提供更多有关设置的信息,我将尝试提供帮助。


客户端是在EKS节点上运行的容器,服务器是安装了SSM代理的EC2机器。问题是我不能使用密钥,因为那样我需要将公钥添加到所有的EC2机器中,并且还需要使用我的私钥重新构建容器。因此,我正在寻找任何不需要使用密钥选项的解决方案,其中一种方法是通过S3推送文件,但由于安全问题,我无法使用S3发布数据,然后在我的脚本中使用。这意味着我只有两个选项可以通过SSM发送文件, 1)通过scp(带有密钥)上述步骤 2)通过S3 - Naggappan Ramukannan
我更新了我的问题,因为这是一个私钥,我无法将其保存到S3中,这个密钥将在我的服务中生成,该服务正在EKS上以POD的形式运行,并将被发送到EC2机器上(注意:每台机器都会发送不同的密钥)。 - Naggappan Ramukannan
如果我使用SNS/SQS,我需要在EC2机器上添加新的消费者来实现这个目的,但由于这些EC2机器有点像一些设备,所以这也是不可能的。 - Naggappan Ramukannan
哦,抱歉我没有一个好的答案。 我能想到的是你可以使用EC2实例连接,它允许你临时发送密钥到EC2: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html#ec2-instance-connect-connecting-aws-cli - Nathan Williams
18
为什么我需要SSH密钥对?SSM的整个意义就在于摆脱SSH密钥。 - Matteo
显示剩余2条评论

4
@Nathan Williams给出的答案令人困惑(scp file.txt ec2-user@i-04843lr540028e96a)。使用scp时,您需要使用SSH作为协议进行复制,因此您必须设置用户名/密码或用户名SSH密钥来复制文件。如果没有共享密钥、指定区域和配置文件,这个scp file.txt ec2-user@i-04843lr540028e96a是无法工作的。完整的命令应该类似于: scp -i keyfile file.txt ec2-user@i-04843lr540028e96a --region xxx --profile myprofile(如果您配置了默认配置文件和区域,则不需要在命令中添加它们)。我认为大多数人都只是希望通过ssm轻松地将文件传输到ec2实例,例如ssm cp file instancename,根据我的研究,这种方法并不存在。 @Matteo的说法是正确的,如果SSM的整个目的就是摆脱SSH密钥,那么为什么还需要SSH密钥呢?但基本上,您可以将SSM用作一种代理,以便无需指定实际IP地址即可访问EC2机器(可能实例没有公共IP,或者有公共IP的情况下,您必须在安全组中将源IP加入白名单),因此您可以通过SSM访问EC2实例的22端口,只需指定i-id进行身份验证(使用密钥和用户名)。SCP通过SSH工作,因此仍然需要一个密钥来使用它。再次强调,我认为大多数人只是希望简单地使用ssm cp file instance来传输文件。

更好的格式化答案可以提高可读性。 - Ruben

1

您可以将S3存储桶用作代理。唯一需要的是授予EC2访问S3的权限。这样,您就不必使用SSH协议在机器之间复制文件。

所有步骤都在此处解释


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接