From bff59128289eece8a7d5e3df9c98b84b8784f3c6 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Tue, 26 Aug 2014 09:17:41 +0100 Subject: [PATCH] add a README --- README.md | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..24cfcb0 --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ + +=============== +A/I Auth Server +=============== + +An authentication server with an LDAP backend and some advanced +features: + +* OTP support +* application-specific passwords +* rate limiting and brute force protection +* user partitioning across multiple backends + +The authentication server can be queried using an HTTP API. The +software includes a PAM module (pam_authclient) that can be used +to integrate system services. + + +# Configuration + +The authentication server data model is based on the concept of a +*user account*. The server knows how to retrieve user accounts stored +in LDAP, but it has to be told the specific details of how to find +them and how to map the information there to what it needs. + +The server's behavior can be configured with a Python file defining +some module-level variables: + +* `LDAP_URI` is the LDAP connection string. +* `LDAP_BIND_DN` and `LDAP_BIND_PW` specify the bind credentials: they + should allow the server to read authentication-related attributes on + the user objects, and to search the user subtree. +* `LDAP_SERVICE_MAP` is a `{service: query}` dictionary that defines + how to query the LDAP database for user accounts, for each service. + + +## Query definition + +LDAP queries are meant to return a single user account object from the +database using a *search* operation. They are represented as +dictionaries, with the following fields: + +* `dn`: specifies the full DN of the object +* `base`: specifies a base DN for the search +* `filter`: specifies a filter to apply to the search + +The `dn` and `base` attributes are mutually exclusive. In fact, +queries can be of two types: + +* If you can know the specific DN of a user account object given its + username, specify the `dn` field. This will run a SCOPE_BASE query + for that specific DN. In this case, `filter` is optional. +* Specify `base` and `filter` together to identify a single object. + This will result in a SCOPE_SUBTREE search starting at `base`. In + this case the `filter` attribute is required. + +On every incoming request, the query fields are subject to string +substitution, using the standard Python syntax of the `%` operator, +with the following client-provided variables available: + +* `user`: username +* `service`: authentication service +* `shard`: user shard + +So, for example, a mail service could use the following query: + + { + 'base': 'ou=Accounts,dc=example,dc=com', + 'filter': 'mail=%(user)s' + } + +or alternatively, if the database structure is simple enough: + + { + 'dn': 'mail=%(user)s,ou=Accounts,dc=example,dc=com' + } + + + +# Usage + +## Client authentication + +Requests to the authentication server can themselves be authenticated, +and it may be a good idea to do so in a production environment. + +Authserv supports TLS-based authentication using a private CA: in +order to perform authentication queries, a client must present an X509 +certificate signed by a specific Certification Authority. + +This feature is enabled by passing the `--ca`, `--ssl-cert` and +`--ssl-key` options to the server. + +The PAM client has options to specify a client certificate. + + +## HTTP API + +The authentication server accepts HTTP POST requests at the +`/api/1/auth` URL. Requests should contain the following parameters +(with a Content-Type of `application/x-www-form-urlencoded`): + +* `service`: the service to authenticate for +* `username`: username +* `password`: password +* `otp_token`: a 6-digit TOTP token (optional) +* `source_ip`: the remote address of the client connection (optional) +* `shard`: server shard (optional) + +The response is a simple string, one of: + +* `OK`: the authentication request was successful +* `ERR_AUTHENTICATION_FAILURE`: the authentication request failed +* `ERR_OTP_REQUIRED`: an OTP token is required in order to + authenticate, but it was not provided in the request. + +If the client application receives an `ERR_OTP_REQUIRED` result, it +should prompt the user for an OTP token and retry the authentication +request (including the same username and password) with the +`otp_token` field set. The PAM module, for example, can ask the user +for the OTP token interactively, while web applications could display +an interstitial form. + + +## PAM + +A PAM module, `pam_authclient`, is provided to integrate system +services with the authentication server. It provides only the +*account* (a no-op) and *auth* operations. + +Example usage: + + auth required pam_authclient.so auth_server=127.0.0.1:1616 + +The module knows about the following options: + +* `auth_server=`*HOST:PORT* specifies the authentication server to talk + to. It's possible to specify more than one server, separated by + commas, in which case they will be tried in sequence in case of + failure. +* `ssl_crt=`*FILE* load the X509 client certificate from FILE (in PEM format). +* `ssl_key=`*FILE* load the X509 certificate key from FILE. +* `ca=`*FILE* should point at the X509 CA certificate, used to verify + the authenticity of the server connection: the server certificate + must be signed by this CA. +* `shard=`*ID* sets the *shard* parameter, which may be used by the + authentication server to limit authentication to a subset of users. + + +## NGINX mail_http_auth support + +The authentication server can optionally offer an HTTP API compatible +with NGINX's `mail_http_auth` module. This is particularly useful in +combination with user partitioning, as the server can use the `shard` +attribute of the user to direct NGINX to the right backend. + +The module understands the following configuration variables: + +* `NGINX_AUTH_SERVICE` (default: `mail`) is the service that will be + used for authentication by this module. +* `NGINX_AUTH_PORT_MAP` is a dictionary that maps protocol names to + port numbers for the backend connection. The default is + `{"pop3": 110, "imap": 143}`. + -- GitLab