如何配置AWS SSM端口转发以允许非localhost来源的连接?
问题
在Docker容器中通过AWS CLI调用EC2实例上的SSM服务,建立到远程主机的端口转发会话,并将容器内5432端口映射到宿主机同端口,但宿主机连接该端口时会立即断开。容器内访问localhost:5432连接正常,推测是SSM端口转发默认仅允许localhost来源的连接,宿主机的请求不被识别为合法来源。
相关信息
官方SSM文档AWS-StartPortForwardingSessionToRemoteHost内容
{ "schemaVersion": "1.0", "description": "Document to start port forwarding session over Session Manager to remote host", "sessionType": "Port", "parameters": { "portNumber": { "type": "String", "description": "(Optional) Port number of the server on the instance", "allowedPattern": "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", "default": "80" }, "localPortNumber": { "type": "String", "description": "(Optional) Port number on local machine to forward traffic to. An open port is chosen at run-time if not provided", "allowedPattern": "^([0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", "default": "0" }, "host": { "type": "String", "description": "(Optional) Hostname or IP address of the destination server", "allowedPattern": "^[^,$^&\\(\\)!;'\\"<>\\`{}\\[\\]\\|#=]{3,}$", "default": "localhost" } }, "properties": { "portNumber": "{{ portNumber }}", "type": "LocalPortForwarding", "localPortNumber": "{{ localPortNumber }}", "host": "{{ host }}" } }
Dockerfile
FROM amazon/aws-cli RUN curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm" && yum install -y ./session-manager-plugin.rpm && yum install -y telnet
Docker运行命令
docker run \ --rm \ -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \ -p 5432:5432 \ -ti \ awscli-ssm \ ssm start-session \ --target <my-ec2-instance-id> \ --region <my-region> \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["<my-rds-host>.rds.amazonaws.com"],"portNumber":["5432"], "localPortNumber":["5432"]}'
测试结果
- 容器内访问正常:
bash-4.2# telnet localhost 5432 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
- 容器外访问立即断开:
chris@chris-machine:~$ telnet localhost 5432 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host.
解决方案
问题根源是SSM的LocalPortForwarding默认将转发端口绑定到127.0.0.1,仅允许容器内部访问。要支持宿主机连接,需将端口转发绑定到0.0.0.0以接受所有来源的请求,具体步骤如下:
1. 创建自定义SSM文档
复制官方文档内容,新增bindAddress参数并在properties中设置默认绑定地址为0.0.0.0:
{ "schemaVersion": "1.0", "description": "Custom document to start port forwarding session over Session Manager to remote host (allow external connections)", "sessionType": "Port", "parameters": { "portNumber": { "type": "String", "description": "(Optional) Port number of the server on the instance", "allowedPattern": "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", "default": "80" }, "localPortNumber": { "type": "String", "description": "(Optional) Port number on local machine to forward traffic to. An open port is chosen at run-time if not provided", "allowedPattern": "^([0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", "default": "0" }, "host": { "type": "String", "description": "(Optional) Hostname or IP address of the destination server", "allowedPattern": "^[^,$^&\\(\\)!;'\\"<>\\`{}\\[\\]\\|#=]{3,}$", "default": "localhost" }, "bindAddress": { "type": "String", "description": "(Optional) IP address to bind the local forwarding port to. Use 0.0.0.0 to allow external connections", "default": "0.0.0.0" } }, "properties": { "portNumber": "{{ portNumber }}", "type": "LocalPortForwarding", "localPortNumber": "{{ localPortNumber }}", "host": "{{ host }}", "bindAddress": "{{ bindAddress }}" } }
将该文档上传至AWS SSM,命名为Custom-StartPortForwardingSessionToRemoteHost(或自定义名称)。
2. 修改Docker运行命令
使用自定义SSM文档启动端口转发会话:
docker run \ --rm \ -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \ -p 5432:5432 \ -ti \ awscli-ssm \ ssm start-session \ --target <my-ec2-instance-id> \ --region <my-region> \ --document-name Custom-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["<my-rds-host>.rds.amazonaws.com"],"portNumber":["5432"], "localPortNumber":["5432"]}'
若需显式指定绑定地址,可在--parameters中添加"bindAddress":["0.0.0.0"],默认已配置该值可省略。
3. 验证
在宿主机重新执行telnet localhost 5432,连接应能正常保持。
补充说明
- 官方
AWS-StartPortForwardingSessionToRemoteHost文档未暴露bindAddress参数,因此必须通过自定义文档实现允许外部连接的功能。 - 绑定
0.0.0.0后,容器内的转发端口会接受所有来源请求,结合Docker端口映射,宿主机的请求可被正确转发至SSM会话。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

