1

I recently have a requirement in Nginx to rewrite a URL and then forward this onto to another backend server to a dynamic proxy pass address. I've tried a few things but have not had much luck at the moment. For example, this is the kind of setup I have in my nginx.conf file:

server {
  listen 443;
  server_name scheduler.domain-name;
  rewrite ^scheduler(.*)/(.*)/(.*) $2$1$3; # scheduler.domain.local/changepass/report?target=service
...

location / {
  proxy_pass $to-rewrite-address:9443; # changepass.domain.local/report?target=service
  ...
}

Essentially, I just need to use a re-written URL variable to forward the request on a different port but can't seen to get this to work.

I've done quite a bit of searching but haven't found the solution to this as of yet, though I understand that the DNS resolver has to be set when using a proxy pass variable (Dynamic proxy_pass to $var with nginx 1.0).

Grateful if anyone could advise on how the above could be achieved, many thanks.

  • 1
    `rewrite` directive works with normalized URI (`/changepass/report` in your example), it does not work with domain name or query arguments. – Ivan Shatsky Sep 17 '20 at 21:53
  • 1
    This particular example should work with something like `location /changepass/ { proxy_pass http://changepass.domain.local:9443/; }`. It would be better if you provide more details to your question about your possible endpoints. – Ivan Shatsky Sep 17 '20 at 22:02
  • Thanks for your response. Currently there are only a couple of endpoints but in the future there will be a lot more. The hope was that we could just use the rewrite directive to handle this without ever having to add additional proxy_pass directives in Nginx as each one becomes available. – Daniel Campailla Sep 18 '20 at 06:51

1 Answers1

1

Assuming your endpoint would always be specified as the first part of your URI, here is an example of configuration that should work:

server {
    listen 443;
    server_name scheduler.domain-name;
    resolver <your resolver for domain.local>;
    ...
    location ~ ^/(?<endpoint>changepass|endpoint2|endpoint3|...)(?<route>/.*) {
        proxy_pass http://$endpoint.domain.local:9443$route;
    }
}

I'm using named capturing groups here for a better readibility, this location block is equal to

    location ~ ^/(changepass|endpoint2|endpoint3|...)(/.*) {
        proxy_pass http://$1.domain.local:9443$2;
    }

I'm not sure if query arguments would be preserved with such a construction, if they won't, change

proxy_pass http://$endpoint.domain.local:9443$route;

to

proxy_pass http://$endpoint.domain.local:9443$route$is_args$args;
Ivan Shatsky
  • 13,267
  • 2
  • 21
  • 37