Skip to content
Micah Andersen edited this page Dec 1, 2017 · 1 revision

NOTE: These instructions are for configuration under Apache 2.2. If you are using Apache 2.3 or 2.4, please refer to the ConfigApache24 page. For a summary of changes from Apache 2.2 to Apache 2.4 see the UpgradeTo24 page.

There are three parts to doing the configuration. First, if you are using dynamic loading, you need to configure Apache to load the mod_authnz_external module. If 'apxs' is working correctly, it should do this for you automatically, but it doesn't always.

Second you define the external program and communication method to use in your httpd.conf file, identifying them with a keyword.

Finally you set up specific directories to use that authenticator, referencing it by keyword.

These instructions talk about editing the "httpd.conf" file, as it appears in the standard Apache distributions. In many version of Linux, however, this file will actually just include a lot of other configuration files, some of which may be automatically generated by various GUI configuration tools. I include notes on some of these variations that I have encountered, but you may need to do some of your own figuring to find out how to adapt these instructions to your server configuration.

1. Getting the Module Loaded

This step is not required if you are using static loading. Even if you are doing dynamic loading, apxs should have set up everything correctly for you. If you are trustful, you can skip ahead to step 2 and only come back to this if things don't seem to be working. In cases where you are using multiple non-authoritative authenticators you'll probably want to check this manually, even if apxs works right, to ensure that the modules are loaded (and thus envoked) in the desired order.

  1. First, you should make sure that there is a proper "LoadModule" command in the httpd.conf file. This should have been put there by 'apxs' but, some older Linux distributions, like Redhat 6.1, messed it up. Basically, the 'LoadModule' command should look a lot like all the other LoadModule commands you'll find there. Something like
    LoadModule authnz_external_module modules/mod_authnz_external.so
    where the second part is the path from Apache's root directory to the location where the module was stored by apxs.

    Make sure that apxs didn't put this directive inside any inappropriate <IfDefine> directives, as some Redhat versions have done in the past.

    If you previously had mod_authnz_external or mod_auth_external installed and are installing a new version, you may have more than one LoadModule command in httpd.conf. You only need one. Get rid of the old ones.
  2. Check you httpd.conf file to see if there is a "ClearModuleList" command. If this exists, then you need to add a command like:
    AddModule mod_authnz_external.c
    somewhere below "ClearModuleList" command (probably somewhere among dozens of other AddModule commands). If you used 'apxs' to install mod_authnz_external, then this should already be done, but it may again be stashed in an inappropriate <IfDefine>.

    The standard Apache configuration files don't have a "ClearModuleList" command and don't need an "AddModule" command. However the standard Redhat configuration files, among others, do.

2. Configuring the External Authenticator

In this section we insert commands into httpd.conf that will be run when Apache starts up to tell Apache where your external authenticators are and how to communicate with them.

It is possible to configure several different external authenticators into Apache. For each one you need to configure a name, a method of communicating with authenticator, and the location of the authenticator.

The structure of Apache httpd.conf differs widely on different systems. The notes below on where to put configuration commands assume that you have something close to a straight apache install, but you probably don't. Very likely there will be comments in your httpd.conf file that tell you where to put local configuration commands.

If you are using virtual hosts, put these commands at the end of the appropriate <VirtualHost> block. The declarations must be inside the <VirtualHost> block to work for a virtual host. They are not inherited from the primary host to the virtual hosts. Note that most Apache SSL servers are set up as virtual hosts, so you'll probably need to put these definitions in the <VirtualHost> block for use with an SSL server.

Otherwise, just put them anywhere (just before the Virtual Hosts section of the standard Apache config file might make the most sense).

Two different command syntaxes are supported in mod_authnz_external. One that is compatible with releases before 3.2.0, and one that is a bit more compact, using one command instead of two.

2.1. External Password Authenticators

New-Style Syntax:

DefineExternalAuth <keyword> <method> <location>

Old-Style Syntax:

AddExternalAuth <keyword> <location>
SetExternalAuthMethod <keyword> <method>

<keyword> is some name you choose to identify the authenticator. You can configure multiple different external authenticators by using different keywords for them.

<method> defines how the login and password are passed to the external authenticator. The possible values are:

pipe read newline-terminated strings from stdin. (default)
environment get args from environment variables.
checkpassword read null-terminated strings from file descriptor 3.
function internal authenticator called as function.

'Pipe' is the default. Environment used to be the default in versions of mod_auth_external before 3.1.0, but is insecure on some versions of Unix.

<location> tells where to find the authenticator. It's syntax varies somewhat by method (which is why we introduced the new syntax - to keep it closer to the method declaration):

  • For "pipe", "environment", and "checkpassword" methods: <location> is the full path where you installed your external authentication program, like "/usr/local/bin/auth_check". It always starts with a slash. If you put it in quotes, you can include command-line arguments, but these arguments won't be processed by a shell, so you can't use wildcards or I/O redirects or anything like that. (If you need shell processing of arguments, write an sh-script wrapper for your authenticator, and put the path to that here.)

  • For the "function" method: <location> is a string like "<type>:<data>". The <type> part is a string that can be used to select from multiple internal functions. <data> is a string passed to that function and is typically used as config file path. The ":" is required even if the <data> is an empty string.

In the old-style syntax, the path declaration should always precede the method declaration, and the method declaration can be omitted if you want the default.

Here are some examples. We give old-style syntax only for the first example, but it can be used in all cases:

For external authentication programs using a pipe:

DefineExternalAuth archive_auth pipe /usr/local/bin/authcheck

-or-

AddExternalAuth archive_auth /usr/local/bin/authcheck
SetExternalAuthMethod archive_auth pipe

For external authentication programs using a pipe:

DefineExternalAuth archive_auth environment /usr/local/bin/authcheck

For external authenticators using the checkpassword protocol:

DefineExternalAuth archive_auth checkpassword "/bin/checkpassword /bin/true"

For HARDCODE functions with a configuration file:

DefineExternalAuth archive_auth function RADIUS:/usr/local/raddb

For HARDCODE functions with no configuration file:

DefineExternalAuth function archive_auth RADIUS:

2.2. External Group Checkers

If you want to use an external program to do group checking, add one of the following to your server's httpd.conf:

New-Style Syntax:

DefineExternalGroup <keyword> <method> <location>

Old-Style Syntax:

AddExternalGroup <keyword> <location>
SetExternalGroupMethod <keyword> <method>

<keyword> is some name you choose to identify this particular group checking method. The keywords for login authenticators and group authenticators are separate name spaces, so it doesn't matter if these keywords match any you defined with DefineExternalAuth or AddExternalAuth.

<method> defines how the login and group names are passed to the external authenticator. Legal values are:

pipe authenticator reads data from standard input.
environment authenticator gets data from environment variables.

Pipe is the default. Environment used to be the default before version 3.1.0. The "checkpassword" keyword also works, but doesn't really make a lot of sense since there are no checkpassword authenticators for groups.

Examples:

For external group checking programs using a pipe:

DefineExternalGroup archive_group pipe /usr/local/bin/grpcheck

-or-

AddExternalGroup archive_group /usr/local/bin/grpcheck
SetExternalGroupMethod archive_group pipe

For external group check programs using environment variables:

DefineExternalGroup archive_group environment /usr/local/bin/grpcheck

3. Configuring Web Pages to Use Authentication

For any directory you want to protect, you need either a .htaccess file in the directory or a <Directory> block for the directory in your httpd.conf file.

Note that for .htaccess files to work, you must specify "AllowOverride AuthConfig" in the httpd.conf file for any directories they appear under. As distributed, Apache sets "AllowOverride None" for most directories. If this is not changed, .htaccess files will be ignored.

3.1. External Password Authenticators

For normal user authentication, the following directives should be in the .htaccess file or <Directory> block:

AuthType Basic
AuthName <authname>
AuthBasicProvider external
AuthExternal <keyword>
Require valid-user

Here <authname> identifies what we are authenticating for - it usually appears in the browser's pop-up login window. <keyword> matches a keyword you defined with DefineExternalAuth or AddExternalAuth in step 2.

In version 2.3.4 and later it is possible to list more than one authenticator on the AuthExternal command:

AuthExternal <keyword1> <keyword2>...

Here each keyword should match an authenticator defined with the DefineExternalAuth command. If the first authenticator fails, then the second one will be run, and so on, until either one authenticator accepts the user's login/password combination or all reject it.

If you only want some users to have access to the directory, as opposed to all valid users, you can list the users on the "require" line, changing it to:

Require user <username1> <username2> ...

Or if you have mod_authz_owner installed and you want to allow only user's whose login name matches the login name of the unix user who owns the file being accessed, you can say:

Require file-owner

3.2. External Group Checkers

If you want to use the external group check program to allow only users in a given group to have access, you could do:

AuthType Basic
AuthName <authname>
AuthBasicProvider external
AuthExternal <keyword>
GroupExternal <groupkeyword>
Require group <groupname1> <groupname2> ...

Here <groupkeyword> matches a name you defined with with the DefineExternalGroup or AddExternalGroup command in step 2.

Normally if you have multiple group names on your "Require group" command, then the group checker will be run only once, passing it the whole space-separated list of groups. Some older group checking programs may only be able to handle one group name at a time. So if you want the group checker to be run once for each group name, you can add the directive:

GroupExternalManyAtOnce off

If, instead of listing group names, you want to allow access only to users whose group name (as determined by whatever group database your external group checker uses) matches the unix group name that owns the file being accessed, you can configure an external group checker, install mod_authz_owner and then do:

Require file-group

3.3. Passing Context Information into Authenticators

If you want the authentication to work slightly differently in different directories, then you can add a directive like:

AuthExternalContext <context>

This will simply pass whatever <context> string you entered to the authenticator in an environment variable called CONTEXT. The authenticator can use that to modify it's behavior.

3.4. Modifying Error Codes for Group Checking

Normally, if a group authentication fails, then mod_authnz_external will return a 401 error, which will normally cause the browser to pop up a fresh login box so the user can try logging in with a different ID. This may not always be appropriate. If you rejected him because he has a blocked IP address, returning a 403 error, which displays an error page (which you can configure) may be a better choice. To get a 403 error instead of a 401 error on failed group access checks, you would add the following command to your configuration:

GroupExternalError 403

This would effect only group checks, never password checks. Bad passwords always result in a 401 error.

3.5. Interactions with Other Authenticators

It is possible to configure more than one different authentication module. If you do so, you will normally want to make them unauthoritative, so that if one fails, the others will be tried. That way, authentication or access will be granted if ANY of the the configured modules finds it valid.

If all your password checkers are "authn" modules running under mod_auth_basic, then you need do nothing. The arbitration among such modules is different than the arbitration between top level modules, and does the right thing by default. But if some are not "authn" modules, then you'll want to make mod_auth_basic unauthoritative with the "AuthBasicAuthoritative off" directive described in the Apache manual.

If you have multiple group checkers, then you will need to make mod_authnz_external un-authoritative for group checking. To do this, use the directive:

GroupExternalAuthoritative off

Of course, you'll probably also have to make the other module unauthoritative. For example, if you have a "Require user pete" directive and a "Require group admin" directive and expect it to allow either pete or any admin to login, then you need to make mod_authz_user unauthoritative, because that's what checks "Require user" directives.

See the Apache manual pages on AuthType, AuthName, AuthBasicProvider, Require, and AuthGroupFile for more information.

3.6. Old Directives

Some of the directives mentioned above used to have different names. The old names still work for backward compatibility.

AuthzExternalAuthoritative equals GroupExternalAuthoritative

AuthExternalGroupsAtOnce equals GroupExternalManyAtOnce

Return to step (5) on the Installation page for the rest of the setup procedure.