From 0c0237b7494669b7ee306425c8d937ccf4d2631b Mon Sep 17 00:00:00 2001 From: Google Code Exporter Date: Fri, 24 Apr 2015 10:30:47 -0400 Subject: [PATCH 1/1] Migrating wiki contents from Google Code --- AuthHowTo.md | 222 ++++++++++++++++++++++++++++++++ AuthList.md | 108 ++++++++++++++++ AuthNZ.md | 7 + ConfigApache22.md | 262 ++++++++++++++++++++++++++++++++++++++ ConfigApache24.md | 283 +++++++++++++++++++++++++++++++++++++++++ Configuration.md | 4 + FutureFeatures.md | 51 ++++++++ HardCode.md | 63 +++++++++ HistoryNotes.md | 11 ++ Installation.md | 139 ++++++++++++++++++++ Links.md | 67 ++++++++++ ModAuthzUnixGroup.md | 46 +++++++ ModAuthzUnixGroup22.md | 55 ++++++++ ModAuthzUnixGroup24.md | 39 ++++++ ProjectHome.md | 57 +++++++++ UpgradeTo24.md | 77 +++++++++++ UpgradeToNZ.md | 75 +++++++++++ 17 files changed, 1566 insertions(+) create mode 100644 AuthHowTo.md create mode 100644 AuthList.md create mode 100644 AuthNZ.md create mode 100644 ConfigApache22.md create mode 100644 ConfigApache24.md create mode 100644 Configuration.md create mode 100644 FutureFeatures.md create mode 100644 HardCode.md create mode 100644 HistoryNotes.md create mode 100644 Installation.md create mode 100644 Links.md create mode 100644 ModAuthzUnixGroup.md create mode 100644 ModAuthzUnixGroup22.md create mode 100644 ModAuthzUnixGroup24.md create mode 100644 ProjectHome.md create mode 100644 UpgradeTo24.md create mode 100644 UpgradeToNZ.md diff --git a/AuthHowTo.md b/AuthHowTo.md new file mode 100644 index 0000000..33cdd53 --- /dev/null +++ b/AuthHowTo.md @@ -0,0 +1,222 @@ +## 1. Languages ## + +External authenticators can be written in almost any language. I've seen examples in C, Perl, Python, Java, Ruby and sh. The sample +authenticators in the 'test' directory are in Perl. The 'pwauth' +authenticator is in ANSI C. The example code fragments in this document +are in C. + +It should be noted that there is one compelling advantage to using a compiled language like C for the authenticator. Authenticators are run anew for every HTTP request that needs authentication. If your page references 5 images that are also in the protected directory, then your authenticator will be run six times every time the page is loaded. Interpreted programs are slow to start up. Every time you run a Perl program, the whole huge Perl interpreter needs to be run and it needs to read and compile your script file before it can start executing it. By contrast, if you write it in C, then each invocation requires only that the rather small compiled program be loaded and run. So the performance difference is likely to be substantial. And though C programs are certainly harder to write and debug, in most cases it isn't going to be that big a program, so the extra effort isn't that much. + +If the authenticator is a script rather than a compiled program, it normally +has to start with a "'#!/bin/sh'" or "'#!/usr/bin/perl'" type directive. Scripts +without such directives may get interpreted by the shell, or may just not +work, depending on your installation. + +## 2. Security ## + +The authenticator program should be written with great care because it runs +as a privileged user and handles privileged data. A poorly written +authenticator could substantially compromise the security of your system. +You get points for paranoia. Some notes: + + * Don't make any assumptions about the length of the login names and passwords given by the user. I _think_ Apache will never pass you ones that are longer than 8192 characters, but don't depend this. C programmers should check very carefully for buffer overflows. + + * Don't make assumptions about the content of the login and password strings. For example, if you are using them in an SQL query, do proper checking and/or quoting to insure that nobody is doing SQL injection. + + * Think about locking. It is possible to get lots of hits at your website very fast, so there may be many programs simultaneously reading your authentication database, plus updates may be going on at the same time. Probably some form of locking is needed to make all this work right. + + * If you are programming in C, think about core dumps. On some systems core dump files can be publicly readable. A core dump from your authenticator is likely to contain the user's plain text password, and may include large chunks of your password database that may have been in buffers. For C programs on most versions of Unix, it is possible to disable core dumps by doing something like: +``` + rlim.rlim_cur = rlim.rlim_max = 0; + (void)setrlimit(RLIMIT_CORE, &rlim); +``` + +It may not hurt to spend a little time looking at the features of the [pwauth](http://code.google.com/p/pwauth/) +authenticator, which is the most secure external authenticator that I have +written. + +## 3. Password Authenticators ## + +Authenticators communicate their result by the exit status code they return. +A value of 0 indicates that the password is correct. Other values indicate +that the password is incorrect, or something else is wrong. It can be +useful to return different numeric error codes for different kinds of errors, say 1 for "no such login", 2 for "bad password", 3 for "cannot read password database", etc. These +will be logged in the Apache error log file, and can be helpful in diagnosing +problems. `Mod_auth*_external` does not have any provision for +returning textual error messages from the external authenticator. You might +be able to use syslog() for this. This might be improved in future releases. + +Returned error codes should not be negative. Negative values are used +internally in 'mod\_authnz\_external' to indicate problems launching your program or retrieving the returned status code after it exits. + +Messages written to standard error will go into the Apache error log. This can be useful for error logging and debugging. You should not write out the password in any production configuration. + +How the external authentication program gets its arguments depends on +the method used. The method used is determined by the '`SetExternalAuthMethod`' +command in your Apache configuration file. You need implement only the +method that you plan to use in your configuration, which should almost always be the "pipe" method. + +### 3.1. Password Authenticators using Pipe Method ### + +In the "pipe" method, the arguments are read from standard input. The user name will be on the first line, and the password will be on the second. Here's a typical chunk of C code to read that: + +``` + main() + { + char user[100], password[100], *p; + + if (fgets(user, sizeof(user), stdin) == NULL) exit(2); + if ((p= strchr(user, '\n')) == NULL) exit(4) + *p= '\0'; + + if (fgets(password, sizeof(password), stdin) == NULL) exit(3); + if ((p= strchr(password, '\n')) == NULL) exit(5) + *p= '\0'; + + if (check_password(user, password) == OK) + exit(0); /* Good Password */ + else + exit(1); /* Incorrect Password */ + } +``` + +Here we simply read two lines from stdin, being careful not to allow buffer overflows and stripping off trailing newlines. + +We assume "`check_password()`" is some function that checks the validity of a +password and returns 'OK' if it is good. + +Note that we exit with different non-zero error codes in different error cases. This will be helpful for debugging, as those values will be logged when authentication fails, giving you some clue as to what went wrong. It'd really be better for check\_password() to return more detailed error codes, but I wanted to keep the example simple. + +### 3.2. Password Authenticators using Checkpassword Method ### + +The "checkpassword" method is identical to the "pipe" method, except that the user name and password are terminated by NUL (`'\0'`) characters instead of newline characters, and they must be read from file descriptor 3 instead of standard input. Documentation for the checkpassword interface is at http://cr.yp.to/checkpwd.html. + +### 3.3. Password Authenticators using Environment Method ### + +In the "environment" method, the arguments are passed in environment variables. The user id and the clear-text password are passed in the USER and PASS environment variables respectively. + +Note that the environment method has fundamental security weaknesses, and should probably not be used. Use the pipe method instead. + +A typical chunk of C code to authenticate with the environment method might be like: + +``` + main() + { + char *user, *password; + + if ((user= getenv("USER")) == NULL) exit(2); + if ((password= getenv("PASS")) == NULL) exit(3); + + if (check_password(user, password) == OK) + exit(0); /* Good Password */ + else + exit(1); /* Incorrect Password */ + } +``` + +## 4. Group Authenticators ## + +Security is generally less of a issue with group authenicators, since they are not handling any data as sensitive as clear-text passwords. They are only passed a user name (presumably already authenticated), and a list of group names. They exit with status code 0 if that user is in one of those groups, and a non-zero code otherwise. + +In versions of `mod_auth_external` before 2.1.8, external authenticators were always passed just one group name. If the Apache "`require group`" directive listed more than one group, then the external authenticator would be called once with each group name, which could be inefficient if you have a large number of groups. `Mod_auth_external` will still behave this way if you issue the "`GroupExternalManyAtOnce off`" directive. + +Newer versions of `mod_auth_external` and `mod_authnz_external` will pass all group names, separated by spaces. There will only be multiple calls if more than one "require group" (or "require external-group" in Apache 2.4) directive applies to the same program (e.g., if different parent directories contain such directives in their `.htaccess` files - for efficiency, this should be avoided). The list of group names is passed in exactly as they appear on the "require group" directive - if your program can't handle multiple spaces between group names, don't put them there. + +Arguments are passed in a manner similar to password authenticators. The method used is determined by the '`SetExternalGroupMethod`' command in your Apache configuration file. + +### 4.1. Group Authenticators using Pipe Method ### + +In the "pipe" method, the arguments are read from standard input. The user name will be on the first line, and the group name will be on the second. Here's a typical chunk of C code to read that: +``` + main() + { + char user[100], groups[100], *group, *p; + + if (fgets(user, sizeof(user), stdin) == NULL) exit(2); + if ((p= strchr(user, '\n')) == NULL) exit(4) + *p= '\0'; + + if (fgets(groups, sizeof(groups), stdin) == NULL) exit(3); + if ((p= strchr(groups, '\n')) == NULL) exit(5) + *p= '\0'; + + group= strtok(groups, " "); + while (group != NULL) + { + if (check_group(user, group) == OK) + exit(0); /* User is in group */ + group= strtok(NULL, " "); + } + exit(1); /* User is not in any group */ + } +``` + +We simply read two lines from stdin, being careful not to allow buffer overflows and stripping off trailing newlines. We loop through all groups, checking each. + +Here "check\_group()" is some function that looks in your database to see if user is in group and returns 'OK' if he is. + +### 4.2. Group Authenticators using Checkpassword Method ### + +Mod\_auth\_external will happily try to do group authentication via the checkpassword method, piping NUL (`'\0'`) terminated user and group names to the child process's file descriptor 3, but this isn't actually allowed for in the checkpassword protocol specification, so I don't recommend it. + +### 4.3. Group Authenticators using Environment Method ### + +In the "environment" method, the arguments are passed in environment variables. The user id and the group names are passed in the USER and GROUP environment variables respectively. A typical chunk of C code to fetch the arguments and check each group might be like: + +``` + main() + { + char *user, *groups, *group; + + if ((user= getenv("USER")) == NULL) exit(2); + if ((groups= getenv("GROUP")) == NULL) exit(3); + + group= strtok(groups, " "); + while (group != NULL) + { + if (check_group(user, group) == OK) + exit(0); /* User is in group */ + group= strtok(NULL, " "); + } + exit(1); /* User is not in any group */ + } +``` + + +## 5. Other Environment Variables ## + +In all cases (pipe or environment method, password or group authentication), the following additional environment variables will be supplied to the authenticator: + +| AUTHTYPE | either "PASS" or "GROUP" depending on whether we are doing password or group authentication. This is handy if you are using one program to do both. | +|:---------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| +| CONTEXT | a string whose value is set by an "AuthExternalContext" directive in the .htaccess file or "``" block for the directory. This can be used to select different authentication behaviors in different directories. It is undefined if there is no "AuthExternalContext" directive. | +| IP | the client's ip-address. | +| HOST | the client's host name, if Apache has "`HostnameLookups` On". | +| PATH | the httpd's path environment variable. | +| COOKIE | all cookie values passed in by the client. | +| HTTP\_HOST | the server's host name, as given in the HTTP request. May be useful if you have multiple virtual hosts sharing an authenticator. | +| URI | the document requested. This is the URL including any extra path information, but not including the hostname or any CGI arguments.| + +These may be useful for logging, or you may want to accept logins from certain users only if they are connecting from certain locations or requesting certain documents. + +Note that if you have configured Apache with "`HostnameLookups Off`" then HOST will usually not be set. If you really want host names, either turn on `HostnameLookups` or do your own `gethostbyaddr()` calls from the authenticator when HOST is not defined. Note that if the user is coming from an unresolvable IP, then host name lookups can be very slow. + +Note that using IP addresses to track a user through your site is not reliable. Users of services like AOL and WebTV use proxy servers, so that their IP addresses appear to change constantly since each request my come through a different proxy. A single user's requests for successive pages, or for different images on the same page may all come from different IP addresses. + +The PATH environment variable passed to the authenticator is just whatever PATH was in effect when Apache was launched, and may differ if the server was launched automatically during a reboot or manually by an admin. Probably your program should set its own PATH if it needs one. + +The COOKIE environment variable contains all cookies set in the current request. This has the same format as the HTTP\_COOKIES ("`key=val;key=val`") passed to a CGI program. This should be used with caution. Cookies come from the user's computer and might have been created, editted or deleted by the user rather than your website. This severely limits their use for authentication. It is not possible to set cookies from an authentication module. + +The URI variable is there because various people want it. Mostly it is useful not for authentication ("who is this person?") but for access control ("is this person permitted to do this?"), and good design usually dictates separating those functions. Strictly speaking, an authenticator is not the right place to be doing access control. Furthermore, in mod\_authnz\_external 3.3.0 and later requests to new URI's within the same authentication configuration may not always trigger a re-authentication. This will never happen for sub-requests (like an internal redirection or a server-side-include) and may not happen for other requests if you use mod\_authz\_socache. So really the URI should only be used for logging, not for anything that effects whether you accept the request or not. + +## 6. Testing ## + +You should test you authenticator in isolation before trying to run it from `mod_authnz_external`. For an authenticator that takes input from a pipe, I typically issue the following command from 'csh' or 'tcsh': +``` +./myauth; echo $status +``` +or from 'sh' or 'bash': +``` +./myauth; echo $? +``` +Then I type in the login and password, one per line. The correct status code should come back right after I enter the password, zero for valid logins, other values for invalid ones. \ No newline at end of file diff --git a/AuthList.md b/AuthList.md new file mode 100644 index 0000000..cc10e63 --- /dev/null +++ b/AuthList.md @@ -0,0 +1,108 @@ +`Mod_auth_external` is, of course, useless unless it has an external authenticator to run. There are some examples of authenticators included in the distribution, and several useful ones are available separately. + +## Example External Authenticators in Distribution ## + +
+
test
+
+Several small dummy external authentication programs written in Perl. These are meant only for testing of mod_auth*_external. They accept any user whose password exactly matches his login name. They write lots of debugging info to the error_log file.
+
+Author and Maintainer: Jan Wolter + +
+ +
auth-mysql
+
+A external authenticator for authenticating out of a MySQL database. Written in Perl using the DBI/DBD library, so it is easily adapted to any other SQL server. (These days, using Apache's mod_authn_dbd is probably a better choice for most appications.)
+
+Author and Maintainer: Anders Nordby + +
+
+ +## Example Internal Authenticators in Distribution ## + +
+
radius
+
+A Radius client using code from the publicly available Merit Radius source code. Unmaintained. + +Author: Tyler Allison (allison@nas.nasa.gov)
+
+
+ +
sybase
+
+A function that queries a sybase database and compares the passwords for said user.
+Unmaintained. + +Author: br@ota.fr.socgen.com
+
+
+ +## Authentication Modules Available Separately ## + +`Mod_auth*_external` can be used either with authenticators specifically written for it or with [checkpassword](http://cr.yp.to/checkpwd.html) authenticators. This is not a [complete list](http://www.qmailwiki.org/index.php/Qmail-checkpassword) of `checkpassword` authenticators, but I'll include a few here. + +
+
pwauth
+
+A setuid-root external authentication program for securely authenticating out of most flavors of Unix shadow password files, or via PAM. Combined with 'pam_smb', this supports NT-style SMB authentication. Supports some Unix lastlog and faillog options.
+
+Available From: http://code.google.com/p/pwauth/ + +Author and Maintainer: Jan Wolter +
+ +
vcheck
+
+An external authenticator by Anders Brander for use against a vpopmail user database.
+
+Available From: http://anders.brander.dk/stuff/workings/vcheck/ + +Author and Maintainer: Anders Brander
+
+ +
checkpassword
+
+The original checkpassword program authenticates from the Unix system password file, like pwauth.
+
+Available From: http://cr.yp.to/checkpwd/install.html + +Author: D. J. Bernstein
+
+ +
checkpassword-pam
+
+Another way to authenticate via PAM.
+
+Available From: http://checkpasswd-pam.sourceforge.net/ + +Author: Alexey Mahotkin alexm@hsys.msk.ru
+
+ +
checkpassword-ldap
+
+An LDAP authenticator.
+
+Available From: http://freshmeat.net/projects/checkpassword-ldap/ +
+ +
checkpasswd-imap
+
+An IMAP authenticator written in Python that caches credentials for better performance and so you don't overrun server rate limits.
+
+Available From: http://www.namazustudios.com/blog/checkpasswd-imap-a-mod_authnz_external-style-password-checker/ + +Author: Patrick Twohig
+
+ +
radcheckpassword
+
+Checking against external Radius server(s).
+
+Available From: http://free.acrconsulting.co.uk/email/radcpw.html + +Author: Andrew Richards
+
+
\ No newline at end of file diff --git a/AuthNZ.md b/AuthNZ.md new file mode 100644 index 0000000..49120df --- /dev/null +++ b/AuthNZ.md @@ -0,0 +1,7 @@ +Users of `mod_authnz_external` may find it helpful understand a bit more of it's internal structure. It is actually best thought of as two functionally separate modules, `mod_authn_external` and `mod_authz_external`, which have combined into a single module simply because they share a lot of code (actually more recent revisions have reduced the amount of shared code, and it may actually make sense to split the module someday). In any particular application, you may only be using one of these two modules, or you may be using both. + +The `mod_authn_external` part is an authentication provider for the `mod_auth_basic` module. `Mod_auth_basic` handles all the negotiations with the browser, while all `mod_authn_external` does is check if a password submitted by the user is correct (which it does by running an external program to perform the check). + +The `mod_authz_external` part does access control. In Apache version 2.2, it had no relation to `mod_auth_basic`. It comes into play after authentication is complete, when a "`Require group`" or "`Require file-group`" directive is given. It checks if the authenticated user is in the list of required groups (which it does by running an external program to perform the check). + +In Apache 2.4, the split in functionality remains the same, but the `mod_authz_external` access control checker becomes a provider to `mod_auth_basic` just as the authenticator already was. \ No newline at end of file diff --git a/ConfigApache22.md b/ConfigApache22.md new file mode 100644 index 0000000..38f066c --- /dev/null +++ b/ConfigApache22.md @@ -0,0 +1,262 @@ + + +**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. +
  3. 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.
    +
  4. +
+ +## 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 `` block. The declarations must be _inside_ the `` 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 `` 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 +``` + +Old-Style Syntax: +``` +AddExternalAuth +SetExternalAuthMethod +``` + +`` is some name you choose to identify the authenticator. You can configure multiple different external authenticators by using different keywords for them. + +`` 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. + +`` 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:** `` 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:** `` is a string like "`:`". The `` part is a string that can be used to select from multiple internal functions. `` is a string passed to that function and is typically used as config file path. The "`:`" is required even if the `` 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 +``` + +Old-Style Syntax: +``` +AddExternalGroup +SetExternalGroupMethod +``` + +`` 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`. + +`` 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 `` 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 `` block: +``` +AuthType Basic +AuthName +AuthBasicProvider external +AuthExternal +Require valid-user +``` + +Here `` identifies what we are authenticating for - it usually appears in the browser's pop-up login window. `` 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 ... +``` +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 ... +``` +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 +AuthBasicProvider external +AuthExternal +GroupExternal +Require group ... +``` + +Here `` 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 +``` +This will simply pass whatever `` 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](Installation.md) page for the rest of the setup procedure.** \ No newline at end of file diff --git a/ConfigApache24.md b/ConfigApache24.md new file mode 100644 index 0000000..bf88ef9 --- /dev/null +++ b/ConfigApache24.md @@ -0,0 +1,283 @@ + + +**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/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.
    +
    +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. +
  3. 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.
    +
  4. +
+ +## 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 `` block. The declarations must be _inside_ the `` 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 `` 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 +``` + +Old-Style Syntax: +``` +AddExternalAuth +SetExternalAuthMethod +``` + +`` is some name you choose to identify the authenticator. You can configure multiple different external authenticators by using different keywords for them. + +`` 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. + +`` 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:** `` 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:** `` is a string like "`:`". The `` part is a string that can be used to select from multiple internal functions. `` is a string passed to that function and is typically used as config file path. The "`:`" is required even if the `` 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 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 +``` + +Old-Style Syntax: +``` +AddExternalGroup +SetExternalGroupMethod +``` + +`` 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`. + +`` 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 `` 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 `` block: +``` +AuthType Basic +AuthName +AuthBasicProvider external +AuthExternal +Require valid-user +``` + +Here `` identifies what we are authenticating for - it usually appears in the browser's pop-up login window. `` 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 ... +``` +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 ... +``` +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 +AuthBasicProvider external +AuthExternal +GroupExternal +Require external-group ... +``` + +Here `` 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 +``` +This will simply pass whatever `` 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 `` 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](Installation.md) page for the rest of the setup procedure.** \ No newline at end of file diff --git a/Configuration.md b/Configuration.md new file mode 100644 index 0000000..f8c400d --- /dev/null +++ b/Configuration.md @@ -0,0 +1,4 @@ +Please read the configuration version for your version of Apache: + + * ConfigApache22 - Apache version 2.2 + * ConfigApache24 - Apache version 2.4 \ No newline at end of file diff --git a/FutureFeatures.md b/FutureFeatures.md new file mode 100644 index 0000000..b92eaa2 --- /dev/null +++ b/FutureFeatures.md @@ -0,0 +1,51 @@ +Several design changes are under consideration for `mod_authnz_external`. I'm interested in feedback on these ideas, or in other ideas that people might find useful. + +## Splitting the Module ## + +It would be possible to split the module into two modules, `mod_authn_external` which would do password checking and `mod_authz_external` which would do group checking. The original justification for combining the two was that there was a lot of shared code between them, but the 3.2 rewrite reduced that, because much of the business of launching the external process was farmed out to Apache's process management library. At this point the main area of overlap is the `exec_external()` which is largish, but not so largish that the need for combining the two modules is compelling. + +The main advantage would be in replacing one complex module with two simpler modules. People who only need one of them, which I think means most people, would be installing a smaller module with simpler configuration instructions. The minority who use both would have to install two modules, but configuration would still be much the same. + +We'd have to split the `AuthExternalContext` command into two commands each effecting one module. + +At this point I'm not quite ready to do this. The benefits aren't that great, and it's confusing enough having `mod_authnz_external` and `mod_auth_external` without adding `mod_authn_external` and `mod_authz_external` to the mix. Maybe if something else comes along to compel another major re-design of the module, then this could be done at the same time. + +## Authentication Daemons ## + +`Mod_authnz_external` currently works by running the authenticator each time an authentication is needed. You might get better performance if the authenticator were a persistent daemon to which `mod_authnz_external` made socket connections each time an authentication was needed. Probably we'd define the authenticator with a command like: +``` +DefineExternalAuth server : +``` +When an authentication was needed, `mod_authnz_external` would open a socket connection to the given host and port. If `` was "`localhost`" and we were running on a Unix system it would do a UNIX socket. It would write the login name and password to the socket, and the authenticator would check them and write back either "OK" or an error message which `mod_authnz_external` would log. + +There are obvious performance advantages to this. Establishing a socket connection is probably faster than launching a new process. Plus the authenticator can do things like maintaining persistent database connections and caching recent authentications that can further improve it's performance. Plus it opens up the possibility of having the authenticator running on a different server than the HTTP daemon. + +There are some down sides too though. Certainly the authenticator is going to be much harder to write. Instead of just reading from stdin and returning an exit code, it must listen for connections on a socket. However we could supply sample templates for that part of the code and people could just fill in their own authentication code. + +Authentication daemons could become a bottleneck. There are usually many httpd processes running on a server. If they all have to go to the same authentication daemon for their authentications, then this could be a problem on busy servers. And if the server isn't busy, why use a daemon at all? + +Problems could also arise if the authentication daemon died or stopped responding. One possibility would be to have `mod_authnz_external` restart the daemon if it is not responding. We could introduce another syntax, like this: +``` +DefineExternalAuth daemon : +``` +Unlike the "`server`" option, this would always have the daemon running on localhost, with the given port number. If it fails to respond, then it would run the program at the given pathname, wait a few seconds, and try again to make a socket connection. + +The daemon would have to be built with the usual restart logic, where upon start up it checks if a copy is already running, kills that if it exists, and then starts serving. So again the complexity of the authenticator goes up. + +None of this would be terribly hard to build into `mod_authnz_external`. There are already hooks in the `exec_external()` function that would make it able to launch daemons. I'd need to research to see what kind of socket management can be done through the Apache API (see [here](http://apr.apache.org/docs/apr/trunk/group__apr__network__io.html) and [here](http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html)), since I'd prefer not to make this Unix dependent. One of the biggest questions would be the protocol used to communicate over the socket to the authenticator. Many protocols exist that include authentication. Could we do something compatible with one of those that would allow us to use some existing daemons with this? + +But I think that before I under took this I'd want to have someone who seriously wanted this feature and was willing to invest some time on testing and development. I don't have a production server where this would make sense, and if I construct it as a pure theoretical exercise, then I'm afraid it might turn out unusable in practice. + +Actually, I'm afraid of that in any case. Good, stable, scalable server programs are hard to write, and without one an authentication system built on this would tend to be fragile. I think the existing method of starting up a fresh authenticator for each request may well be better for most applications. + +## Caching Authentications ## + +If you have a user logged onto your system, then you need to re-authenticate him for every HTTP request he makes. This is stupid. It should be possible to cache the fact that a given login/password pair is valid, and skip launching the authenticator if we recently checked that pair. + +Actually, this shouldn't be part of `mod_authnz_external` but should be a separate module. There is already a [mod\_auth\_cache](http://mod-auth-cache.sourceforge.net/) but it appears to cache the login data in a cookie, where it can readily be manipulated by the user. This is completely unacceptable. The cache needs to be on the server side. + +The cache could simply be kept in Apache's memory, but there are typically many copies of Apache running, and ideally you'd like the cache to be shared across them all. Possibly a dbm file or shared memory could be used. If you were using a disk cache, you'd probably do something like take an MD5 checksum of login/password/domain, and use that as a key into the dbm file, with the last access time as the value. With a stored memory solution you could probably skip the encryption. + +There seems to be a [caching option for mod\_auth\_ldap](http://www.muquit.com/muquit/software/mod_auth_ldap/mod_auth_ldap_cache.html) that uses a dbm file. Might be worth looking at that as an example. + +Apache 2.4 will have a [ap\_socache.h](http://svn.apache.org/repos/asf/httpd/httpd/trunk/include/ap_socache.h) interface that defines a new distributed small-object cache interface. Should check if that is going to be useful. \ No newline at end of file diff --git a/HardCode.md b/HardCode.md new file mode 100644 index 0000000..dfe607f --- /dev/null +++ b/HardCode.md @@ -0,0 +1,63 @@ +There are some hooks in `mod_authnz_external` designed to make it easy to replace the call to an external authenticator with a call to an internal function. This is a bit weird, as such internal functions have none of the advantages of an external authenticator, but this can be a short-cut way to create a custom authentication module. + +The procedure is as follows: + +### Step 1: ### + +Edit "`mod_authnz_external.c`" + +### Step 2: ### + +Uncomment the `_HARDCODE_` #define. + +### Step 3: ### + +Uncomment the line: +``` +/* #include "your_function_here.c" */ +``` + +Actually, I think it might be better to embed the function itself directly in this file instead of including it. Modules work better if they are implemented in a single source file. + +Your function should start something like: +``` +int example(char *user_name,char *user_passwd,char *config_path) +``` +Obviously you should call it something other than `example`, but the rest of the function declaration should be just as above. + +It should return 0 if the password is correct for the given user, and other values if it is not, pretty much just like external authentication programs do. + +You'll want to code this very carefully. A crash will crash not just your program but the entire httpd. + +**DO NOT** use exit() or other such calls that will cause your function to exit abnormally or dump core. It will take the entire httpd with it and display a message to your browser saying "no data". Use "return" instead of exit(). + +### Step 4: ### + +Choose an all-caps function name for your function. ie: 'RADIUS' or 'SYBASE' This will be used for telling mod\_authnz\_external which hard coded function you want to call. In this documentation we will call it `EXAMPLE`. + +### Step 5: ### + +Find the `exec_hardcode()` function inside `mod_authnz_external.c`. Find the big commented section there. Replace the example call to `example()` with a call to your function. Also change the name "`EXAMPLE`" to the name you chose for your function. + +The function call in `exec_hardcode()` should look something like: +``` +if (strcmp(check_type,"EXAMPLE")==0) { + code = example(c->user,sent_pw,config_file); +} +``` + +Here, we replace "EXAMPLE" with the name you chose in step 4 and "example" with whatever you called your function in step 3. + +### Step 6: ### + +Save your work. Also save some whales. + +### Step 7: ### + +Compile and configure mod\_authnz\_external as described on the [Installation](Installation.md) and [Configuration](Configuration.md) pages. + +The AddExternalAuth command in your httpd.conf file might look something like +``` +AddExternalAuth whatever EXAMPLE:/usr/local/data/configfile +``` +Here 'whatever' is the name you will use to invoke this authenticator in the AuthExternal commands in your .htaccess files. 'EXAMPLE' is the name you choose in step 4 and inserted into the "if" statement in step 5. Any data after the colon will be passed into your function as the argument called "'config\_path`" in the sample function declaration in step 3. It might be a config file path or something else. \ No newline at end of file diff --git a/HistoryNotes.md b/HistoryNotes.md new file mode 100644 index 0000000..9aa7df7 --- /dev/null +++ b/HistoryNotes.md @@ -0,0 +1,11 @@ +## License and Copyright ## + +The first version of `mod_auth_external` was written by Nathan Neulinger. My theory is that he started with some apache module, like 'mod\_auth\_file' and started editing it to turn it into `mod_auth_external`. He just left the original Apache license in there. It was, after all, still partly Apache's code. This is why the copyright message in 'mod\_auth\_external' says the copyright is held by the Apache Group, although the Apache group is in no way responsible for this code. + +Since then `mod_auth_external` has suffered three major rewrites and many small evolutionary changes, and about all that is untouched is the 1995 vintage Apache copyright/license message in front. Does this make sense? The authors of 'mod\_auth\_external' haven't the faintest idea and none of them care very much. + +## Version Branches ## + +There used to be another version of `mod_auth_external` maintained by Satoh Fumiyasu. I believe the last version was called version 3.0.0beta3. The versions seem to have diverged after version 2.0.0, Tyler Allison's next-to-last release. It differed significantly from this version, and was not precisely compatible. Fumiyasu's version supported authenticating through a socket against an authentication daemon, a feature I may support in the future. It's documentation was mostly in Japanese. This seems to have largely disappeared from sight. + +However, this is the reason why the version of `mod_auth_external` distributed here skipped the version number 3.0. \ No newline at end of file diff --git a/Installation.md b/Installation.md new file mode 100644 index 0000000..7f817d5 --- /dev/null +++ b/Installation.md @@ -0,0 +1,139 @@ +## Notes: ## + +Before installing, note the following: + + * These instructions are for the current version of `mod_authnz_external`. The installation procedure for older versions is very similar, and is documented in the INSTALLATION file included in the distribution. + + * Make sure that you are using the correct version of `mod_auth_external` for your version of Apache: +| Apache 2.4 | mod\_authnz\_external-3.3.x | +|:-----------|:----------------------------| +| Apache 2.2 | mod\_authnz\_external-3.1.x or mod\_authnz\_external-3.2.x | +| Apache 2.0 | mod\_auth\_external-2.2.x | +| Apache 1.3 | mod\_auth\_external-2.1.x | + +> You can check your apache version by running it from the command line with the -v flag. + + * Originally, `mod_auth_external` was a stand-alone module. However a new authentication module structure was introduced in Apache-2.1, where `mod_auth_basic` and `mod_auth_digest` are the only top-level authentication modules. All other authentication modules simply provide authentication services to these modules, and have names starting with "`mod_authn_`" for authentication modules, or "`mod_authz_`" for access control modules, or "`mod_authnz_`" for modules that provide both services. `Mod_authnz_external` is designed to fit into this new structure. It has essentially the same features as `mod_auth_external`, but there are differences in the configuration commands. + +> It should be noted that it is still possible to use older-style independent authentication modules in Apache 2.2, and `mod_auth_external-2.2.x` can be made to work with only a little difficulty arising from `mod_auth_basic`'s reluctance to be turned off. See the `mod_auth_external INSTALL` document for information on using it with Apache 2.2. Do not, however, install both mod\_auth\_external and mod\_authnz\_external in your httpd. I don't know what exactly would happen, but it won't be good. + + * If you are upgrading from `mod_auth_external` to `mod_authnz_external` read the [Upgrading to Mod\_authnz\_external](UpgradeToNZ.md) page. + + * If you want to use `mod_authnz_external` with a hard-coded internal authentication function rather than with an external authenticator, then follow the [Hard Code Installation instructions](HardCode.md) before follow the instructions on this page. + + * Starting with version 3.2.x, mod\_authnz\_external is designed to work on any platform supported by Apache. Previous versions were Unix-only. So mod\_authnz\_external might work on Windows, but the author doesn't really do Windows development and doesn't even own a Windows C compiler. So it has not been tested at all, no pre-compiled Windows code is available, and there are no installation instructions for non-Unix platforms. If you figure any of this out, please consider contributing your findings. + + * There are two ways of installing mod\_authnz\_external on a Unix system. + 1. You can statically link it with Apache. This requires rebuilding Apache in such a way that 'mod\_authnz\_external' will be compiled in. This is rarely done in modern Apache installations, but might be done if you want to get slightly better performance. + 1. You can make mod\_authnz\_external a dynamically loaded module. If your Apache has been built to support dynamically loaded modules you can do this without rebuilding Apache, so it is pretty easy For information on dynamically loaded modules see http://www.apache.org/docs/dso.html . + +> This page gives instructions only for installing Apache as a dynamically loaded module. There are instructions for installing it statically in the INSTALLATION file in the distribution, but it has been so long since I have done this, that I do not know if they are still correct. + +## Step-by-Step Directions ## + +### (1) Check if Dynamically Loaded Modules are Supported ### + +Ensure that your Apache server is configured to handle dynamically loaded modules. These days, nearly all are, but if you want to check this, run Apache server with the -l command flag, like +``` + httpd -l +``` +If 'mod\_so.c' is one of the compiled-in modules, then you are ready to go. Note that some installations may give the http daemon different names, like 'apache' or 'httpd2'. Some may have multiple copies of apache sitting in different directories. Be sure you looking at the one that is being run. + +### (2) Compile the Module ### + +Use the following command in the 'mod\_authnz\_external` distribution directory: +``` + apxs -c mod_authnz_external.c +``` +'Apxs' is the Apache extension tool. It is part of the standard Apache distribution. If you don't have it, then there may be a Apache development package that needs to be installed on your system, or your Apache server may not be set up for handling dynamically loaded modules. Some systems rename it weirdly, like 'apxs2' in some openSUSE distributions. + +Apxs should create a file named '`mod_authnz_external.so`'. + +_AIX USERS_: If you have problems at this point, see the notes in the INSTALL file. + +### (3) Install the Module ### + +Apxs can do this for you too. Do the following command (as root so you can write to Apache's directories and config files): +``` + apxs -i -a mod_authnz_external.la +``` +This will create `mod_authnz_external.so` and copy it into the proper place, and add appropriate `AddModule` and `LoadModule` commands to the configuration files. + +### (4) Configure the Module ### + +The next step is to do the necessarily Apache configuration. The procedure is substantially different in different versions of Apache. See whichever of the pages below that applies you your Apache version for details: + + * ConfigApache22 - Apache version 2.2 + * ConfigApache24 - Apache version 2.3 or 2.4 + +### (5) Install the Authenticator ### + +Install your external authentication program in the location named by the pathname in the `AddExternalAuth` directive that you configured. + +Make sure everything is permitted so that whatever account the `httpd` runs under can execute the authenticator. Typically this requires 'execute' access to the script and all the directories above it. If it is a script, then read access to the script will also be needed. + +If your script is an set-uid script, then make sure the file is owned by the user it is supposed to run as, and that the suid-bit is set. + +### (6) Restart Apache ### + +Restart Apache, so that all the new configuration commands will be loaded. If you have the `apachectl` command do: +``` +apachectl restart +``` +For some systems which doesn't have `apachectl`, you'll want to manually run the startup script for apache. The locations of these vary somewhat in different Unix systems, but they typically are something like this: +``` +/etc/init.d/httpd restart +``` + +### (7) Test It ### + +Test your changes/code by trying to view a protected page. + +If it doesn't work, check the apache error logs. They are loaded with helpful information. Some common problems and their usual causes: + + * Miscellaneous odd behaviors. + +> Did you restart the httpd after the last time you edited the httpd.conf file, installed a new version of the module, or recompiled Apache? Confirm that an "Apache configured -- resuming normal operations" message appeared in the error log when you restarted. + + * Apache complains about not recognizing `mod_authnz_external` commands in the `httpd.conf` file like "`DefineExternalAuth`" and "`AddExternalAuth`". + +> Either the module didn't get installed (if you staticly linked the module, are you running the newly compiled copy of `httpd`?), or it isn't enabled (if it is dynamically linked, the `AddModule` and `LoadModule` commands described on the configuration pages may be missing, incorrect, or commented out by an inappropriate ``). + +> Sometimes I've found that the `httpd.conf` file I've been editing is not actually the one being used by the copy of Apache that is running. Sometimes I test this by inserting deliberately invalid commands and checking to see if error messages are generated when Apache is restarted. + + * It displays pages in a protected directory without asking for a login and password. + +> For some reason Apache is not seeing the directory configuration commands that set up authentication for that directory. If you are using `.htaccess` files, does your `httpd.conf` file say "`AllowOverride AuthConfig`" for the directory? Apache is usually distributed with "`AllowOverride None`" set, which will cause `.htaccess` files to be quietly ignored + + * All logins are rejected, and the error log says it cannot execute the authentication module. Error messages might look like: +``` +exec of '/foo/bar/authcheck' failed: (2) No such file or directory +[Thu Nov 15 12:26:43 2007] [error] AuthExtern authcheck + [/foo/bar/authcheck]: Failed (-1) for user foo +[Thu Nov 15 12:26:43 2007] [error] user foo: authentication + failure for /mae/index.html": Password Mismatch +``` + +> The first of these three messages is from Apache's process launching library, and gives the clearest information about what caused the error. Typically it will be either "No such file", which means that the pathname you specified for the authenticator in the Apache configuration file does not match the actual location of your external authenticator, or it will be "permission denied", indicating that either the file or one of the directories above it is permitted so whatever account apache is configured to run as does not have execute permission. If it's a script, it also needs read permission. + +> The second error message is actually generated by mod\_auth\_external. It just says authentication failed for the user. Normally it would give the status code returned by the authenticator in parenthesis, but if the authenticator could not be executed it will show a phoney status code of -1 (which some systems display as 255). + +> The third error message is from Apache. Don't be mislead by it's saying "Password Mismatch". When `mod_auth_external` fails, it rejects all access attempts. To apache this looks like a password mismatch. + + * Authentications failed and the message in the error log says it failed with a status code of -2 or 254, for example: +``` +[Thu May 21 12:29:46 2009] [error] [client 127.0.0.1] + External authenticator died on signal 9 +[Thu May 21 12:29:46 2009] [error] [client 127.0.0.1] + AuthExtern authcheck [/foo/bar/authcheck]: Failed (-2) for user foo +[Thu May 21 12:29:46 2009] [error] [client 127.0.0.1] + user foo: authentication failure for "/mae/index.html": Password Mismatch +``` + +> The status code of -2 (or 254) in the second message indicates that the authenticator crashed or was killed before it could return a status code. The first message identifies the particular signal number that terminated the process, either because some other process sent the signal, or because the program executed an illegal command causing a segmentation fault. Again, the "Password Mismatch" message from Apache is pretty meaningless. + + * There are several other internal errors that can theoretically occur in mod\_authnz\_external which will also be reported with error messages and negative status codes, similar to the previous example. These are rare and generally indicate really unusual exhaustions of system resources or bugs in mod\_authnz\_external, apache, or other modules. Read the source or contact the mod\_authnz\_external developers for help. + + * Error log says "Failed (X) for user foo" with X being some usually positive number and no other more specific error messages. + +> This means the authenticator ran, and exited with the given non-zero return code. You'll have to check the authenticator to see under what conditions it exits with that return code. This is the normal expected behavior for mod\_authnz\_external when an authenticator rejects a login. \ No newline at end of file diff --git a/Links.md b/Links.md new file mode 100644 index 0000000..a2e47da --- /dev/null +++ b/Links.md @@ -0,0 +1,67 @@ +Here are some relevant links. See also the [list of available external authenticators](AuthList.md): + +## Other Software ## + +
    +
  • Apache HTTP Server. Can't run mod_auth_anything without it.
    +
  • + +
  • pwauth external authenticator. Used with mod_auth*_external for authenticating out of a unix password database or via PAM.
    +
  • + +
  • mod_auth_shadow, by Bruce Duggan, appears to be a re-implementation of the same basic concept for authenticating out of shadow password file. I haven't checked it out enough to decide if it has any advantages over using pwauth with mod_auth_external. On first inspection it appears to be slightly less portable and paranoid.
    +
  • + +
  • mod_auth_pipe is Alvaro Gamez Machado's development from mod_auth_shadow, allowing it to run arbitrary authenticators. The result ends up doing pretty much the same thing as 'mod_auth_external'.
    +
  • + +
  • mod_auth_script looks like it can be used to perform similar functions to mod_auth_external. It runs the authenticator by generating a sub-request to a CGI program. I haven't analyzed this approach, but it has obvious advantages in that the authenticator programs are just normal CGIs.
    +
  • + +
  • Modification of mod-auth-external to enable authentication caching. This is a branch of mod_authnz_external 3.2.5 modified to do authentication caching in module. It caches the username and IP address only, so until the timeout, further requests with the same IP address and username will be automatically accepted without running the external authenticator. I find it worrisome that those authentication requests will be accepted even if the password is not the same. At least that has the upside of not creating a less secure replica of your password database like mod_authn_socache sometimes does, but I can't say I'm very happy about it. Note also that the cache is not in shared memory, so that each Apache process maintains its own cache, though it would still give a substantial performance boost. I'm inclined to think mod_authn_socache will be a better solution, when available, but I'm not entirely happy with either.
    +
  • + +
  • PAM. Portable Authentication Modules are libraries that have a common interface and can be linked to a program to do authentication out of different databases. Linux, FreeBSD and Solaris support PAM. OpenBSD does not.
    +
    +If you want to authenticate from a PAM module, but the user your httpd runs as does not have the necessary access, then the pwauth external authenticator can be run from mod_auth*_external to do the PAM authentication.
    +
    +The list of PAM modules includes authenticators for Kerberos, radius, unix password or shadow files, SMB, various SQL databases, and just about anything else imaginable.
    +
  • + +
  • mod_auth_pam. If you want to use a PAM module to authenticate, and whatever user Apache runs as has the necessary access to do the check, then you don't need an external authenticator, and you should probably use this module instead of mod_auth*_external and pwauth. There is such a thing as mod_auth_pam2, which is supposed to work with Apache2.
    +
  • + +
  • mod_auth_any. This seems to be similar in function to mod_auth*_external. It seems very sparsely documented at this stage, but it from looking at the source code it seems to pass the login/password to the external authenticator on the command line, which doesn't seem very secure since they'd be trivially visible to anyone doing a 'ps'.
    +
  • + +
  • Apache Module Registry. A good place to find apache modules.
    +
  • + +
  • checkpassword-imap. An IMAP authenticator written in Python for mod_auth_external that caches credentials for faster performance and so that you don't run up against rate limits on the IMAP server.
    +
  • + +
  • BlueQuartz Authentication Script seems to be an external authentication script for PAM written in Perl, similar to pwauth. Seems to have some good security features, but I wasn't able to figure out how to get the source code.
    +
  • +
+ +## How To Pages ## + + \ No newline at end of file diff --git a/ModAuthzUnixGroup.md b/ModAuthzUnixGroup.md new file mode 100644 index 0000000..5ef397e --- /dev/null +++ b/ModAuthzUnixGroup.md @@ -0,0 +1,46 @@ +# Mod\_authz\_unixgroup # + +**Author and Maintainer:** Jan Wolter [email](http://www.unixpapa.com/white.cgi)
+Mailing List: mod_auth_external@googlegroups.com + +

Introduction:

+ +Mod_Authz_Unixgroup is a unix group access control module for Apache 2.1 and later. If you are having users authenticate with real Unix login ID over the net, using something like my mod_authnz_external / pwauth\ combination, and you want to do access control based on unix group membership, then mod_authz_unixgroup is exactly what you need.
+
+There are different versions of mod_authz_unixgroup for different Apache releases:
+
+ +
Apache 2.2 Mod_authz_unixgroup 1.0.x
Apache 2.4 Mod_authz_unixgroup 1.1.x
+ +The configuration commands for these two versions are quite different.
+
+Let's say you are doing unix passwd file authentication with mod_authnz_external and pwauth. Your .htaccess file for a protected directory would probably start with the following directives:
+
AuthType Basic
+AuthName mysite
+AuthBasicProvider external
+AuthExternal pwauth
+
+That would cause mod_auth_basic and mod_authnz_external to do authentication based on the Unix passwd database. Mod_Authz_Unixgroup would come into play if you wanted to further restrict access to specific Unix groups. You might append the following directives:
+
+Apache 2.2: +
AuthzUnixgroup on
+Require group staff admin
+
+Apache 2.4: +
Require unix-group staff admin
+
+This would allow only access to accounts in the 'staff' or 'admin' unix groups. You can alternately specify groups by their gid numbers instead of their names.
+
+Though it makes the most sense to use mod_authz_unixgroup with unix passwd authentication, it can be used with other databases. In that case it would grant access if, (1) the name the user authenticated with exactly matched the name of a real unix account on the server, and (2) that real unix account was in one of the required groups. However, I think this would be a pretty senseless way to use this module. I expect that it will really only be used by users of mod_authnz_external and pwauth or other similar software.
+
+Some authentication modules, like mod_auth_kerb, use usernames that have domains appended to them, like "whomever@krb.ncsu.edu". In such cases, mod_authz_unixgroup will take the part before the @-sign as the username and ignore the rest.
+
+It will come as no surprise that this module works only on Unix systems. It should work on pretty much any vaguely modern Unix.
+
+

Installation and Configuration

+ +To install the module in Apache, you follow pretty much the same procedure as for mod_auth_external.
+
+The configuration commands for mod_authz_unixgroup are entirely different depending on whether you are using Apache 2.2 or Apache 2.4. Choose your poison:
+
  • Apache 2.2 Configuration +
  • Apache 2.4 Configuration \ No newline at end of file diff --git a/ModAuthzUnixGroup22.md b/ModAuthzUnixGroup22.md new file mode 100644 index 0000000..f216d09 --- /dev/null +++ b/ModAuthzUnixGroup22.md @@ -0,0 +1,55 @@ +# Configuring Mod\_authz\_unixgroup on Apache 2.2 # + +**NOTE: Configuration commands for Apache 2.2 and Apache 2.4 are quite different. Please make sure you are reading the correct instructions.** + +To use mod\_authz\_unixgroup in a particular directory, you must insert some commands into the `.htaccess` file for the directory or an appropriate `` block in `httpd.conf`. + +First you need to turn `mod_authz_unixgroup` on for the directory: +``` +AuthzUnixgroup on +``` + +Next you'll need a require directive like +``` +Require group admin +``` +or +``` +Require group students teachers staff +``` +The second version allows a person to have access to the directory if he is in any one of the listed groups. You can identify groups using their group id numbers rather than their names, if you prefer. + +Obviously this only makes sense in a directory where you are doing +authentication. This could be any kind of authentication, but it makes +most sense if you are using it in combination with authentication out of +the unix password file. + +A user is considered to be in a group if either (1) the group is the user's primary group identified by it's gid number in `/etc/passwd`, or (2) the group is listed in `/etc/group` and the user id is listed as a member of that group. + +By default, `mod_authz_unixgroup` is authoritative. If you want to use more +than one group checker, like `mod_authz_unixgroup` together with +`mod_authz_groupfile` or `mod_authz_dbm`, then you'll want to make them non- +authoritative, so that if one fails, the other will be tried. You can +make `mod_authz_unixgroup` non-authoritative by saying: +``` +AuthzUnixgroupAuthoritative off +``` + +## Use with mod\_authz\_owner: ## + +You can use `mod_authz_unixgroup` together with `mod_authz_owner` to do something like: +``` +AuthzUnixgroup on +Require file-group +``` +This would allow access to the page only if the user was a member of whichever unix group owns the file. + +You may have to install `mod_authz_owner` before this will work. Though it is part of the standard Apache distribution, it is not usually installed by default. + +## Failure Handling ## + +Note that when access is denied, either because the file does not exist or because the user is not in the group that owns the file, then the normal response will be for the browser to flush it's cached login and password for the authentication realm, and give the user a new login prompt. The user will have to re-login to access other files in the realm that they do have access to. This may be clumsy in some applications, where it would be much nicer to display a "permission denied" error message and not flush the user's credentials. This can be achieved by telling `mod_authz_unixgroup` to return a 403 error when authentication fails instead of the normal 401 error: +``` +AuthzUnixgroupError 403 +``` +You may want to customize the 403 error page if you do this. \ No newline at end of file diff --git a/ModAuthzUnixGroup24.md b/ModAuthzUnixGroup24.md new file mode 100644 index 0000000..9f1caa6 --- /dev/null +++ b/ModAuthzUnixGroup24.md @@ -0,0 +1,39 @@ +# Configuring Mod\_authz\_unixgroup on Apache 2.4 # + +**NOTE: Configuration commands for Apache 2.2 and Apache 2.4 are quite different. Please make sure you are reading the correct instructions.** + +To use mod\_authz\_unixgroup in a particular directory, you must call it up by including the 'unix-group' or 'unix-file-group' provider names on the 'Require' directive in the `.htaccess` file for the directory or an appropriate `` block in `httpd.conf`. + +``` +Require unix-group admin +``` +or +``` +Require unix-group students teachers staff +``` +The second version allows a person to have access to the directory if he is in any one of the listed groups. You can identify groups using their group id numbers rather than their names, if you prefer. + +Obviously this only makes sense in a directory where you are doing +authentication. This could be any kind of authentication, but it makes +most sense if you are using it in combination with authentication out of +the unix password file. + +A user is considered to be in a group if either (1) the group is the user's primary group identified by it's gid number in `/etc/passwd`, or (2) the group is listed in `/etc/group` and the user id is listed as a member of that group. + +## Use with mod\_authz\_owner: ## + +You can use `mod_authz_unixgroup` together with `mod_authz_owner` by doing: +``` +Require unix-file-group +``` +This would allow access to a file only if the user was a member of whichever unix group owns the file. + +You may have to install `mod_authz_owner` before this will work. Though it is part of the standard Apache distribution, it is not usually installed by default. + +## Failure Handling ## + +Note that when access is denied, either because the file does not exist or because the user is not in the group that owns the file, then the normal response will be for the browser to flush it's cached login and password for the authentication realm, and give the user a new login prompt. The user will have to re-login to access other files in the realm that they do have access to. This may be clumsy in some applications, where it would be much nicer to display a "permission denied" error message and not flush the user's credentials. This can be achieved by using the standard Apache directive: +``` +AuthzSendForbiddenOnFailure On +``` +You may want to customize the 403 error page if you do this. \ No newline at end of file diff --git a/ProjectHome.md b/ProjectHome.md new file mode 100644 index 0000000..85bcc24 --- /dev/null +++ b/ProjectHome.md @@ -0,0 +1,57 @@ +## mod\_authnz\_external and mod\_auth\_external ## + +**Current Maintainer**: [Jan Wolter](http://unixpapa.com) ([E-Mail](http://www.unixpapa.com/white.cgi)) +
    +Previous Maintainer: Tyler Allison (allison@nas.nasa.gov)
    +
    +Original Author: Nathan Neulinger (nneul@umr.edu)
    +
    +
    +Mod_authnz_external and mod_auth_external are flexible tools for building custom basic authentication systems for the Apache HTTP Daemon. "Basic Authentication" is a type of authentication built into the HTTP protocol, in which the browser automatically pops up a login box when the user requests a protected resource, and the login ids and passwords entered are checked by Apache. Mod_auth*_external allows the password checking normally done inside Apache to be done by an separate external program running outside of Apache. This is useful in either of two situations:
    +
    +
    • Rapid, Safe Deployment of Custom Authentication Systems. Standard authentication modules with names like mod_auth_file and mod_auth_ldap exist for most common forms of password database, but occasionally you will need to authenticate out of some database for which no appropriate module exists. Writing custom authentication modules is difficult, requiring a lot of knowledge of the internals of Apache, and bugs in such modules can crash Apache. But with mod_auth*_external the custom code can be in a separate program, possibly even a Perl or PHP script. The interface is very simple, and bugs in the authenticator program can not possibly crash Apache.
    + +
    • Authentication out of Secure Databases. It is often undesirable for a password database to be readable by Apache. If it is readable by Apache, then it is possible that bugs in Apache or in any CGI program run by Apache could allow hackers to access the password database. With mod_auth*_external the external authenticator can be configured as a setuid program, so that it runs as a different user than Apache, and so can access databases that are not accessible to Apache. Since only the small, simple authenticator program has the privileges to access the database, instead of all of Apache, this is vastly easier to make secure.
    + +One of the most common secure databases that people want to authenticate out of is the Unix system password database. The open source pwauth program is a mod_auth*_external compatible authenticator that can do this. It can also authenticate from any PAM authentication source.
    +
    +The obvious disadvantage of using mod_auth*_external is that each authentication requires that the authentication program be loaded and launched. This causes some extra computational overhead. Some hooks have been inserted into mod_auth*_external to make it easy to replace the call to an external authenticators with a call to a hardcoded internal authentication subroutine that you write. This is sort of a half-way measure to just writing your own Apache module from scratch, allowing you to easily borrow some of the logic from mod_auth*_external, but you clearly lose the advantages of external authentication listed above.
    +
    +Mod_auth*_external can also be used to run external programs to make access control checks. Access control means checking if a user is in a group allowed to access a particular resource. It occurs after a user has been authenticated, by mod_auth*_external or by another module.
    +
    +

    Compatibility

    + +

    Apache Versions

    + + + + +
    Apache 1.3 mod_auth_external 2.1.x
    Apache 2.0 mod_auth_external 2.2.x
    Apache 2.2 mod_authnz_external 3.1.x or 3.2.x
    Apache 2.4 mod_authnz_external 3.3.x
    + +The addition of "nz" to the module name in recent releases reflects the fact that the module has been redesigned to fit into the new authentication architecture introduced by Apache, in which top level authentication modules named mod_auth_basic and mod_auth_digest call lower level modules with names like mod_authn_file and mod_authn_dbm.
    +
    +

    Windows, OS2, Netware, etc

    +Version 3.2.0 of mod_authnz_external was redesigned to avoid all unix system calls and work entirely through the Apache API. In theory it should now work on any operating system supported by Apache, including Windows. However, I do not know that anyone has tried this. If you experiment with this, please let us know the results.
    +
    +

    Digest Authentication

    +Mod_authnz_external does not work with digest authentication. It is unlikely that anyone would actually want to do this. In digest authentication, the password is one-way encrypted before it is sent by the browser to the http server. It is only possible to check the validity of that password, if the password database contains either plain text passwords or passwords encrypted by exactly the method defined in the digest authentication standard. If the database used some other one-way encryption method, then there would be no way to tell whether or not the password sent from the browser and the one in the database matched. So digest authentication could not be used with most reasonable authentication databases (storing plain text passwords is not reasonable). Digest authentication out of a Unix password database is impossible, for example.
    +
    +

    Security Considerations

    +Older versions of mod_auth_external would by default pass logins and passwords into the authentication module using environment variables. This is insecure on some versions of Unix where the contents of environment variables are visible on a 'ps -e' command. In more recent versions, the default is to use a pipe to pass sensitive data. This is secure on all versions of Unix, and is recommended in all installations.
    +
    +People using mod_auth*_external with pwauth to authenticate from system password databases should be aware of the innate security risks involved in doing this.
    +
    +

    Wiki Pages

    + + + + +
    • Unix Group Checking with the Mod_authz_unixgroup Module \ No newline at end of file diff --git a/UpgradeTo24.md b/UpgradeTo24.md new file mode 100644 index 0000000..b8304ce --- /dev/null +++ b/UpgradeTo24.md @@ -0,0 +1,77 @@ +If you are upgrading from Apache 2.2 to Apache 2.3 or 2.4 you will need to be aware of several changes in the configuration and behavior of mod\_authnz\_external. + +First, you must use `mod_authnz_external` version 3.3. Previous versions will not work with Apache 2.3 or 2.4. + +### "`Require`" Command Syntax Changes ### + +When using an external group checker, the syntax in Apache 2.2 and before was: + +``` + GroupExternal + Require group ... +``` + +In Apache 2.4, we need to replace the keyword `group` on the `Require` command with the keyword `external-group`, like this: + +``` + GroupExternal + Require external-group ... +``` + +Similarly, if you wanted to check if users were in the group that owns a file, the Apache 2.2 directive was: +``` + Require file-group +``` +while in Apache 2.4 you must say: +``` + Require external-file-group +``` + +### Per Configuration Authentication versus Per URI Authentication ### + +In Apache an HTTP request for a URI may sometimes trigger other "sub-requests" for other URIs. For example, there might be an internal redirect to a different page or a .shtml file might use a server-side include to fetch other files. Mod\_perl programs and the like can generate sub-requests very freely. + +In previous versions of Apache, the authentication checks were redone each time a sub-request accessed a new URI. In version 2.4, authentication modules repeat authentication checks for sub-requests only when it is for a resource with a different authentication configuration. So if you are doing a server-side include of a file that is in a directory where it has exactly the same authentication settings as the original, then the authentication check will only be done once. This is good. + +It might create a possible problem for a rare few users of mod\_auth\_external. One of the environment variables passed to external authenticator programs is "URI". To quote myself: + +> The URI variable is there because various people want it. Mostly it is useful +> not for authentication ("who is this person?") but for access control ("is this +> person permitted to do this?"), and good design usually dictates separating +> those functions. Strictly speaking, an authenticator is not the right place +> to be doing access control. However, mod\_authnz\_external is 50% a +> kludge-builder's tool, so we won't fuss if you want to break the rules. + +Well, if broke the rule and wrote an external authenticator that uses the URI environment variable in a way that would lead it to giving different results for different URIs (not just for, say logging), and if you are doing anything at all that generates sub-requests, then you might be a bit messed up. + +I think the number of people likely to be troubled by this issue is somewhere between "a couple" and "none". If you are among those people, you should either (1) redesign your authentication setup, or (2) edit the mod\_authnz\_external source code before installing it, changing three instances of "AP\_AUTH\_INTERNAL\_PER\_CONF" to "AP\_AUTH\_INTERNAL\_PER\_URI". I considered adding a configuration directive to mod\_authnz\_external that would let you switch the setting in a nicer way, but I suspect it would have to bypass the Apache API to work, and it's just not worth it. + +### Authoritativeness ### + +In Apache 2.4 the moderation between multiple different access control modules is now controlled entirely by mod\_auth\_basic, not by the individual modules. This means that the old mod\_auth\_external directives, + +``` + GroupExternalAuthoritative + AuthzExternalAuthoritative +``` + +no longer exist. + +### Modifying Error Codes for Group Checking ### + +In previous versions of mod\_authnz\_external, there was a directive which could +be used to send a different error code when an access control check failed: + +``` + GroupExternalError 403 +``` + +This also no longer exists. The approximate same effect can be achieved with a new Apache directive: + +``` + AuthzSendForbiddenOnFailure On +``` + +### Use With Mod\_authn\_socache ### + +Apache 2.4 introduces an authentication caching module that can substantially improve the performance of mod\_authnz\_external by reducing the number of times the external authenticator needs to be run. For most users of mod\_authnz\_external, however, it also has some negative security implications as well. Please see the ConfigApache24 page for details. \ No newline at end of file diff --git a/UpgradeToNZ.md b/UpgradeToNZ.md new file mode 100644 index 0000000..55101bf --- /dev/null +++ b/UpgradeToNZ.md @@ -0,0 +1,75 @@ +If you are upgrading from `mod_auth_external` to `mod_authnz_external` then it may help to start by reading the page describing the [Apache Authn/z Architecture](AuthNZ.md). + +After that: +
        +
      1. +Make sure mod_auth_external is no longer being loaded. You cannot load both mod_auth_external and mod_authnz_external without problems. This means ensuring that there is no "LoadModule" or "AddModule" line for mod_auth_external. You could also remove the mod_auth_external.so file from the Apache 'modules' directory.
        +
      2. + +
      3. +Install mod_authnz_external as described on the Installation page.
        +
      4. + +
      5. +The server-level configuration directives in the httpd.conf file can be left unchanged. The "AddExternalAuth", "AddExternalGroup", "SetExternalAuthMethod", and "SetExternalGroupMethod" commands still work work the same way as before. There was, however, a new, more compact alternate syntax was introduced in version 3.2.0 which can be used instead.
        +
      6. + +
      7. +In the per-directory configurations (either in .htaccess files or in a <Directory> block in httpd.conf) need to include a new directive to tell mod_auth_basic to use mod_authnz_external for authentication. For mod_auth_external, the per-directory configurations normally looked something this:
        +
        AuthType Basic
        +AuthName <authname>
        +AuthExternal <keyword>
        +require valid-user
        +
        + +For mod_authnz_external, you need to add the "AuthBasicProvider" directive.
        +
        AuthType Basic
        +AuthName <authname>
        +AuthBasicProvider external
        +AuthExternal <keyword>
        +require valid-user
        +
        + +The directive "AuthType Basic" tells Apache that you want to use the mod_auth_basic module to do "basic authentiation". The directive "AuthBasicProvider external" tells mod_auth_basic to use mod_authnz_external to check the correctness of passwords.
        +
        +Note that the "AuthBasicProvider" directive is only needed if you are using mod_authnz_external for password checking. If you are using it only for group checking, then this is not needed.
        +
      8. + +
      9. +If you were using mod_auth_external in a non-authoritative mode, then your per-directory configuration probably included the directive:
        +
        AuthExternalAuthoritative off
        +
        + +This command will no longer work. Instead you should use one or both of the following commands:
        +
        AuthBasicAuthoritative off
        +GroupExternalAuthoritative off
        +
        + +The "AuthBasicAuthoritative" directive effects password checking, which is done through mod_auth_basic.
        +
        +The "GroupExternalAuthoritative" effects only group checking. That is if you had both "GroupExternal" directive setting up an external program for group checking, and an "AuthGroupFile" directive setting up a group file, then it would control whether the first module to process a "Require group admin" directive was the only one to run, or whether each group checker was given a chance to decide if the user was in that group based on it's group database.
        +
      10. + +
      11. +If you were using multiple Require directives, the behavior may change under Apache 2.2. Suppose you wanted to allow access to user "pete" and members of the group "admins". You might have do:
        +
        Require group admin
        +Require user pete
        +
        +Under Apache 2.0, both of these directives would have been checked by mod_auth_external, and it would have correctly allowed access if either of the two conditions were satisfied. In Apache 2.2, however, only "Require group" and "Require file-group" directives are checked by mod_authnz_external. "Require user" and "Require valid-user" are checked by mod_authz_user, a standard module that comes with Apache. How the two directives interact depends on whether they are authoritative or not. mod_authz_user is Authoritative by default, so to get the old behavior, you will need to do
        +
        GroupUserAuthoritative off
        +
        +
      12. + +
      13. +Note that a new type of functionality is available under Apache 2.2 with mod_authnz_external. Thanks to mod_authz_owner, you can now do:
        +
        Require file-owner
        +
        +or
        +
        Require file-group
        +
        + +The first checks if the name of the authenticated user matches the name of the unix account that owns the file. The second checks if, according to whatever group database has been configured for the current directory, the currently authenticated user is in a group with the same name as the Unix group that owns the file.
        +
        +Normally these are rather strange directives, because normally unix accounts have no relationship to accounts in whatever database is being used for http authentication, but for people using 'pwauth' with mod_authnz_external, these really check if the user has been authenticated as the unix user who owns the file.
        +
      14. +
      \ No newline at end of file -- 2.50.1