Skip to content


Sven-Haegar Koch edited this page Apr 15, 2016 · 2 revisions

NOTE: These instructions are for configuration under Apache 2.4. If you are using Apache 2.2, please refer to the ConfigApache22 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 section is mostly a relic of the old days when 'apxs' installed modules incorrectly on many systems. I haven't seen those kinds of problems in years, so you can probably skip directly to step 2 and only come back to this if things don't seem to be working. If by some chance you are statically loading mod_authnz_external, then you also don't need to worry about any of this.

  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 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/
    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.

    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


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

For external authentication programs using environment variables:

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.


For external group checking programs using a pipe:

DefineExternalGroup archive_group pipe /usr/local/bin/grpcheck


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.

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 external-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 external-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 external-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. The error code returned is no longer under the control of mod_authnz_external, but it you can use the following Apache directive to tell Apache to return a 403 error code when access control checks fail:

AuthzSendForbiddenOnFailure On

3.5. Interactions with Other Authenticators

It is possible to configure more than one different authentication module. The arbitration between modules these days is entirely under the control of mod_auth_basic and mod_authz_core. All the old business of declaring modules authoritative on unauthoritative is gone.

See the Apache manual pages on mod_authn_basic and mod_authz_core for more information.

3.6. Use with Mod_Authz_Socache

Mod_authnz_external version 3.3.1 and later can be used with the new Apache 2.4 mod_authn_socache module, which caches authentications. If you do this, then after a successful authentication, mod_socache will remember the user for a settable time (5 minutes by default) and not rerun the external authenticator again to check their password until after the timeout. This can be a very substantial performance improvement.

It can also be a very substantial security problem. One common use of mod_authnz_external is to authenticate from databases that are not readable by Apache, and should not be. For example, if you are authenticating out of the a unix password file with pwauth, you don't want make the password file readable to Apache because then an Apache bug would risk exposing your entire password file to the net. But if you turn on caching with mod_authn_socache, then the cache it builds up is essentially an Apache-readable copy of the most sensitive data from your password file. With some settings, it may even be stored on disk rather than on memory. The only good thing you can say for it is that all the passwords in that cache will be encrypted (even if you are dopey enough not to encrypt them in your actual password database). But encryption is a pretty weak defense all by itself.

There might also be problems with cache latency. When a user changes his password, it may be five minutes before the old one expires out of the cache so that the new one can be used. If you delete a user's account, they might still be able to log in for another five minutes until their cache entry expires. There ought to be a way to flush the cache, but I don't think there is much you can do right now short of restarting Apache, and I'm not sure even that will always work. Still, I've been nagging the Apache people about this and maybe something will happen to change it.

So using mod_authnz_external with mod_authn_socache might be dumb, but, what the heck, when has mod_authnz_external ever passed up a chance to give you more rope to hang yourself with?

One more note: normally when you use mod_authn_socache with one of the standard Apache modules, a cache entry is created everytime it looks up a user's password in the database, even if the password they submitted wasn't the correct one. With mod_authnz_external it only happens after successful authentications. That's because mod_authnz_external doesn't have direct access to the password database. After a successful authentication we can fake-up something that looks to mod_authn_socache like some credentials out of a database by simple encrypting the password that the user sent us and pretending we got that out of a database. This means we don't get quite the performance gains that mod_authn_socache would give with something like mod_authn_dbd, but we get pretty close.

So here's how you do it. First your AuthBasicProvider statement should list both 'socache' and 'external', and it's important that 'socache' should be listed first, so that it tries to look up users in the cache before mod_authnz_external runs the authenticator:

       AuthBasicProvider socache external

Then you need to tell mod_authnz_external to start forging credentials for mod_authn_socache:

       AuthExternalProvideCache On

And you need to tell mod_authn_socache to accept credentials from mod_authnz_external:

       AuthnCacheProvideFor external

And that should do it. You should see many fewer runs of the external authenticator, and perhaps a slight decline in your overall security.

Note: As of Apache 2.3.14-beta, mod_authn_socache will dump core if you try to configure it from a .htaccess file. You must configure it from a <Directory> block in the httpd.conf file. A fix has been added to the development release which will enable it to be configured from a .htaccess file if and only if you have a "AuthnCacheEnable" directive in the httpd.conf file. This is stupid, and I hope it will be changed before this is out of beta.

3.7. Old Directives

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

AuthExternalGroupsAtOnce equals GroupExternalManyAtOnce

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

You can’t perform that action at this time.