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?

2

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.

  • 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 at 20:25
  • I added a possible automatic mapping rule to the answer. – Tero Kilkanen Feb 3 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 at 4:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.