Nginx Conditional Dynamic Proxy

I have a game running on my server. When a user requests it, a new process on my server is started and starts to listen for a websocket connection on a random port in the range 8001-8100.

On the client i want to connect to the game.

var port = 8044; // <- Client is given this number when creating a new game
connection = new WebSocket("wss://XXX/websocket?port=" + port);

My server is a nginx reverse proxy. I want to do something like this: (I need a working replacement for it, the below should illustrate the point.)

server {
...
location /websocket/ {
  if(isNumber($port) && $port <= 8100 && $port >= 8001 {
    proxy_pass http://localhost:$port;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
} }

Reason for those reverse proxy shenanigans is to be able to use the default 443 port, meaning clients won't have firewall problems. Othwerwise I would just directly connect to the correct port from the client.

Any ideas?

1 answer

  • answered 2017-06-17 20:02 Richard Smith

    The port argument is available as $arg_port. It can be checked using a regular expression. For example:

    location /websocket/ {
        if ($arg_port !~ "^80[0-9]{2}$") {
            return 403;
        }
        proxy_pass http://localhost:$arg_port;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    

    A little poetic licence with the port range, but a more complex expression can achieve your precise requirements. I avoid putting anything too complex inside an if block for these reasons.

    See this document for more.