Nginx Proxy a large port range to equivalent port on a different ip address
You can do this with the built-in server_port variable:
proxy_pass http://backend-host-name:$server_port;
That would make whatever port the request came in on be proxied to the same back-end port.
So you don't need 1000 proxy_pass statements. But, you may have a problem with the listen directive. It won't accept a range of ports, so you will need 1000 lines of the form:
listen 9000;
listen 9001;
listen 9002;
That list can be easily generated with a spreadsheet. You will probably also need to adjust the number of file handles allowed by nginx to handle this number of sockets. Nginx can do it, the limits may be at the OS layer. See here and here.
I will say, though that this seems to be a problematic design. Why do you need 1000 ports? Wouldn't using host names or some part of the URL to differentiate requests make more sense? It would be far more scalable - no need for 2000 sockets as a baseline.
Here's what I ended up doing instead:
server {
server_name "~^port(?P<forwarded_port>9\d{3})\.example\.com$";
location / { proxy_pass http://127.0.0.1:$forwarded_port; }
}
That way, you can simply connect to http://port9034.example.com;
Since NGINX version 1.15.10 the listen
directive accepts port ranges.
From the documentation:
Port ranges (1.15.10) are specified with the first and last port separated by a hyphen:
listen 127.0.0.1:12345-12399; listen 12345-12399;
Thus, using
server {
listen 9000-9999;
proxy_pass http://upstream-host:$server_port;
}
should do the trick.
It is important to note that he number of worker connections has to be adjusted accordingly, otherwise, NGINX will issue an error:
# nginx -s reload
nginx: [emerg] 512 worker_connections are not enough for 1000 listening sockets