How to configure nginx X-Forwarded-Port to be the originally request port

22,555

Solution 1

The only workaround I've found is to use a map rule to get the port from the http_host variable e.g.

    map $http_host $port {
      default 80;
      "~^[^\:]+:(?<p>\d+)$" $p;
    }

Solution 2

This is a just rough idea to write Nginx conf, but I am sure this can help you in redirection

server {    
    listen 80;  
    server_name host.docker.internal;   

    # By default land on localhost:80 to root so in root we copied UI build to the ngnix html dir.
    # have a look to docker-compose uiapp service.
    location / {    
            root   /usr/share/nginx/html;   
            index  index.html index.htm;    
    }   

   # after location add filter, from which every endpoint starts with or comes in endpoint 
   # so that ngnix can capture the URL and reroute it.
   # like /backend/getUserInfo/<UserId> 
   # In above example /backend is that filter which will be captured by Ngnix and reroute the flow.
    location /backend { 
        proxy_set_header X-Forwarded-Host $host;    
        proxy_set_header X-Forwarded-Server $host;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #proxy_pass http://<ContainerName>:<PortNumber>; 
        # In our case Container name is as we setup in docker-compose `beservice` and port 8080
        proxy_pass http://beservice:8080;   
    }   
}

For more details you can have a look at this project

https://github.com/dupinder/NgnixDockerizedDevEnv

Share:
22,555

Related videos on Youtube

Andrew Stubbs
Author by

Andrew Stubbs

Software Engineer

Updated on September 10, 2020

Comments

  • Andrew Stubbs
    Andrew Stubbs over 3 years

    I am using nginx in a standard reverse proxy scenario, to pass all requests to /auth to another host, however I'm trying to use non-standard ports.

    My end goal is to have the X-Forwarded-Port header set to the port that the request comes in on.

    Here is my location block in nginx.conf:

    location /auth/ {
        proxy_pass       http://otherhost:8090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port <VAR>;
    }
    

    This nginx is running in a docker container, that is configured to forward requests from 8085 into 80 in the container, such that the nginx process is listening on 80:

    0.0.0.0:8085->80/tcp

    When I hit the URL:

    http://localhost:8085/auth/

    I am correctly redirected to http://otherhost:8090, but the X-Forwarded-Port header is missing or wrong.

    Where I have <VAR> in the original block, I have tried the following:

    • $server_port - This is the port nginx is listening on (80), not the request port.

    • $pass_port - Seems to be null in my setup, so nginx drops the header.

    • $http_port - This is a random port per request.

    • $remote_port - This is a random port per request.

    I can change my config at deploy time to hardcode to the known port of incoming requests, but ideally I would be able to change the front port without any change to the nginx config.

    I've scoured the nginx variable list but can't find anything like $request_port. Is there any way for me to achieve my intent?

    • Mehdi
      Mehdi about 4 years
      Did you try $remote_port? Apart from that, I have difficulties to understand how the port nginx is listening to ($server_port) would be different from the request's port.
    • Andrew Stubbs
      Andrew Stubbs about 4 years
      @Mehdi - $remote_port also seems to be random per request. Requests hit the docker host on port 8085, which forward to the container on port 80, so nginx listens on 80 but the port in the URL is 8085.
  • Andrew Stubbs
    Andrew Stubbs almost 4 years
    Thanks for the answer but I don't think this is the case. $server_port is the port that the nginx process is listening on, not necessarily the port that the request was made to
  • Nicholi
    Nicholi over 3 years
    The documentation for server_port seems to indicate it is the port the request was made on. nginx.org/en/docs/http/ngx_http_core_module.html $server_port port of the server which accepted a request
  • user1383029
    user1383029 over 3 years
    If there is a load balancer in front of nginx, which gets a request from a client on port 8000, and redirects it to 8100, and the nginx listens on 8100, than $server_port is 8100. But the author needs the port from the original request (8000)