Welcome! Log In Create A New Profile

Advanced

Unable to use subrequest authentication for proxied site

September 19, 2020 12:28PM
How do I configure nginx to use subrequest authentication for a reverse proxied
application with websocket upgrades? The documentation doesn't seem to contain
the information I need to do this.

https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-subrequest-authentication/

When I do, I either get
A) 404 for every request.
B) All requests pass regardless of php session ID (or not at all) or

It seems that I can either proxy the authentication request (and nginx
attempts to serve local content) OR proxy the request itself (and then I get
the etherpad content without it being authenticated) I can't seem to get both
working together.


SYSTEM CONFIGURATION

I have an instance of Etherpad running on a VM on a host called Alpha. Alpha
is running CentOS 7, the VM is running Centos8.

The Etherpad instance is used in a PHP application running on another server,
and it's important to prevent the etherpad pages from being public, so it
seems the easiest way to secure things is to use subrequest authentication.

Applcation: https://mydomain.com
Etherpad URL: https://etherpad.mydomain.com

1) Within the application, the URL for the etherpad iframe has
&sess_id=$php_session_id added. EG:

https://etherpad.mydomain/p/MyPad?sess_id=MyPhpSessId

This is so that nginx can make a subrequest to the application, passing the
PHP Sessid to validate that the end user with the PHP Sessid has rights to the
document in the etherpad instance.

2) The application has an external authentication page at /external/
etherpad.php. It returns http code 200 when the values in the php session
match the URL of the etherpad address as passed in the header X-Original-URI.
(EG: "MyPad" is referenced in MyPhpSessid) and 401 when this test fails.

3) Nginx is set up on Alpha to proxy to the VM called Virtual. The proxy is
set up with Let's Encrypt SSL certificates; the etherpad instance is not
encrypted but has no direct ports to the public cloud.



WHAT I'M EXPECTING FOR A SUCCESSFUL HIT

1) nginx receives a request like:
https://etherpad.mydomain.com/p/MyPadId?sess_id=PhpSessionId

2) nginx makes a request to
https://mydomain.dom/external/etherpad.php
with header:
X-Original-URI: /p/MyPadId?sess_id=PhpSessionId

3) /external/etherpad.php receives authentication request, gets X-Original-URI
and validates the request, returning an http_code 200 when all is well.

4) nginx receives the result of #3, and passes the original request to the
etherpad instance.

5) Etherpad responds with the result

6) Successful Etherpad instance runs in the application.



*********************************************************
WHAT IS HAPPENING (Schenario 1)

1) nginx receives a request like:
https://etherpad.mydomain.com/p/MyPadId?sess_id=PhpSessionId

2) nginx makes a request to
https://mydomain.dom/external/etherpad.php
with header:
X-Original-URI: /p/MyPadId?sess_id=PhpSessionId

3) /external/etherpad.php receives authentication request, gets X-Original-URI
and validates the request, returning an http_code 200 when all is well.

4) Nginx attempts to resolve the request as a local file, can't find it, and
returns 404 to the end user.

SCENARIO 1 NGINX CONFIG FILE

----------------------
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
server_name etherpad.mydomain.com;
listen 8008;

listen 9000 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/etherpad.mydomain.com/fullchain.pem;
# managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/etherpad.mydomain.com/
privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


location / {
proxy_pass http://192.168.122.61:9001/;
proxy_set_header Host $host;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1; # recommended with keepalive connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /p/ {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
}
location /auth {
internal;
proxy_pass https://mydomain.com/external/etherpad.php;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
----------------------

*********************************************************
WHAT IS HAPPENING (Schenario 2: invalid session ID)

1) nginx receives a request like:
https://etherpad.mydomain.com/p/MyPadId?sess_id=INVALID

2) nginx makes a request to
https://mydomain.dom/external/etherpad.php
with header:
X-Original-URI: /p/MyPadId?sess_id=INVALID

3) /external/etherpad.php receives authentication request, gets X-Original-URI
and validates the request, returning an http_code 401.

4) nginx IGNORES the result of #3, and passes the original request to the
etherpad instance, even when validation fails.

5) Etherpad responds with the result

6) Successful Etherpad instance runs in the application despite lacking
credentials.


SCENARIO 2 NGINX CONFIG FILE
----------------------
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
server_name etherpad.mydomain.com;
listen 8008;

listen 9000 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/etherpad.mydomain.com/
fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/etherpad.mydomain.com/
privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

location / {
proxy_pass http://192.168.122.61:9001/;
proxy_set_header Host $host;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1; # recommended with keepalive connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /p/ {
auth_request /auth;
auth_request_set $auth_status $upstream_status;

# NOTE THAT THIS IS A COPY OF LOCATION / UNTIL THE END OF THIS BLOCK.
proxy_pass http://192.168.122.61:9001/;
proxy_set_header Host $host;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1; # recommended with keepalive connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /auth {
internal;
proxy_pass https://mydomain.com/external/etherpad.php;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}

}

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

Unable to use subrequest authentication for proxied site

YesThatGuy September 19, 2020 12:28PM

Re: Unable to use subrequest authentication for proxied site

Francis Daly September 20, 2020 11:30AM

Re: Unable to use subrequest authentication for proxied site

YesThatGuy September 20, 2020 01:34PM

Re: Unable to use subrequest authentication for proxied site

Francis Daly September 21, 2020 04:54AM

Re: Unable to use subrequest authentication for proxied site

YesThatGuy September 24, 2020 10:58PM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 72
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready