Apache Module For OpenID Authentication

mod_auth_oid.jpg

OpenID is a widely adopted technology for user authentication in web applications. It relies on the concepts of distributed user authentication in blog applications. This small cookbook explains step-by-step how to install and configure the Open Source Apache module mod_auth_oid.

The intended purpose of this module is to provide a simple relying party implementation which can be used to protect access to Apache based web applications and resources. The module doesn't implement all, in the official Specification described functions. However, it's features are already mature enough, to provide a comfortable login usability for your applications and users.

There are also two additional modules included which enhance the authentication module with the capability to map userid's to local users not only via the Apache configuration, but with either a local mapping file (which can be already existing from other applications) or via Ldap.

Security Warning: The module doesn't support Protocol Extensions like PAPE. Therefore usage in environments with higher requirements of data protection, like health care or monetary transactions is not recommended.

 

Installation

Prerequisites

In order to install this Apache module the following requirements have to be met:

  • Apache 2.2 including mod_ssl, mod_proxy, mod_include, Headerfiles and apxs/apxs2 (often referred as apache2 and apache2-devel packages).
  • Apache module mod_parp for parameter parsing. Get it from here. Installation is straight forward: Use sudo or login as root:
    $ tar xvBzf mod_parp-0.10-src.tar.gz
    $ cd mod_parp-0.10 $ sudo apxs2 -i -c apache2/mod_parp.c
    $ sudo chmod 755 /usr/lib64/apache2/mod_parp.so

 

Main Module

Download and unpack the Sourcecode from here.

$ tar xvBzf mod_auth_oid-2.0-src.tar.gz
$ cd mod_auth_oid-2.0
$ sudo apxs2 -i -c -I . -D AOID_MOD_EXT_HOOKS apache2/mod_auth_oid.c -lcrypto -lparp

Optional: There are additional modules which come with the Sourcecode. If you want to use also the highly recommended additional module mod_auth_oid_file.c or the mod_auth_oid_ldap.c please compile and install them also with either of the following commands.

$ sudo apxs2 -i -c -I . apache2/mod_auth_oid_file.c
$ sudo apxs2 -i -c -I . apache2/mod_auth_oid_ldap.c

 

Configuration

Server Section

The following Apache Standard modules are required:

  • mod_ssl (provides Encryption routines used by mod_auth_oid)
  • mod_proxy (provides functions for the mod_auth_oid in order to send requests to the OpenID Providers)
  • mod_include (provides rendering of shtml pages)

Enable the modules in your Apache's global configuration section. Adjust the file location according to your file system layout. It is also important, that the modules are loaded after mod_ssl. Thus place this lines at the end of your Apache's LoadModule block. Uncomment the last two lines with the mapping modules if you intend to use them also. If your distribution has an individual style for loading modules please do it according to their instructions (e.g. place the following lines in a file which is included automatically if it lies in a specific directory like modules-enabled or similar.

  LoadModule parp_module                    /usr/lib64/apache2/mod_parp.so
  LoadModule auth_oid_module                /usr/lib64/apache2/mod_auth_oid.so
  # LoadModule auth_oid_file_module           /usr/lib64/apache2/mod_auth_oid_file.so
  # LoadModule auth_oid_ldap_module           /usr/lib64/apache2/mod_auth_oid_ldap.so

Try to restart your server. If the module is loaded correctly, it should be reported in the Servers error.log:

[Sun Nov 06 12:10:59 2011] [notice] Apache/2.2.17 (Linux/SUSE) mod_ssl/2.2.17 OpenSSL/1.0.0c mod_auth_oid/2.0 configured -- resuming normal operations

 

VirtualHost Section

Now it is time to prepare the specific configuration for protection your application. Edit your VirtualHost configuration. Of course it should be your https VirtualHost as we deal with security here. And replace my OpenID YOURNAME with your own OpenID, otherwise YOURNAME could steal your crown jewels one day. ;) If you want to use Google as your OpenID provider you have to go a slightly different way and add a AOID_UserPattern, because Google uses the Directed Identity approach with opaque OpenID's per site. In the last chapter of this howto, called Narrowing the namespace of your prefered OpenID providers the configuration directive is explained with a Google example.

We assume that the resource we want to protect is the location /private and the Authentication handler is located on /aoid. The sections below are commented to indicate what you have to do.

       # A complete reference of all available configuration options
       # is available under: http://auth-openid.sourceforge.net/
       # Caution: Enable on trusted CA's by putting them into cacerts
       # Link them to hashnames like described in the Apache documentation
       # http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslproxycacertificatepath
       SSLProxyEngine            on
       SSLProxyCACertificatePath /etc/ssl/cacerts

       # use httponly flag preventing XSS attacks to the session cookie
       BrowserMatch              "Mozilla.*Firefox/(3|4)" HttpOnlyCookie
       BrowserMatch              "MSIE [6789]"            HttpOnlyCookie
       BrowserMatch              "Opera/(10|9\.[56789])"  HttpOnlyCookie
       BrowserMatch              Secure SecureCookie

       # mod_auth_oid base settings
       AOID_Realm                /
       AOID_StartPage            /private/index.html
       AOID_LogLevel             info
       AOID_LoginPath            /aoid/login
       AOID_LoginSuffix          .shtml
       AOID_Timeout              300
       AOID_CookieName           AJESSIONID

       # OpenID User Mapping. Additional possibilitys are described
       # in the Chapter "Local file mapping" of the Howtoforge Page
       # allowed/known users REPLACE WITH YOUR OPENID
       AOID_User http://YOURNAME.myopenid.com/ YOURNAME

       # Enforce mod_auth_oid user authentication of the following location
       <Location /private>
         AuthType OpenID
         Require valid-user
       </Location>

       # mod_auth_oid login page
       # enable SSI for the login page (requires mod_include)
       <Location /aoid>
          Options            Includes
          AddType            text/html .shtml
          AddOutputFilter    INCLUDES .shtml
       </Location>

 

Files

Now create a directory named private in the DocumentRoot of your VirtualHost, which includes the content you like to protect. As an example add an index.html file which says: "Yeahh!! mod_auth_oid rocks and I hacked 127.0.0.1!.

Additionally you need a loginpage in the Directory aoid which is also in the DocumentRoot. As a start you can use the sample SHTML page from the directory htdocs in the tarball. Just copy it also into your htdocs. Check the permissions of the newly created files, if they match your webservers preferences.

Now you can restart your Apache once again. Please check the error.log to see everything is fine.

 

Test Your Installation

Now open your browser. If you have done everything right and your Apache also does, then you should see a loginpage when you point your browser to the following URL: https://YOURHOST/private/index.html

Select your provider and submit. The module will redirect you to your provider where you log in, and if it was successful you will be sent back to your private application. If you choose Google, just submit the proposed OP Identifier, in the two other cases enter your OpenID into the highlighted part. Later in the howto is a much convenient solution for a fancy looking loginpage described.

 

Debugging In Case Something Went Wrong

In the unlikely case where something is not worked as expected you have several indications what might be wrong in the error.log from your Apache server. The log messages should indicate what fails. A detailed list of the possible error codes and how to enable a higher Loglevel can be found on the mod_auth_oid Page.

 

Additional Options

Fancy Loginpage

I assume that you are like me, and one of the first thing you'd like to see, is a nicely looking loginpage in the browser. Does something like this look cool enough for your taste.

Fancy Loginpage

This professional looking login page was created with the Open Source Project openid-selector which is a user-friendly way to select an OpenID.

After generating the Loginpage it has to be enhanced with the shtml include stuff from mod_auth_oid. I have added the error-rendering part from the original loginpage into the generated html page from openid-selector. My example of the customized page can be downloaded here.

 

Local Userid Mapping

If you also compiled the mod_auth_oid_file module then you can also map your userid records in a local file instead of adding them all to your Apache configuration file. The detailed instructions can be found here.

Read the following chapter to add user self registration with local file mapping in one shot.

 

User Self Administration An OpenID To Local Userid Mapping

Assuming that you already have a user administration in place which is based on Apache's .htpasswd files, you can use the following configuration snipplet to enhance it, so that users can register OpenID account to their local accounts. Copy the file_mapper.html file from the tarball into your htdocs.

  # Virtual Host section
  AOID_File_DB              /etc/apache2/mapdb
  AOID_File_AdminPage       /usr/local/apache2/htdocs/file_mapper.html

  # Profile administration location
  # Adjust filepath according to your existing .htpasswd file
  <Location /profile>
    AuthUserFile            /srv/data/.htpasswd
    AuthName                'Enter your LoginName: Cancel to register if you do not have one.'
    AuthType                Basic
    Require                 valid-user
    SetEnvIf                Request_Method POST parp
    SetEnvIf                Request_Method GET parp
    SetHandler              auth-oid-file
    AOID_File_UserOnly      on
  </Location>

Now, mod_auth_oid_file creates a mapdb file where it stores the relation between OpenID accounts and local .htpasswd accounts.

 

Security Considerations

Relying Party Discovery Document

OpenID recomments to host a Relying Party Discovery Document which indicates a proper return_to address for the OpenID Provider. Yahoo will indicate your site as not trusted, if you don't supply such a document. Further information can be found here.

Save a document called openid.xrd in the DocumentRoot of your site. The content should look similar to the following example. Adjust it according to your setup.

<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
    xmlns:xrds="xri://$xrds"
    xmlns:openid="http://openid.net/xmlns/1.0"
    xmlns="xri://$xrd*($v*2.0)">
    <XRD>
        <Service priority="1">
            <Type>http://specs.openid.net/auth/2.0/return_to</Type>
            <URI>https://YOUR_HOST_HERE/aoid/login</URI>
        </Service>
    </XRD>
</xrds:XRDS>

The document must then be references by either sending a special crafted header with every HTTP response or it can be included in the sites top-level document.

Variant 1 announce it via header (recommended)

    LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
    # .......
Header set X-XRDS-Location https://YOUR_HOST_HERE/openid.xrd

Variant 2 announce it in the top level html document's head section

  ....
  <head>
  <meta http-equiv="X-XRDS-Location" content="https://YOUR_HOST_HERE/openid.xrd"/>
  ....

 

Protecting From DoS And Other Kind Of Attacks

DoS attacks and cross site request forgery is a big issue today. You can protect your site efficiently from DoS attacks with another Open Source Module, called mod_qos. This module is a swiss army knife when it comes to protect your server from various kinds of attacks. The module can be as easily installed as any other Apache module. The following configuration example shows a basic configuration which protects your site from DoS attacks and cross site request forgery on the self administration page.

    # server section
    LoadModule qos_module /usr/lib/apache2/modules/mod_qos.so

    # handles connections from up to 100000 different IPs
    QS_ClientEntries 100000

    # will allow only 50 connections per IP
    QS_SrvMaxConnPerIP 50

    # maximum number of active TCP connections is limited to 256
    MaxClients              256 

    # disables keep-alive when 70% of the TCP connections are occupied:
    QS_SrvMaxConnClose      180

    # minimum request/response speed (deny slow clients blocking the server, ie. slowloris keeping connections open without requesting anything):
    QS_SrvMinDataRate       120 1500 400

    # and limit request header and body (carefull, that limits uploads and post requests too):
    QS_SrvMaxConnClose      70%
    LimitRequestFields      30
    QS_LimitRequestBody     102400

    QS_ClientEventBlockCount 20 300
    QS_SetEnvIfStatus        400               QS_Block
    QS_SetEnvIfStatus        401               QS_Block
    QS_SetEnvIfStatus        403               QS_Block
    QS_SetEnvIfStatus        404               QS_Block
    QS_SetEnvIfStatus        405               QS_Block
    QS_SetEnvIfStatus        406               QS_Block
    QS_SetEnvIfStatus        408               QS_Block
    QS_SetEnvIfStatus        411               QS_Block
    QS_SetEnvIfStatus        413               QS_Block
    QS_SetEnvIfStatus        414               QS_Block
    QS_SetEnvIfStatus        417               QS_Block
    QS_SetEnvIfStatus        500               QS_Block
    QS_SetEnvIfStatus        503               QS_Block
    QS_SetEnvIfStatus        505               QS_Block
    QS_SetEnvIfStatus        QS_SrvMinDataRate QS_Block
    QS_SetEnvIfStatus        NullConnection    QS_Block

    QS_SrvMaxConnExcludeIP 127.0.0.1

    # CSRF protection of the Self Registration Form by setting
    # four milestones for profile administration
    QS_MileStone          deny       "^GET /OpenIdLogin"
    QS_MileStone          deny       "^GET /OpenIDRegistration"
    QS_MileStone          deny       "^GET /profile"
    QS_MileStone          deny       "^POST /profile"

 

Narrowing The Namespace Of Your Prefered OpenID Providers

You can limit which OpenID provider you accept for authentication of your website with the configuration directive AOID_UserPattern. The following two examples give you a rought idea how to construct regular expressions for that purpose.

  # VirtualHost section
  
  # Allow only Google OpenID's
  AOID_UserPattern          "^(https://www\.google\.com/accounts/o8/id\?id=.*)$" "$1"

  # Allow only my.company.com OpenID's and use only a part of it for mapping it to a local user.
  AOID_UserPattern          "^https://my\.company\.com/([a-z]{1})[a-z]+\.([a-z]{2})[a-z]+$" "$1$2"

 

Final Words

Thank you for reading this tutorial. I hope your installation went straight-forward. I wish you, that many users will profit from this module and I hope it was fun for you to install it. If you wish to keep informed about what's going on with the module, you can subscribe on our mod_auth_oid facebook page.

Credits: I wish to thank Pascal Buchbinder who mentored me, to improve this Apache module and enhance it with the identifier_select method. He is a the author of several Apache modules like mod_qos, mod_sslcrl, mod_parp and others.

Share this page:

3 Comment(s)