PAM_ABL(8)

PAM_ABL(8) β€” the Linux-PAM manual, but make it make sense πŸ’…

okay bestie, sit down, hydrate, and let me tell you about pam_abl β€” section 8 of the Linux-PAM manual. this is the PAM Auto Blacklist Module and it is genuinely one of the most iconic little security gremlins in the PAM lineup. let's go πŸ¦‹


✨ NAME ✨

pam_abl β€” the PAM Auto Blacklist Module. that's it, that's the name, no cap. πŸ‘‘


✨ SYNOPSIS ✨

okay so what does it do? it gives you auto blacklisting of hosts and users that are out here being responsible for repeated failed authentication attempts. like, if you keep knocking and the door keeps not opening, this module writes your name in a little notebook. πŸ““

it's generally configured so that blacklisted users still see normal login prompts β€” yes, the prompt still shows up, it's giving totally normal β€” but they are guaranteed to fail to authenticate. the door is right there. the door is locked. you cannot see the difference. that's the point. 😭

big important energy: this functionality is only available to services which call PAM as root. and if pam_abl is called for uid != 0, it will silently succeed. silently. no drama, no error, just vibes and a quiet exit. πŸ’€

✨ DESCRIPTION ✨

let's talk about why this module exists, because the villain of this story is brute force password discovery attacks. 🦹

these are the ones where someone just repeatedly attempts to authenticate against a service using a whole dictionary of common passwords. like a girl with a keyring trying every single key. obviously we want everyone to have strong passwords, but β€” and I say this with love β€” this is not always possible, and in cases where a weak password has been used, brute force attacks can genuinely be effective. sobs. 😭

enter pam_abl, our main character. it monitors failed authentication attempts and automatically blacklists those hosts (and accounts, yes, accounts too) that are responsible for large numbers of failed attempts. and once a host is blacklisted? it is guaranteed to fail authentication β€” even if the correct credentials are provided. correct password, wrong vibe, no entry. periodt. πŸ’…

how the blacklisting actually triggers πŸŽ€

blacklisting is triggered when the number of failed authentication attempts in a particular period of time exceeds a predefined limit. so it's not "one oopsie and you're out" β€” it's a threshold over a window, iykyk. πŸͺŸ

and the good news for anyone who just fumbled their password a bunch and then gave up: hosts which stop attempting to authenticate will, after a period of time, be un-blacklisted. the notebook gets erased. redemption arc. 🌈

commands on state changes ✨

you can also specify commands that will be run when a host or user switches state β€” either from being blocked to clear, or from clear to blocked. so you can hook in your own scripts and be dramatic about it. πŸ“£

see below (bestie, there's more page coming) or check out the pam_abl.conf(5) manpage for the details. πŸ“–

the uid != 0 thing, but explained 🧚

okay so we said it earlier but here's the why, and it's kind of a slay of a security design decision:

if pam_abl is called for uid != 0, it will silently succeed. and if that were not the case β€” if it did anything else β€” it would be possible for a malicious local user to poison the pam_abl data. how? for example: by 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 very hosts. 😱

so yeah. silent success for non-root callers is not laziness, it's armor. πŸ›‘οΈβœ¨

✨ OPTIONS ✨

okay bestie, here's the whole menu of arguments you can hand to this module πŸ’… every single one, no skips:

  • debug β€” takes None. Turns on debug output to syslog. πŸ›
  • expose_account β€” takes None. Ignored. literally just vibes, it does nothing.
  • no_warn β€” takes None. Kills the warnings that would otherwise get dumped into syslog. shhh 🀫
  • try_first_pass β€” takes None. Ignored.
  • use_first_pass β€” takes None. Ignored.
  • use_mapped_pass β€” takes None. Ignored.
  • config β€” takes a Path to the configuration file. This file holds additional arguments. So here's the tea: for the pam_abl command line tool to actually work correctly, most of your configuration should live in the config file instead of being passed in as arguments. The format of the config file is described below. πŸ‘‘
  • limits β€” takes the Minimum and maximum number of attempts to keep. Its value should use this syntax: "<minimum>-<maximum>". If you don't block machines that do too many attempts, the db can easily become bloated 😭 so to prevent that, we introduced this setting. As soon as there are a <maximum> number of attempts for a user/host, the number of stored attempts gets reduced to <minimum>. A <maximum> of 0 means no limits. Make sure that <minimum> is larger then any rule specified. We recommend a value of "1000-1200". fr fr, take the recommendation.
  • db_home β€” takes a Directory for db locking and logging files. Path to a directory where Berkeley DB can place it's locking and logging files. Make sure this dir is writable. πŸ”₯
  • host_db β€” takes a Path to host database file. Path to the Berkeley DB which is used to log the host responsible for failed authentication attempts.
  • host_purge β€” takes the Purge time for the host database. Defines how long failed hosts are retained in the host database. Defaults to 1 day. ⏳
  • host_rule β€” takes the Rule for host blacklisting. The rule (see below for format) which defines the conditions under which a failed hosts will be blackisted.
  • host_whitelist β€” takes Host that do not need to be tracked. ;-seperated list of host that do not need to be tracked. You can specify single IP addresses here or use subnets. For example 1.1.1.1 or 1.1.1.1/24 🌈
  • host_blk_cmd β€” takes a Host block command. > Deprecated for security reasons. Please use host_block_cmd πŸ’€
  • host_clr_cmd β€” takes a Host clear command. > Deprecated for security reasons. Please use host_clear_cmd πŸ’€
  • host_block_cmd β€” takes a Host block command. Command that should be run when a host is checked, and is currently blocked. Within the command, the strings %u, %h and %s are substituted with username, host and service. Not all need to be used. Please see the manpage of pam_abl.conf for the correct syntax. 🫢
  • host_clear_cmd β€” takes a Host clear command. Command that should be run when a host is checked, and is currently clear. Within the command, the strings %u, %h and %s are substituted with username, host and service. Not all need to be used. Please see the manpage of pam_abl.conf for the correct syntax. 🫢
  • user_db β€” takes a Path to user database file. Path to the Berkeley DB which is used to log the user responsible for failed authentication attempts.
  • user_purge β€” takes the Purge time for the user database. Defines how long failed users are retained in the user database. Defaults to 1 day. ⏳
  • user_rule β€” takes the Rule for user blacklisting. The rule (see below for format) which defines the conditions under which a failed users will be blackisted.
  • user_whitelist β€” takes Users that do not need to be tracked. ;-seperated list of users whose attempts do not need to be recorded. This does not prevent the machine they are using from being blocked. πŸ‘€ important distinction bestie!
  • user_blk_cmd β€” takes a User block command. > Deprecated for security reasons. Please use user_block_cmd πŸ’€
  • user_clr_cmd β€” takes a User clear command. > Deprecated for security reasons. Please use clear_block_cmd πŸ’€
  • user_blk_cmd β€” takes a User block command. Command that should be run when a user is checked, and is currently blocked. Within the command, the strings %u, %h and %s are substituted with username, host and service. Not all need to be used.
  • user_clr_cmd β€” takes a User block command. Command that should be run when a user is checked, and is currently clear. Within the command, the strings %u, %h and %s are substituted with username, host and service. Not all need to be used.

πŸš€ USAGE πŸš€

so typically pam_abl.so gets added to the auth stack as a required module, right before whatever modules actually perform authentication. here's a fragment of the PAM config for a production server that's running pam_abl:

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

and yeah, although all of accepted arguments can be supplied right there in the PAM config, they will usually be placed in a separate config file and linked to using the config argument β€” exactly like the example above does. 🌸

here's the thing though: 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. no cap. periodt. πŸ’–

🌸 EXAMPLES 🌸

okay bestie, here's what it actually looks like when you drop it into your PAM config πŸ’… this is the classic four-line stack, in order, no skips:

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

see how pam_abl.so sits in there with its config= pointing at /etc/security/pam_abl.conf? that's the whole assignment, periodt. πŸŽ€


πŸ¦‹ SEE ALSO πŸ¦‹

  • pam_abl.conf(5) β€” the config file, aka where you tell it what to do πŸ‘‘
  • pam_abl(1) β€” the command-line bestie that goes with it ✨

πŸ’– AUTHORS πŸ’–

the icons who built this, no cap:

  • Lode Mertens <pam-abl@danta.be>
  • Andy Armstrong <andy@hexten.net>
  • Chris Tasma <pam-abl@deksai.com>

πŸ‘‘ AUTHOR πŸ‘‘

  • Chris Tasma
    • Author.

and that's the whole page, bestie, we ate and left no crumbs πŸ“ this was PAM_ABL(8) from GNU, dated 03/31/2024 β€” go forth and block those brute-forcers, mwah πŸ’œβœ¨πŸ¦‹

πŸ“¦ where this page comes from