在 Symfony 中为通过 SSH 本地端口转发发送的请求获取客户端端口号

Get client-side port number in Symfony for request sent via SSH local port forwarding

这可能不是 Symfony 特有的,因为客户端端口号在 $_SERVER 超全局中不可见。

有时,我使用 SSH 本地端口转发来预览位于私有子网(无法从 Internet 访问)中的 AWS ElasticBeanstalk 应用程序。

 $ ssh -L 8088:helloworld.eu-west-1.elasticbeanstalk.com:80 bastion

其中 bastion 主机位于 public 子网中,并且可以向私有子网中的服务器发出 HTTP 请求。

当我运行这个命令时,我可以访问位于http://localhost:8088/

的站点

这很好用,除非站点的一部分需要端口号——至少在 Symfony 中是这样。当站点的一部分因为需要身份验证而引发 403 Forbidden 响应时,Symfony 将使用 Symfony\Component\Security\Http\HttpUtils::createRedirectResponse() 执行重定向到登录页面。

它尝试使用 $requst->getSchemeAndHttpHost() 作为基础重定向到 URL。但是,这会删除端口号,因为它已将端口确定为 80 而不是 8088

检查 Xdebug 中的 $_SERVER 值显示:

HTTP_X_FORWARDED_PORT = 80 HTTP_X_FORWARDED_FOR = 10.0.0.48 HTTP_HOST = localhost SERVER_PORT = 80 SERVER_ADDR = 10.0.2.70 REMOTE_PORT = 44348 REMOTE_ADDR = 10.0.3.215

原始请求中的端口号8088在任何地方都不可见。

Symfony(实际上是网络服务器)无法获取您的本地地址,有 2 种可能的方法可以解决此问题:

  1. 通过 public 上的反向代理使专用网络可访问。
  2. 在您的工作机器(如 nginx)上设置反向代理,以便它接受对 workproject.local 域的请求,将 headers 如 X-Forwarded-ForX-Real-Ip 添加到传入请求并通过隧道传递这些请求。

无论如何你还必须配置 symfony 在反向代理下工作,更多信息阅读官方文档: How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy