You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:37:03