Problem with nginx auth_request directive and location block with set

1.7k Views Asked by At

I have a variable called $host_header defined in the server section, which is overridden in location level. It works perfectly fine as all sets are done in the rewrite phase, so before any proxy_pass directive. Eventually, the proxy_pass to the "test-nginx" goes with the Host header "location level". However, (and here comes the magic) when I add the auth_request directive (which in my example always return 200 and it runs in the access phase, so after all sets) to the location block, the proxy_pass goes with the Host header "server-level", which in my opinion is a bug. It's on nginx 1.19.1

Here is the example code. Any ideas why does it happen? Is it a bug or I'm doing smth wrong?

server {
listen 80;

server_name "local.main.server";
set $host_header "server level";

proxy_set_header Host $host_header;

location /test {
    auth_request /auth;

    set $host_header "location level";

    # call backend server
    proxy_pass http://test-nginx;
}

location = /auth {
    internal;

    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;

    # this simply return 200
    proxy_pass http://test-nginx;
}

}

1

There are 1 best solutions below

0
On

I've found a really nice workaround to this strange problem. With the use of the "js_set" directive from the NJS module, we can create another variable $target_host_header and assign to it the result of the getTargetHeader function:

...
load_module /usr/lib/nginx/modules/ngx_http_js_module.so;
...
http {
  ...
  js_import NJS from /path/to/file/with/functions.js;
  ...
  js_set $target_header NJS.getTargetHeader;
  proxy_set_header Host $target_header;
  ...
}

still in the server section we can set the $host_header variable, but inside a location we have to set different variable $proxy_host_header:

server {
   ...
   set $host_header "server level";
   
   location /test {
      set $proxy_host_header "location level";
      proxy_pass http://SOMEENDPOINT;
   }
   ...
}

and here comes the njs function:

function getTargetHostHeader(r) {
    if (r.variables.hasOwnProperty('proxy_host_header') && r.variables.proxy_host_header.length > 0) {
       return r.variables.proxy_host_header;
    } else {
       return r.variables.host_header;
    }
}