Search code examples
phpsymfonyportforwarding

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


This might not be specific to Symfony since the client-side port number is not visible in the $_SERVER superglobal.

Occasionally, I use SSH local port forwarding to preview an AWS ElasticBeanstalk application that lives in the private subnet (not accessible from the internet).

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

Where the bastion host is in the public subnet, and can make HTTP requests to servers in the private subnet.

When I run this command, I can visit the site at http://localhost:8088/

This works well, unless a part of the site requires the port number - at least in Symfony anyway. When part of the site raises a 403 Forbidden response because authentication is required, Symfony will perform a redirect to a login page, using Symfony\Component\Security\Http\HttpUtils::createRedirectResponse().

It tries to redirect to a URL using $requst->getSchemeAndHttpHost() as the base. However, this removes the port number as it has determined the port to be 80 instead of 8088.

Inspecting the $_SERVER value in Xdebug reveals:

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

The port number 8088 in the original request is not visible anywhere.


Solution

  • There is no way Symfony (actually Webserver) can get your local address, there are 2 possible ways to solve the issue:

    1. Make the private network accessible through a reverse proxy on the public one.
    2. Setup reverse proxy on your work machine (like nginx) so that it will accept requests for workproject.local domain, add headers like X-Forwarded-For and X-Real-Ip to incoming requests and pass these requests through the tunnel.

    In any way you also have to configure symfony to work under a reverse proxy, for more information read the official docs: How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy