ruby - 如何使用以 ruby 启动的 SSM 端口转发会话的结果?
问题描述
我无法协调使用 aws cli 和 ruby sdk 与实例建立 ssm 连接之间的差异。例如,如果我尝试使用如下命令:
aws ssm start-session \
--target 'i-abc123' \
--document-name AWS-StartPortForwardingSession \
--parameters '{
"portNumber": ["3000"],
"localPortNumber": ["13000"]
}'
Starting session with SessionId: username-def456
Port 13000 opened for sessionId username-def456.
Waiting for connections...
Connection accepted for session [username-def456]
该工具将暂停,因为它打开了从目标实例上的端口 3000 到我的本地计算机上的端口 13000 的端口转发会话。然后,我可以在我的机器上打开一个 Web 浏览器并将其指向http://localhost:13000
以浏览远程实例上运行的应用程序。此外,我可以查看 AWS 控制台 UI 并看到有一个活动会话,直到我 Ctrl-C
我遇到的麻烦是当我尝试使用 ruby sdk 做同样的事情时:
result = ssm.start_session(
target: 'i-abc123',
document_name: 'AWS-StartPortForwardingSession',
parameters: {
'portNumber' => %w[3000],
'localPortNumber' => %w[13000]
}
)
该result
对象是一个结构,如下所示:
=> #<struct Aws::SSM::Types::StartSessionResponse
session_id="username-def456",
token_value="...",
stream_url="wss://ssmmessages.us-east-1.amazonaws.com/v1/data-channel/username-def456?
role=publish_subscribe">
同样,我可以在控制台 UI 中看到有一个活动会话。但是,如果我尝试http://localhost:13000
在我的机器上浏览,浏览器将无法访问任何内容。如何使用生成的流 url 和令牌来实际创建到 ec2 实例的连接?
额外细节:
- ruby sdk 的核心 gem 版本:3.109.2
- aws cli 版本 - aws-cli/2.1.16
- aws ssm 代理版本 - amazon-ssm-agent-3.0.356.0-1.x86_64
解决方案
您从 API 中得到的是对 Web 套接字的引用。因此,您要么需要为本地侦听器代理创建自己的 Web 套接字,要么像 aws cli 实用程序那样使用 session-manager-plugin。
我最近想出了如何使用 session-manager-plugin,下面的代码片段是 Python,但应该足够明显,可以弄清楚。
def start_aws_ssm_plugin(self, create_session_response, parameters, profile, region):
print('start_aws_ssm_plugin() called: ' + str( create_session_response))
arg0 = '"' + self.config.get_ssm_plugin() + '"'
arg1 = '"' + str(create_session_response).replace('\'', '\\"') + '"'
arg2 = region
arg3 = 'StartSession'
arg4 = profile
arg5 = '"' + str(parameters).replace('\'', '\\"') + '"'
arg6 = 'https://ssm.{region}.amazonaws.com'.format(region=region)
command = arg0 + ' ' + arg1 + ' ' + arg2 + ' ' + arg3 + ' ' + arg4 + ' ' + arg5 + ' ' + arg6
print(command)
# print('session-manager-plugin', arg1, arg2, arg3, arg4, arg5, arg6)
pid = subprocess.Popen(command).pid
return pid
# end def
(是的,这只是一个快速而肮脏的原型。;))
推荐阅读
- c# - 未加载资产的 Cefsharp 触发器
- java - Spring Boot 应用程序 - 406 Not Acceptable 错误,在本地工作正常,但在 AWS 上部署时不能
- javascript - Outlook 错误:发送消息时“加载项仍在工作”
- java-8 - 奇怪的TestNg DataProvider MethodMatcherException
- vba - 如何用 MS Access 表单中的数据填充 Microsoft Word 中的文本框?
- amazon-web-services - SQS 用多条记录/消息触发 Lambda?
- angular - 多次双击时的角垫图标背景颜色
- ubuntu - Ubuntu do-release-upgrade 检查不正确的地址 - 如何更改它的查找位置?
- angular - 在 Angular 应用程序中与单击事件绑定、禁用绑定和验证一起使用时,data-dismiss 不会关闭 Bootstrap 模式
- python-2.7 - 在 Windows 10 中,pip 导入错误:安装 pipenv 后无法导入名称 main