Apache2 Reverse Proxy to an end-point that requires BasicAuth but want to hide this from user

44,726

Solution 1

Add or overwrite the Authorization header before passing any request on to the endpoint. The authorization header can be hard coded, it's just a base-64 encoding of the string "username:password" (without the quotes.)

Enable the mod_headers module if not already done.

RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="

To perform this conditionally, enable the mod_setenvif, e.g. still ask for the master password in the case of local requests:

SetEnvIf Remote_Addr "127\.0\.0\.1" localrequest
RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" env=!localrequest

EXAMPLE

# ALL remote users ALWAYS authenticate against reverse proxy's
#  /www/conf/passwords database
#
<Directory /var/web/pages/secure>
  AuthBasicProvider /www/conf/passwords
  AuthType Basic
  AuthName "Protected Area"
  Require valid-user
</Directory>

# reverse proxy authenticates against master server as:
#  Aladdin:open sesame (Base64 encoded)
#
RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="

Solution 2

Well I used your example to point to two IP cameras using apache proxypass. When I used the syntax user:[email protected] and accessed through an iphone I got a security message from safari (iphone navigator) so I changed the example to work well with and iPhone 4S

<Location /camarafeliz1/ >
        # usuario admin password 123456
        ProxyPass         http://192.168.0.39/
        ProxyPassReverse  http://192.168.0.39/
        RequestHeader set Authorization "Basic YWRtaW46MTIzNDU2=="
</Location>
<Location /camarafeliz3/ >
        # usuario admin password 123456
        ProxyPass         http://192.168.0.99/
        ProxyPassReverse  http://192.168.0.99/
        RequestHeader set Authorization "Basic YWRtaW46MTIzNDU2=="
</Location>

and the iphone 4s stopped complaining about security because of user and password in the link.

Share:
44,726
Bo Jeanes
Author by

Bo Jeanes

Updated on May 07, 2020

Comments

  • Bo Jeanes
    Bo Jeanes about 4 years

    Basically my scenario is that I have an internal website that requires a SINGLE hard-coded username and password to access (and this can't be turned off, only changed). I am exposing this website through a reverse proxy for various reasons (hiding the port, simplifying url, simplifying NAT, etc).

    However, what I would like to do is be able to use Apache to handle the authentication so that:

    1. I don't have to give out single password to everyone
    2. I can have multiple usernames and passwords using Apache's BasicAuth
    3. For internal users, I don't have to prompt for a password

    EDIT: Second part about richer authentication has been moved to new question

    Here's more or less what I have now:

    <VirtualHost *:80>
      ServerName sub.domain.com
    
      ProxyPass        / http://192.168.1.253:8080/endpoint
      ProxyPassReverse / http://192.168.1.253:8080/endpoint
    
      # The endpoint has a mandatory password that I want to avoid requiring users to type
      # I.e. something like this would be nice (but does not work)
    
      # ProxyPass        / http://username:[email protected]:8080/endpoint
      # ProxyPassReverse / http://username:[email protected]:8080/endpoint
    
      # Also need to be able to require a password to access proxy for people outside local subnet
      # However these passwords will be controlled by Apache using BasicAuth, not the ProxyPass endpoint
    
      # Ideas?
    </VirtualHost>
    
  • Bo Jeanes
    Bo Jeanes about 15 years
    This looks promising but I don't want to ask for the MASTER password if it's non-local requests, i want apache to maintain a basic Auth passwd list and allow users to Auth with one of several different passwords which the endpoint will never see. This doesn't do that afaik right?
  • vladr
    vladr about 15 years
    Just use the first (unconditional, i.e. without SetEnvIf and 'localrequest') variant, i.e. 'RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="'. The reverse proxy will always authenticate with the master password, and users will always use the other passwords to connect to the RP.
  • Bo Jeanes
    Bo Jeanes about 15 years
    I tried both your original suggestion using SetEnvIf and trying to get BasicAuth working and had no success either way. I can successfully disable the password thru the proxy altogether, but not conditionally based on the type of request.
  • vladr
    vladr about 15 years
    Not sure I understand what was successful and what was not successful. Did the "EXAMPLE" work at all, in the sense that was it able to successfully authenticate against the backend with the master password? What did not work?
  • Bo Jeanes
    Bo Jeanes about 15 years
    The RequestHeader part worked a charm, but the full Example has a few problems: Directory doesn't make sense here, AuthBasicProvider doesn't so what I think it does, and if it did this would always require a PW. Need to allow users to access proxy if they are on 192.168.1.* OR have a valid PW
  • Bo Jeanes
    Bo Jeanes about 15 years
    Screw it I will put the second part into another question. You've answered the core part which was how to send Auth details to the end point behind the proxy.
  • Marinos An
    Marinos An almost 6 years
    On latest apche2 versions you can use setifempty instead of set to be able to provide different credentials for proxified resources that are not accessible with the server's default account.