Separated reverse proxy for different users

classic Classic list List threaded Threaded
6 messages Options
pva
Reply | Threaded
Open this post in threaded view
|

Separated reverse proxy for different users

pva
Hi, I'm relatively new to HTTP servers and absolutely new to nginx.
I have HTTP server which should ask user credentials and redirect every user
to its own reverse proxy.

The initial setting is:
    server {
        listen      80 default_server;
        listen [::]:80  default_server ipv6only=on;
        set $auth_status 100;
        server_name  localhost;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;

        location / {
            try_files $uri $uri/ =404;
            auth_basic "restricted content";
            auth_basic_user_file "/home/secure/.passwords";
            auth_request_set $auth_status $upstream_status;

            if ($remote_user = "ivy") {
                proxy_pass <a href="http://localhost:10080;">http://localhost:10080;
                break;
            }
            if ($remote_user = "john") {
                proxy_pass <a href="http://localhost:10081;">http://localhost:10081;
                break;
            }
      }

It works OK. However, I think it's pretty ugly to have separated "if" per
user. Therefore, I want to add a map:
    map $remote_user $rp_port {
       include /home/secure/reverse_proxy.map;
    }

The map contains:
ivy 10080;
john 10081;

From documentation I understood this should come before server definition.
Then I tried to replace all "ifs" in server body with:
          proxy_pass <a href="http://localhost:$rp_port">http://localhost:$rp_port

This configuration gives following errors:
2017/08/25 06:29:38 [error] 26582#26582: *631 invalid port in upstream
"localhost:", client: ..., server: localhost, request: "GET / HTTP/1.1",
host: "..."
2017/08/25 06:29:48 [error] 26582#26582: *632 no resolver defined to resolve
localhost, client: ..., server: localhost, request: "GET / HTTP/1.1", host:
"..."

It's clear that I miss something in the documentation.
Please, help to build a map for reverse proxy by user authentication
properly.

Thank you.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,276150,276150#msg-276150

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Separated reverse proxy for different users

Francis Daly
On Fri, Aug 25, 2017 at 06:33:11AM -0400, ivy wrote:

Hi there,

> Therefore, I want to add a map:
>     map $remote_user $rp_port {
>        include /home/secure/reverse_proxy.map;
>     }
>
> The map contains:
> ivy 10080;
> john 10081;
>
> From documentation I understood this should come before server definition.
> Then I tried to replace all "ifs" in server body with:
>           proxy_pass <a href="http://localhost:$rp_port">http://localhost:$rp_port
>
> This configuration gives following errors:
> 2017/08/25 06:29:38 [error] 26582#26582: *631 invalid port in upstream
> "localhost:", client: ..., server: localhost, request: "GET / HTTP/1.1",
> host: "..."

That is because your map does not have a "default" value, so when
$remote_user is empty or does not match one of your listed names,
$rp_port is empty and your configuration is effectively

  proxy_pass <a href="http://localhost:;">http://localhost:;

which is invalid. Simplest fix is to always have a value for $rp_port.

> 2017/08/25 06:29:48 [error] 26582#26582: *632 no resolver defined to resolve
> localhost, client: ..., server: localhost, request: "GET / HTTP/1.1", host:
> "..."

That is because you use a proxy_pass with variables, and this version of
nginx does not try to resolve the hostname at startup, instead resolving
it at processing time -- and you have not defined a resolver. Simplest
fix is to use 127.0.0.1 instead of localhost here.

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
pva
Reply | Threaded
Open this post in threaded view
|

Re: Separated reverse proxy for different users

pva
Hi Francis,

Thanks for your reply.
I added default value to map file and replaced "localhost" with 127.0.0.1
So currently the map file looks like:

ivy 10080;
john 10081;
default 65355;

The conf.file looks like:
map $remote_user $rp_port {
  include /home/secure/reverse_proxy.map;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;
  set $auth_status 100;
  server_name localhost;
  root /usr/share/nginx/html;
  include /etc/nginx/default.d/*.conf;

  location / {
    try_files $uri $uri/ =404;
    auth_basic "restricted content";
    auth_basic_user_file "/home/secure/.passwords";
    auth_request_set $auth_status $upstream_status;

     proxy_pass <a href="http://127.0.01:$rp_port">http://127.0.01:$rp_port 
  }
}

This gave me following error:
2017/09/02 12:46:32 [error] 26959#26959: *1905 connect() failed (111:
Connection refused) while connecting to upstream, client: client_ip, server:
..., request: "POST / HTTP/1.1", upstream: "http://server_ip:10081/", host:
"server_ip", referrer: "http://server_ip/"

I added URI in the proxy_pass line:
            proxy_pass <a href="http://127.0.0.1:$rp_port$uri;">http://127.0.0.1:$rp_port$uri;
Among many iterative experiments i found that $uri and $request_uri give the
same result:
- On plain root request (like: my.site.info) the needed page is loaded.
client_ip - ivy [02/Sep/2017:14:59:43 -0400] "GET / HTTP/1.1" 200 33185 "-"
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/60.0.3112.101 Safari/537.36" "-"

- However, on request of any sub-location (like: my.site.info/about) the
proxy_pass generates redirect to itself.
client_ip - ivy [02/Sep/2017:14:59:47 -0400] "GET /sysinfo/ HTTP/1.1" 404
571 "http://server_ip/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36"
"-"

Here
(https://www.jethrocarr.com/2013/11/02/nginx-reverse-proxies-and-dns-resolution/)
provided number of workarounds with changing upstreams. I tried all of them
with the same result as above - sub-locations give error 404.

I'd glad to try more ideas.
Thank you.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,276150,276228#msg-276228

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Separated reverse proxy for different users

Francis Daly
On Sat, Sep 02, 2017 at 03:53:52PM -0400, ivy wrote:

Hi there,

there are a few things here I'm not sure about.

>   location / {
>     try_files $uri $uri/ =404;

Why is that line there? That probably says "return 404 to most
requests". You report that you get a 404 to most requests. Remove that
line if you cannot say what you think it should be doing.

>     auth_basic "restricted content";
>     auth_basic_user_file "/home/secure/.passwords";
>     auth_request_set $auth_status $upstream_status;
>
>      proxy_pass <a href="http://127.0.01:$rp_port">http://127.0.01:$rp_port 

If you copy-paste'd that line, you possibly have some typos in your config.

If you transcribed that line, then this is an indication of why you
should not transcribe.

> 2017/09/02 12:46:32 [error] 26959#26959: *1905 connect() failed (111:
> Connection refused) while connecting to upstream, client: client_ip, server:
> ..., request: "POST / HTTP/1.1", upstream: "http://server_ip:10081/", host:

"10081" corresponds to "john", yes? Your proxy_pass line wanted to talk
to 127.0.0.1, but the log line says server_ip.

I suspect that you are not testing with the configuration/logs that you
are showing here.

Anyway: the log line says that the server on 10081 is not running. Is
the server on 10081 running? If not, make it be running before you test again.

> I added URI in the proxy_pass line:
>             proxy_pass <a href="http://127.0.0.1:$rp_port$uri;">http://127.0.0.1:$rp_port$uri;

That should not be necessary, if the first problems are solved.

> - However, on request of any sub-location (like: my.site.info/about) the
> proxy_pass generates redirect to itself.

Just for clarity: a 404 is not a redirect to itself.

The 404 probably comes from your try_files line, before proxy_pass takes
effect. Your upstream server on port 10081 probably shows nothing in
its logs for this request.

> Here
> (https://www.jethrocarr.com/2013/11/02/nginx-reverse-proxies-and-dns-resolution/)
> provided number of workarounds with changing upstreams. I tried all of them
> with the same result as above - sub-locations give error 404.

I don't see any suggestions on that page that are relevant to you; you
don't have varying hostnames in your proxy_pass directives, unless I
have missed something.

> I'd glad to try more ideas.

Remove the try_files line; and if something remains imperfect, build a
test system that does not have any secret names or addresses and show
the actual tested configuration, request, and logged result.

Good luck with it,

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Separated reverse proxy for different users

Ish Sookun
In reply to this post by pva
Hi Ivy,

On 09/02/2017 11:53 PM, ivy wrote:
>   location / {
>     try_files $uri $uri/ =404;
>     auth_basic "restricted content";
>     auth_basic_user_file "/home/secure/.passwords";
>     auth_request_set $auth_status $upstream_status;
>
>      proxy_pass <a href="http://127.0.01:$rp_port">http://127.0.01:$rp_port 
>   }

The above try_files directive would return only the files & directories
that are present withing the document_root. Any other request would meet
a 404 error. The requests do not seem to reach the proxy_pass.

If all requests are to be served by the proxy_pass, I suggest
commenting/removing the try_files directive. E.g.

  location / {

    auth_basic "restricted content";
    auth_basic_user_file "/home/secure/.passwords";
    auth_request_set $auth_status $upstream_status;

    proxy_pass <a href="http://127.0.01:$rp_port;">http://127.0.01:$rp_port;
  }

Regards,

Ish Sookun
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
pva
Reply | Threaded
Open this post in threaded view
|

Re: Separated reverse proxy for different users

pva
In reply to this post by Francis Daly
Bingo!
> try_files $uri $uri/ =404;

This line was inherited from default configuration of nginx.
As newbie I am afraid to change anything I don't completely understand.

Thank you very much for help, Francis.
:-)

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,276150,276406#msg-276406

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx