When you need to deploy a custom, weird or non typical Auth schema with Apache, knowing about the Auth External module can save you tons of time.
It is is commonly deployed along with pwauth for allowing unix users to authenticate against Apache, but this only one case use. Actually it can be used for almost any Auth setup that you can imagine.
The main idea behind it is very simple and powerful, it delegates Apache authentication on any program or script that you want. Simply it will feed your program with the user/password variables along other interesting variables like IP, cookies, URI, etc. and your program must return zero if the user is allowed to access or non-zero otherwise.
I will show you a simple example.
” I have my home server where I run an LDAP directory with some users and I also have a remote server in a hosting company where I want to allow the users of my LDAP directory to access some https directory protected by the Apache authentication.
Accessing the LDAP directory from the remote server is not an option because I have a firewall protecting it and I can’t/don’t want to do such a thing. And configuring an slave LDAP server on the remote server is even a worse option.”
So here is when Auth external comes to rescue.
On my home server I configure a dummy https virtual host that authenticates users via the local LDAP
<VirtualHost *:443> SSLEngine on ServerName dummy-https.homeserver.com ServerAdmin clopez@igalia.com TransferLog /var/log/apache2/dummy-https-access.log ErrorLog /var/log/apache2/dummy-https-error.log <Directory /var/www/empty> AuthName Auth AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative On AuthLDAPURL "ldap://localhost/dc=homeserver,dc=com?uid" AuthLDAPGroupAttribute uniqueMember AuthLDAPGroupAttributeIsDN On Require valid-user Order allow,deny Allow from all </Directory> </VirtualHost>
And on the remote server I just implement a very simple script that will read from stdin an user and password strings and will try to establish an https connection with my apache home server using the supplied credentials. It will return zero if it can get the connection, otherwise will return 1
#! /bin/sh read user read password /usr/bin/curl -f -u "$user":"$password" https://dummy-https.homeserver.com >/dev/null 2>&1 || exit 1 exit 0
I saved this script as /usr/local/bin/home-ssl.sh and now I will install the auth external module and will enable it
apt-get install libapache2-mod-authnz-external a2enmod authnz_external
Note: for Debian Lenny grab the backport’s package
And now I will configure the Apache virtual host with the auth external authentication:
<VirtualHost *:443> SSLEngine on ServerName securearea.hostingprovider.com ServerAdmin clopez@igalia.com TransferLog /var/log/apache2/securearea.hostingprovider-access.log ErrorLog /var/log/apache2/securearea.hostingprovider-error.log DocumentRoot /var/www/securearea <Directory /var/www/securearea> AuthType Basic AuthName "Restricted" AuthBasicProvider external AuthExternal home-ssl require valid-user </Directory> AddExternalAuth home-ssl /usr/local/bin/home-ssl.sh SetExternalAuthMethod home-ssl pipe </VirtualHost>
In summary:
- User access https://securearea.hostingprovider.com/
- Apache@hostingprovider ask user for credentials
- Apache@hostingprovider calls /usr/local/bin/home-ssl.sh and feed it with user credentials
- /usr/local/bin/home-ssl.sh calls Apache@homeserver at https://dummy-https.homeserver.com
- Apache@homeserver ask for user credentials to local LDAP database
- If credentials are correct Apache@homeserver will allow /usr/local/bin/home-ssl.sh to access making it to return zero so the user will be allowed to access securearea at Apache@hostingprovider
Want to write an external authenticator? Here you have a quick howto Enjoy !