Nginx Redirect to Different IP Based on Port Number

nginx

I have multiple HTTP servers (IoT stuff) connected to a Raspberry Pi with a Nginx instance. I want to proxy the access to those servers through Nginx by using its IP address and multiple ports:

192.168.1.100:8080 -> 192.168.2.80
192.168.1.100:8081 -> 192.168.2.81
...

I have this configuration in Nginx which works:

server {
    listen  8080;
    location / {
        proxy_pass http://192.168.2.80;
        ..... extra config
    }
}

However, I don't want to write a separate config entry for every possible address since there can be many and I have to add for each some extra config settings which I don't want to repeat. I know I can add multiple listen ports in the same server configuration, but is there any way to extract the port number and use it to rewrite the proxy_pass address?

Best Answer

EDIT:

An automatic port -> IP address mapping might work like this:

map $server_port $upstream {
    "~^80(?<dest>[0-9+])$"   192.168.2.$dest;
}

Here a regular expression capture is used to capture the latter part of port number into variable, and then the variable is used in the destination string.


I haven't tested this myself, but it should work.

First, you need to define a map in the http level, which maps port numbers to proxy endpoints:

map $server_port $upstream {
    8080     192.168.2.80;
    8081     192.168.2.81;
    8082     192.168.2.82;
    ...
}

You might need to add a default line to the map.

Then, in the server level, you add the following:

listen 8080;
listen 8081;
listen 8082;

location / {
    proxy_pass http://$upstream;
}

This setup makes a single server block listen to multiple ports, and when using the mapped variable as proxy_pass destination, it will make nginx send the request to desired destination.