2

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?

1 Answer 1

4

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.

3
  • Thanks! This works well for my purpose. It would be perfect if the map could extract the numbers automatically (i.e. 8080 -> .....2.80), but it's still much better than repeating the server blocks.
    – rslite
    Feb 2, 2019 at 20:25
  • I added a possible automatic mapping rule to the answer. Feb 3, 2019 at 21:51
  • After trying different things I realized that the mapping works, but regex in maps is supported only in higher versions of nginx (not the one in the RPi's repositories). It worked after I compiled from the most recent sources. I wish listen would take ranges too :) Maybe in a future version.
    – rslite
    Feb 8, 2019 at 4:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .