Apache2: Enable LDAP authentication and SSL termination for Ubuntu

Some web applications leave authentication as an orthogonal concern to the application – not including any kind of login functionality and instead leaving authentication as an operational concern.

When this happens, a reverse proxy that has an LDAP integration can act as an architectural sentry in front of the web application and also fulfills the requirements for Single Sign-On.  Apache2 serves this purpose very well with minimal overhead.

Install Apache Packages

First we install Apache2, then several required apache modules, and finally open the Apache exposed ports:

# apt-get install apache2 apache2-utils libapache2-mod-proxy-html npm -y

# /usr/sbin/a2endmod proxy proxy_http headers rewrite ssl
# /usr/sbin/a2endmod ldap authnz_ldap

# ufw allow 80/tcp
# ufw allow 443/tcp

HTTP Redirect to Secure Port

To enforce secure access, we will redirect any non-secure requests to the secure port.  Modify the “/etc/apache2/sites-available/000-default.conf”:

<VirtualHost *:80>
        ServerName FQDN
        RewriteEngine On
        RewriteCond %{HTTP:X-Forwarded-Proto} !https
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
        ErrorLog ${APACHE_LOG_DIR}/error.log    
</VirtualHost>

Replace the FQDN with the fully qualified name of your server.

Self-Signed Certificate

If Apache2 is going to act as an SSL termination point, then we need to give it a public/private key pair.  The article I wrote here describes the exact steps for creating a .crt and .key file in /etc/pki/tls/certs.

The cert created will have a CN matching the FQDN of the host, and must be addressed as such in your browser.  If you need to create a local hosts entry to match the FQDN of the host, then do so.

SSL Termination

Analogous to the config for the non-secure port, we create a configuration file in the “/etc/apache2/sites-available” directory and make sure it is linked into the sites-enabled directory.

# cd /etc/apache2/sites-available
# touch -f 001-default.conf
# chmod 644 001-default.conf
# ln -s /etc/apache2/sites-enabled/001-default.conf\
/etc/apache2/sites-available/001-default.conf

And make the contents of 001-default.conf:

<VirtualHost _default_:443>
    ServerName FQDN

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    SSLEngine on
    SSLProxyEngine on
    SSLCertificateFile /etc/pki/tls/certs/FQDN.crt
    SSLCertificateKeyFile /etc/pki/tls/certs/FQDN.key
    # self signed do not have chain
    #SSLCertificateChainFile /path/to/DigiCertCA.crt

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    ProxyPreserveHost On
    ProxyRequests Off
    RequestHeader set X-Forwarded-Proto "https"

    # change these ports and paths to suit your env
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/

    LogLevel debug ssl:debug

    # for testing file provided credentials
    # htpasswd -c /etc/apache2/.htpasswd admin
    #<Location "/">
    #AuthName "Apache2 file check"
    #AuthType Basic
    #AuthBasicProvider file
    #AuthUserFile "/etc/apache2/.htpasswd"
    #Require valid-user
    #</Location>

    <Location "/">
    AuthName "Apache2 LDAP Check"
    AuthType Basic
    AuthBasicProvider ldap
    LDAPReferrals Off
    AuthLDAPUrl ldap://LDAPHost/dc=myorg,dc=com?sAMAccountName?sub?(objectClass=*)
    AuthLDAPBindDN "myid@MYORG.COM"
    AuthLDAPBindPassword "mypass!"
    Require ldap-group CN=My App Group,OU=CustomGroups,DC=myorg,DC=com
    # there can be more than one ldap-group required
    #Require ldap-group
    </Location>

</VirtualHost>

Replace FQDN with the fully qualified name of your host.  When an unauthenticated user hits this Apache2 frontend, it will throw up a BASIC dialog and check if they are a member of the “My App Group” AD group in the MYORG.COM domain.

LDAP connectivity requires an administrative bind user, so a service account named “myid” must be created manually.

Once authenticated, Apache will serve as the reverse proxy for the HTTP application listening on port 8080 or whatever port and path you configure.

Start research here on hardening the Apache2 instance to remove SSLv2/v3, using strong ciphers, strict transport security, etc.

 

REFERENCES

https://www.digitalocean.com/community/tutorials/how-to-use-apache-http-server-as-reverse-proxy-using-mod_proxy-extension

https://www.nginx.com/blog/nginx-plus-authenticate-users/

https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html