1

From mod_proxy guide I configured reverse proxy with user authentication.

# Set reverse proxy
ProxyPass "/" "http://localhost:10080/"
ProxyPassReverse "/" "http://localhost:10080/"
ProxyRequests On
ProxyVia On

<Proxy *>
    Order deny,allow
    Allow from all
    AuthType Basic
    AuthName "Password Required"
    AuthUserFile /home/secure/.passwords
    Require user ivy
</Proxy>

This works as following: User accesses to the server --> Server asks username/password --> User enters his credentials --> If credentials are OK for user ivy then reverse proxy works for port 10080 on local host.

All users are added with htpasswd. I run apache2.4 over Linux.

What I need to do: I want allow different users using the proxying. On the server number of reverse tunnels are open with ports 10080, 10081, 10082, and so on... I want to assign every single user to use separated proxy port. I.e.:

  • ivy --> 10080
  • joe --> 10081
  • doe --> 10082

If I write Require user ivy joe doe then I redirect all users into single port 10080.

It seems the trick is somewhere in lines ProxyPass "/" "http://localhost:10080/" and <Proxy *>. Or where?

Update: Following Jenny's suggestion tried:

LoadModule rewrite_module modules/mod_rewrite.so
<IfModule mod_rewrite.c>
    RewriteEngine On
    #RewriteCond %{REMOTE_USER} ivy  # Unconditional redirect for testing.
    RewriteRule ^/(.*)$ "http://localhost:10080/test.html" [R=301,L]
</IfModule>

Tried this with Proxy enabled (proxy is stronger than Rewrite) and Proxy disabled (Local index.html displayed).

Tried use flags [R,L], [L,R], [L,R=301] - no luck.

Tried to add into <Directory "/var/www/html"> and into <Proxy *>:

RewriteEngine On
RewriteRule ^/(.*)$ "http://localhost:10080/test.html" [R=301,L]

Tried this with Proxy enabled (proxy is stronger than Rewrite) and Proxy disabled (Local index.html displayed).

Deep dig found this trick:

RedirectMatch ^/.*$ /test.html

This works but this is not conditional: i.e. I still can't assign different redirect per user.

Update2: Tried solution of Cedric Knight with no luck too. Decided to give up with Apache, switched to nginx. Works OK. The server configuration for separated reverse proxy per user is:

server {
    listen       80 default_server;
    listen [::]:80  default_server ipv6only=on;
    set $auth_status 100;
    server_name  localhost;
    root         /usr/share/nginx/html;

    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 http://localhost:10080;
            break;  # break is essential since proxy_pass in 'if' isn't allowed.
        }
        if ($remote_user = "joe") {
            proxy_pass http://localhost:10081;
            break;
        }
    }
}

This is brute-force solution. In next step, I'll add reading the map user:port from file.

  • You could probably do this with mod_rewrite using a mapping table. – Jenny D Aug 19 '17 at 14:58
  • Thank you, Jenny. I tried what I could understand from the Internet with no success meanwhile. Updated the question. – Ivy Growing Aug 21 '17 at 9:20
  • "mod_rewrite using a mapping table." Was my initial thoughts. Dunno what to add here. – Net Runner Aug 21 '17 at 11:13
0

Yes, Jenny's idea makes sense. Don't use the ProxyPass directive, just use mod_proxy via mod_rewrite using the P flag then you can as a next stage set additional users up with RewriteMap.

<IfModule mod_proxy.c>
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REMOTE_USER} ivy
    RewriteRule ^/(.*)$ "http://localhost:10080/$1" [P]
    RewriteCond %{REMOTE_USER} joe
    RewriteRule ^/(.*)$ "http://localhost:10081/$1" [P]
    #etc.
    # optional step: set up RewriteMap
    RewriteMap user-to-port txt:/home/proxy-ports.txt
    # contains one entry per line 'doe 10082' etc
    RewriteCond %{REMOTE_USER} ^(.*)$
    RewriteRule ^/(.*)$ "http://localhost:${user-to-port:%1|10080}/$1" [P]
    # 10080 is default port for other users
</IfModule>
</IfModule>

And if you get rid of the <Proxy> section, separate out the authentication challenge accordingly, using Apache 2.4 directives:

<Location "/">
    AuthType Basic
    AuthName "Password Required"
    AuthUserFile /home/secure/.passwords
    <RequireAll>
        Require valid-user
    </RequireAll>
</Location>

I don't see the need for ProxyVia in a reverse proxy situation; although you might want to log local and remote ports. I've not tested any of the above, just wanted to suggest a direction for what you want to do.

  • Thank you, Cedric. Proposed configuration makes many things clear. I copied it into my config file and tried to run it using <Proxy> section and without it, using <Location "/">. Unfortunately, no fortune. Fortunately, I decided to switch from Apache to nginx and managed to learn it and implement everything just reading common examples. Thank you again for help. – Ivy Growing Aug 22 '17 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.