pam_honeycreds(8)

πŸ“¦
version 2.0 Β· 2 versions
, in nixpkgs unstable

🍯 pam_honeycreds(8) β€” the manual page, bestie edition

okay so real talk: this is pam_honeycreds, straight out of the System Manager's Manual, and it's genuinely one of the most iconic little PAM modules out there. we're gonna get into it πŸ’…


✨ NAME ✨

pam_honeycreds β€” it watches for certain passwords being tried at logon, and/or captures the passwords being tried. that's it, that's the whole vibe πŸ“


🌸 SYNOPSIS 🌸

pam_honeycreds.so [user=<username>] [file=<path to creds file>] [syslog] [logcreds] [deny|denyall] [fails] [prompt=<prompt>]

like, that's the shape of it. every piece is optional, mix and match, you got this 🫢


πŸ’– DESCRIPTION πŸ’–

pam_honeycreds.so is a PAM (Pluggable Authentication Modules) module that literally just… watches for certain passwords being used. main character energy, but for auth πŸ‘‘

so here's the deal: you keep a list of passwords, and that list can be stored either in cleartext or as a list of salted sha256 hashes. either one is fine, no judgement.

it can also log passwords that don't match any list β€” but it will NEVER log passwords that are in a list. instead it reports them by file and line. that's the whole safety thing, iykyk πŸ”₯

and it's not just logging! a script can be run when a password is matched. so you can go full automation gremlin.

what's it for, you ask? three whole vibes:

  • "honey credentials" β€” fake passwords made available to catch malicious actors within an environment 🍯
  • lists of common passwords β€” to detect bruteforcers πŸ’€
  • or to detect real passwords turning up where they shouldn't 😭

✨ OPTIONS ✨

these are the PAM options that can be applied to configuration files in /etc/pam.d. slay, let's go through every single one, no skipping:

  • user=[user patterns] β€” comma separated list of fnmatch (shell-style) patterns that identify users for whom this rule applies. to match all users, either leave this out, leave it blank, or explicitly set it to user=*. a '!' character at the start of the pattern allows inversion, so to match all users but root use: user=!root. you CAN mix usernames with and without a leading '!' in a user list, so for instance user=!billing,bill* would match all usernames starting with bill except for billing. cute, right? πŸŽ€
  • !user=[user patterns] β€” comma separated list of fnmatch (shell-style) patterns that identify users for whom this rule DOES NOT APPLY. note that this is different from putting a ! before a user in a user= list β€” using the !user= keyword means all listed users are ignored by this rule. you CANNOT MIX user= and !user= in the same PAM entry, you must use one or the other to specify which users apply or don't. pick a lane bestie πŸ’…
  • host=[host patterns] β€” comma separated list of fnmatch (shell-style) patterns that identify hosts for which this rule applies. to match all hosts, either leave this out, leave it blank, or explicitly set it to host=*. a '!' character at the start of the pattern allows inversion, so to match all hosts but 192.168.1.1 use: host=!192.168.1.1. ⚠️ check whether your software is configured to supply host credentials to PAM as hostnames or IP addresses β€” fr fr, go check.
  • !host=[host patterns] β€” comma separated list of fnmatch (shell-style) patterns that identify hosts for which this rule DOES NOT APPLY. note that this is different from putting a ! before a host in a host= list β€” using the !host= keyword means all listed hosts are ignored by this rule. you CANNOT MIX host= and !host= in the same PAM entry, you must use one or the other to specify which hosts apply or don't. and again, ⚠️ check whether your software is configured to supply host credentials to PAM as hostnames or IP addresses.
  • file=[path to creds file] β€” comma separated list of files in which to check for matching passwords. the file format is discussed below, keep reading πŸ¦‹
  • sfile=[path to file] β€” comma separated list of sorted files in which to check for matching passwords. these will be simple text files, one password per line, and alphabetically sorted so that a fast binary search can be used. speed, she's iconic ⭐
  • syslog β€” record events via syslog messages. you probably want to do this if you intend to "harvest" lists of passwords tried by your attackers, in which case you need to set logcreds too. teamwork!
  • logcreds β€” if this option appears, then passwords will be logged in syslog messages, but only if they do not appear in any of the file lists. if your own passwords appear in the list files (as sha256 salted hashes, of course). they will not be logged. remember, your log files could be compromised too, so you want to avoid revealing your passwords in them. πŸ”’ since pam_honeycreds 2.0, logcreds implies syslog.
  • logfound β€” if this option appears, then passwords will be logged in syslog messages, EVEN IF THEY APPEAR IN FILE LISTS. this is a dangerous option β€” if someone gains access to your log files they could harvest your passwords. it is intended for use with lists of passwords that are not your real passwords, so you can detect password-guessing attempts. since pam_honeycreds 2.0, logfound implies syslog. 😭 please read that warning twice.
  • ignore-blank β€” ignore blank passwords. this option is intended for use with ssh systems that use a public/private key pair to log in. such logins create 'false positive' warnings, but can be ignored using this option. no more spam, blessed πŸ™ˆ
  • script=[path] β€” run script in the event of a match. arguments passed to the script will be "Event Type", "Matching File Entry" "User" "Host", where "Event Type" will be Match or WrongUser, "Matching File Entry" will have the form [file path]:[line in file], "Host" will be the host from which the login has been attempted, and "User" will be the user that is being logged in. yes the arg order in that sentence is a little chaotic, we don't make the rules 🫠
  • deny β€” deny login if a password matches one of the file lists.
  • fails β€” log and run script for all passwords that are not in any list. this can be used to monitor particular account names for password-guessing activity. detective mode πŸ”
  • denyall β€” deny all logins, whether a match is found or not. this is normally used against a user for whom we want to go through the authentication process, but whom we never wish to allow to log in. applications like sshd allow us to specify which users can log in, but users not in this list are not properly processed through pam_honeycreds. thus we configure sshd to allow login by any user, but use the denyall option at the pam_honeycreds level to block certain users from logging in at all. if a denyall rule has a script entry, then the script will be run for any event, even if no match is found within the credentials files. this allows triggering against some users (e.g. root) that should never login via some services (say, ssh). πŸ’€ big gun energy.
🌈 heads up: pam_honeycreds should appear in the pam module list after a module like pam_unix.so, so that the normal configured prompting proceedure is followed. order matters bestie, don't do it dirty.

πŸŽ€ CREDENTIAL FILE CONFIG πŸŽ€

pam_honeycreds uses credentials files that contain one password per line. passwords containing spaces can be enclosed in quotes, or the spaces can be quoted with a \ (backslash) character. passwords can either be stored in plain-text (if they're fake) or as sha256 hashes of the password combined with a salt β€” the salt is simply prefixed to the password, and the resulting string is then hashed. πŸ§‚βœ¨

the format of the password file is:

<password> [salt=<salt>] [user=<user>]

the user option is a comma-separated list of fnmatch patterns that match usernames who are allowed to use this password. this is used to raise an error if a user not in the list uses this password. snitch behaviour, honestly iconic πŸ’…


πŸ¦‹ SORTED FILES πŸ¦‹

the 'sfile' option allows the use of a second type of file: a sorted file of unhashed one-password-per-line entries. this is useful for very large lists of common passwords (these are available online) that can be used to detect password guessing/bruteforcing attempts. big list, fast search, no cap 🌸


πŸ”₯ EXAMPLES πŸ”₯

an example PAM config file in /etc/pam.d might look like the example below. copy-paste responsibly 🫢

#%PAM-1.0
auth    include   system-auth
auth    required  pam_honeycreds.so user=root syslog logcreds denyall file=/etc/mypasswords.conf
auth    required  pam_honeycreds.so user=!root syslog logcreds file=/etc/mypasswords.conf /etc/10-common-passwords.txt script=/usr/local/sbin/warn-admin.sh
auth    required  pam_honeycreds.so user=user* syslog fails file=/etc/honeycreds.conf script=/usr/local/sbin/honeycreds.sh
account   required  pam_nologin.so
account   include   system-auth
password  include   system-auth
session   include   system-auth
session   required  pam_loginuid.so

πŸ‘‘ SEE ALSO πŸ‘‘

pam.conf(5), pam.d(5), pam(8)


okay that's the whole page!! and for the cute sign-off: this edition is from 2015/05/15, part of the System Manager's Manual β€” so like, a little vintage, but she still ate. periodt πŸ’œπŸŽ€

πŸ“¦ where this page comes from