The Auto Blacklist Module: pam_abl

Synopsis

Module name:
    pam_abl
Author:
    Andy Armstrong <andy@hexten.net>
Maintainer:
    Andy Armstrong <andy@hexten.net>
Management groups provided:
    auth
Cryptographically sensitive:
    No.
Security rating:
Clean code base:
    Clean.
System dependencies:
    Requires Berkeley DB (tested with 4.3.21 and 4.2.50).
    Requires a configuration file (by convention /etc/security/pam_abl.conf)
Network aware:
    No.

Overview of module

Provides auto blacklisting of hosts and users responsible for repeated failed
authentication attempts. Generally configured so that blacklisted users still
see normal login prompts but are guaranteed to fail to authenticate.

This functionality is only available to services which call PAM as root. If
pam_abl is called for uid != 0 it will silently succeed.

Auth component

Recognised arguments:

         Name         Arguments                    Description
    debug           None          Enable debug output to syslog.
    expose_account  None          Ignored
    no_warn         None          Disable warnings which are otherwise output
                                  to syslog.
    try_first_pass  None          Ignored
    use_first_pass  None          Ignored
    use_mapped_pass None          Ignored
                                  The configuration file contains additional
                                  arguments. In order for the pam_abl command
                    Path to the   line tool to work correctly most of the
    config          configuration configuration should be placed in the config
                    file.         file rather than being provided by arguments.
                                  The format of the config file is described
                                  below.
                    Path to host  Path to the Berkeley DB which is used to log
    host_db         database      the host responsible for failed
                    file.         authentication attempts.
                    Purge time    Defines how long failed hosts are retained in
    host_purge      for the host  the host database. Defaults to 1 day.
                    database.
                    Rule for host The rule (see below for format) which defines
    host_rule       blacklisting. the conditions under which a failed hosts
                                  will be blackisted.
                    Path to user  Path to the Berkeley DB which is used to log
    user_db         database      the user responsible for failed
                    file.         authentication attempts.
                    Purge time    Defines how long failed users are retained in
    user_purge      for the user  the user database. Defaults to 1 day.
                    database.
                    Rule for user The rule (see below for format) which defines
    user_rule       blacklisting. the conditions under which a failed users
                                  will be blackisted.

Description:

    Brute force password discovery attacks involve repeated attempts to
    authenticate against a service using a dictionary of common passwords.
    While it is desirable to enforce strong passwords for users this is not
    always possible and in cases where a weak password has been used brute
    force attacks can be effective.

    The pam_abl module monitors failed authentication attempts and
    automatically blacklists those hosts (and accounts) that are responsible
    for large numbers of failed attempts. Once a host is blacklisted it is
    guaranteed to fail authentication even if the correct credentials are
    provided.

    Blacklisting is triggered when the number of failed authentication attempts
    in a particular period of time exceeds a predefined limit. Hosts which stop
    attempting to authenticate will, after a period of time, be un-blacklisted.

    This functionality is only available to services which call PAM as root. If
    pam_abl is called for uid != 0 it will silently succeed. If this was not
    the case it would be possible for a malicious local user to poison the
    pam_abl data by, for example, discovering the names of the hosts from which
    root typically logs in and then constructing PAM authentication code to
    lock out root login attempts from those hosts.

Usage:

    Typically pam_abl.so is added to the auth stack as a required module just
    before whatever modules actually peform authentication. Here's a fragment
    of the PAM config for a production server that is running pam_abl:

    auth required   pam_env.so
    auth required   pam_abl.so config=/etc/security/pam_abl.conf
    auth sufficient pam_unix.so try_first_pass nullok
    auth required   pam_deny.so

    Although all of accepted arguments can be supplied here they will usually
    be placed in a separate config file and linked to using the config argument
    as in the above example. The pam_abl command line tool reads the external
    config file (/etc/security/pam_abl.conf in this case) to find the databases
    so in order for it work correctly an external config should be used.

Config file syntax:

    The config file can contain any arguments that would be supplied via PAM
    config. In the config file arguments are placed on separate lines. Comments
    may be included after a '#' and line continuation is possible by placing a
    back slash at the end of the line to be continued. Here is a sample /etc/
    security/pam_abl.conf:

    # /etc/security/pam_abl.conf
    debug
    host_db=/var/lib/abl/hosts.db
    host_purge=2d
    host_rule=*:10/1h,30/1d
    user_db=/var/lib/abl/users.db
    user_purge=2d
    user_rule=!root:10/1h,30/1d

    All of the standard PAM arguments (debug, expose_account, no_warn,
    try_first_pass, use_first_pass, use_mapped_pass) are accepted; with the
    exception of debug and no_warn these are ignored.

    The arguments that are specific to pam_abl are as follows:

                Specify the name of the databases that will be used to log
                failed authentication attempts. The host database is used to
    host_db,    log the hostname responsible for a failed auth and the user
    user_db     database is used to log the requested username. If host_db or
                user_db is omitted the corresponding auto blacklisting will be
                disabled.
                Specify the length of time for which failed attempts should be
                kept in the databases. For rules to work correctly this must be
                at least as long as the longest period specified in a
                corresponding rule. You may wish to retain information about
                failed attempts for longer than this so that the pam_abl
                command line tool can report information over a longer period
    host_purge, of time. The format for this item is a number with an optional
    user_purge  multiplier suffix, 's', 'm', 'h' or 'd' which correspond with
                seconds, minutes, hours and days. To specify seven days for
                example one would use '7d'. Note that in normal operation
                pam_abl will only purge the logged data for a particular host
                or user if it happens to be updating it, i.e. if that host or
                user makes another failed attempt. To purge all old entries the
                pam_abl command line tool should be used.
                These are the rules which determine the circumstances under
                which accounts are auto-blacklisted. The host_rule is used to
    host_rule,  block access to hosts that are responsible for excessive
    user_rule   authentication failures and the user_rule is used to disable
                accounts for which there have been excessive authentication
                failures. The rule syntax is described in full below.

Rule syntax:

    Each rule consists of a number of space separated 'user clauses'. A user
    clause specifies the user (and service) names to match and a set of
    triggers. A simple example would be

    *:10/1h

    which means 'block any user (*) if they are responsible for ten or more
    failed authentication attempts in the last hour'. In place of the '*' which
    matches any user a list of usernames can be supplied like this

    root|dba|admin:10/1h

    which means 'block the users root, dba and admin if they are responsible
    for ten or more failed authentication attempts in the last hour'. You can
    also specify a service name to match against like this

    root/sshd|dba/*:3/1d

    which means 'block the users root for service 'sshd' and dba for any
    service if they are responsible for three or more failed authentication
    attempts in the last day'. Finally you can specify multiple triggers like
    this

    root:10/1h,20/1d

    which means 'block the user root if they are responsible for ten or more
    failed attempts in the last hour or twenty or more failed attempts in the
    last day.

    Multiple rules can be provided separated by spaces like this

    *:10/1h root:5/1h,10/1d

    in which case all rules that match a particular user and service will be
    checked. The user or host will be blocked if any of the rule triggers
    matches. The sense of the user matching can be inverted by placing a '!' in
    front of the rule so that

    !root:20/1d

    is a rule which would match for all users apart from root. It is important
    to treat root as a special case in the user_rule otherwise excessive
    attempts to authenticate as root will result in the root account being
    locked out even for valid holders of root credentials.

    Here is the full syntax for rules:

    word        ::= /[^\s\|\/\*]+/
    name        ::= word | '*'
    username    ::= name
    servicename ::= name
    userservice ::= username
                |   username '/' servicename
    namelist    ::= userservice
                |   userservice '|' namelist
    userspec    ::= namelist
                |   '!' namelist
    multiplier  ::= 's' | 'm' | 'h' | 'd'
    number      ::= /\d+/
    period      ::= number
                |   number multiplier
    trigger     ::= number '/' period
    triglist    ::= trigger
                |   trigger ',' triglist
    userclause  ::= userspec ':' triglist
    rule        ::= userclause
                |   userclause /\s+/ rule

Examples/suggested usage:

    Sample PAM config fragment:

    auth required   pam_env.so
    auth required   pam_abl.so config=/etc/security/pam_abl.conf
    auth sufficient pam_unix.so try_first_pass nullok
    auth required   pam_deny.so

    Sample /etc/security/pam_abl.conf:

    # /etc/security/pam_abl.conf
    debug
    host_db=/var/lib/abl/hosts.db
    host_purge=2d
    host_rule=*:10/1h,30/1d
    user_db=/var/lib/abl/users.db
    user_purge=2d
    user_rule=!root:10/1h,30/1d
