NOTE: OpenBSD 3.8-current is required to build and install the module. 3.8-current includes a dynamically linkable version of libevent which is required in order to link libevent with an Apache module. Alternatively, you could selectively update and re-install /usr/src/lib/libevent.
mod_auth_bsd is an Apache module that supports BSD Authentication on OpenBSD. As of version 0.8.0 it can authenticate even when Apache is run in a chroot jail, as it is in a default installation of OpenBSD. Also as of 0.8.0, the login_bsd wrapper has been removed. The wrapper was no longer required and gave too much privileged system access to regular users.
Currently mod_auth_bsd only supports AuthType Basic and the "login" service protocol, so your available authentication options are limited to a user/pass pair as entered through a browser via HTTP Basic authentication, and passing that user and password to the wrapper (and thus to any underlying system authentication scripts). Fortunately, this is the typical usage for almost all Apache auth modules.
By default mod_auth_bsd erases the supplied password after verifying a user. This way CGI or in-process scripts such as PHP and Perl are not able to see the password. Likewise, mod_auth_bsd checks for an SSL connection before continuing to authenticate. This behavior can be altered with the AuthBSDKeepPass and AuthBSDRequireSSL configuration directives, but is intended to help the developer protect the privacy of system passwords.
mod_auth_bsd also supports credential caching, both for successful and unsuccessful authentication attempts. Unsucccessful attempts can be throttled on a per-user basis by introducing a delay between failed authentication requests. This delay does not block the authentication daemon, though it will of course block the child httpd process.
In more recent environments (tested on OpenBSD 5.0),
the global configuration option
auth should be used. Adding
www's supplement group list is
insufficient to grant the authentication daemon
permission to authenticate the password.
Make default group for the authentication daemon
Support SSL certificate authentication. Not sure how to go about this.
A caching mechanism using browser cookies so that user authentication can be handled entirely by mod_auth_bsd. In other words, a way for mod_auth_bsd to track authenticated users outside of HTTP Auth protected areas. This way application developers would not need to duplicate work between protected areas (where passwords are actually transferred) and the rest of the website.
Support Require user and Require group. Add AuthBSDStrictRequire option. When enabled all Require directives must match to allow access. By default only one must match.
Add ability to query user information during authentication, specifically the ability to query group membership. Now it should be easy to make "Require group foo" work.
0.8.1 actually makes I/O in the daemon non-blocking (forgot the call to fcntl(2)).
Finally got around to making everything work in a chroot jail. Version 0.8.0 removes the login_bsd wrapper and introduces credential caching in the server.
Added experimental support for BSD Auth from a chroot'd Apache. The support includes a daemon which forks and execs the login_bsd wrapper on behalf of a socket peer. The daemon changes its UID to that of the peer after forking, and before parsing the credentials and executing the wrapper.
The SHA1 implementation in Apache 1.3 was broken for 64-bit platforms. Reverted to MD5 for use in mod_auth_bsd.
Added mechanism to prevent authentication of system accounts (e.g. root). The compile-time define is FAIL_BELOW_UID, which will automatically fail and log attempts to test authentication against accounts below the specified uid (defaults in Makefile to 1000).
Not defining, or setting FAIL_BELOW_UID to 0 disables this feature completely.
Reverted to revision 1.1 of login_bsd. The failure database is just untenable. Even if we were to operate on a copy, then that copy would be created as the user, since there is no `auth' user available to u+s to. So, then there would be a race where the user could alter the database just before it was swapped with the primary one.
The issue of a user being able to brute-force accounts is something that cannot be handled reasonably at this level. Possibly the best option is just to nanosleep(2) for a 1/2 second before checking credentials. Authenticating is an operation that should not happen often.
This poses a problem for the mod_auth_bsd implementation, since in HTTP authentication the user/name is authenticated every single time. So, possibly now is a good time to integrate an optional caching mechanism into mod_auth_bsd.
After giving some thought to how to handle signals, it seems that the current use of the database subjects it to corruption when a user kills the process as it writes to the database. The kill(2) man page says that users can still send SIGKILL to setgid processes.
The best solution is probably to create a directory in the LOCALSTATEDIR with the database and a separate lock file. Writes will occur to a copy of the database, and then the copy can be swapped with the original atomically using rename(2).
For practical purposes this problem is only significant locally, since it would be rather hard (if possible at all) for an attacker to somehow misuse mod_auth_bsd or apache to signal the child program.
Committed Makefile changes: 1) default LOCALSTATEDIR is /var/db, since /var/run gets wiped on reboot and we need the failure log (with its permissions) to stay around; and 2) initialize the failure log on install so that dbopen(O_RDONLY) doesn't fail.
Committed SSL detection. SSL is required by default unless the AuthBSDRequireSSL flag is turned `Off'.
Committed auth log expired entry culling and checking against auth log for failures and penalties upon every authentication attempt. Remote and local brute force and dictionary attacks should be sufficiently moderated w/ minimum expense to legitimate users.
HMAC code is committed and seems to work fine.
Because of internal redirects, the password erasure code makes the module fail, at least for regular html and index content handlers (this module was originally tested on PHP, where the issue did not manifest). One solution seems to be to replace the password with a digest, which is an HMAC of the user name and an internally secret key. The module will first check to see if the password is a valid digest. I have code which works this way, and am fixing some bugs. Stay tuned.
Copyright (C) 2003, 2005, 2006 William
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Global options control the authentication daemon:
AuthBSDUser www | jimmy | ...
AuthBSDGroup www | auth | ...
In any directory or location directive, you can set the following options:
AuthBSD On | Off
AuthBSDKeepPass On | Off
AuthBSDRequireSSL On | Off
AuthBSDStrictRequire On | Off
AuthBSDService login | challenge
AuthBSDStyle passwd | radius | ldap | ...
AuthBSDType auth-www | auth-webdav | ...
You must also set AuthType Basic to enable HTTP Basic authentication in Apache. SSLRequireSSL is requisite for security purposes. An example configuration is:
AuthName "ACME Login"
For more information on BSD Authentication in OpenBSD, read the authenticate(3) man page: man authenticate
If you find this work useful, show your gratitude by giving back to the community.