# pam_bloom `pam_bloom` is a Linux PAM password module that rejects passwords found in one or more Bloom filters. It can be used to prevent users from choosing passwords found in known password lists such as RockYou, organization-specific password lists, or other administrator-provided dictionaries. The package includes: * `pam_bloom.so` — PAM module * `pam_bloom_create` — utility for creating Bloom filters from wordlists WARNING: This software modifies PAM configuration. There is always risk involved with re-configuring the system's authentication system such as locking legitimate users out. Administrators are responsible for testing their PAM configuration before deployment. ## Requirements On Debian or Ubuntu, install the compiler, PAM development files, and other build tools: ```sh sudo apt update sudo apt install build-essential libpam0g-dev ``` The Makefile also uses `dpkg-architecture` to determine Debian's multiarch PAM module directory. This is normally already available on Debian systems. ## Build Clone or unpack the source and run: ```sh make ``` This builds: ```text pam_bloom.so pam_bloom_create ``` Install them with: ```sh sudo make install ``` On a typical x86-64 Debian system this installs: ```text /usr/bin/pam_bloom_create /usr/lib/x86_64-linux-gnu/security/pam_bloom.so /etc/security/pam_bloom/filters.d/ ``` Finally, run `pam-auth-update` to enable `pam_bloom`: ```sh sudo pam-auth-update ``` ## Create a Bloom filter `pam_bloom_create` creates a Bloom filter from a wordlist: ```sh pam_bloom_create WORDLIST OUTPUT NAME ``` For example: ```sh pam_bloom_create rockyou.txt rockyou.bloom rockyou ``` The default false-positive rate is `0.001`. A different false-positive rate can be selected with `-p`: ```sh pam_bloom_create -p 0.000001 rockyou.txt rockyou.bloom rockyou ``` Install the resulting filter: ```sh sudo cp rockyou.bloom /etc/security/pam_bloom/filters.d/ ``` The PAM module checks every `.bloom` file in this directory. A password matching any installed filter is rejected. ## Configure PAM **Be careful when modifying PAM configuration. An incorrect PAM configuration can prevent authentication or password changes. Keep a root session open while testing changes.** On Debian and Ubuntu, edit: ```text /etc/pam.d/common-password ``` Add `pam_bloom.so` before the `pam_unix.so` password entry. For example: ```text password requisite pam_bloom.so password [success=1 default=ignore] pam_unix.so obscure yescrypt use_authtok password requisite pam_deny.so password required pam_permit.so ``` The important points are that `pam_bloom.so` runs before `pam_unix.so` and that `pam_unix.so` uses `use_authtok`. `pam_bloom` obtains the new password through PAM, checks it against the installed Bloom filters, and rejects it if a match is found. `pam_unix` then uses the same password token. ## Test Change a test user's password normally: ```sh passwd ``` Try selecting a password contained in one of the installed wordlists. `pam_bloom` should reject the password and identify the Bloom filter that matched it. A password that does not match any filter is passed on to the rest of the PAM password stack. ## Custom filter directory The default filter directory is: ```text /etc/security/pam_bloom/filters.d ``` A different directory can be configured with the PAM `dir=` option: ```text password requisite pam_bloom.so dir=/srv/security/bloom ``` The directory and filter files must satisfy `pam_bloom`'s ownership and permission checks. ## Included RockYou filter `pam_bloom` includes a pre-built Bloom filter generated from the RockYou password list: ```text rockyou.txt.bloom ``` The supplied filter was created with a false-positive rate of: ```text 0.001 ``` This filter is installed to `/etc/security/pam_bloom/filters.d/rockyou.txt.bloom` by default. Because this is a Bloom filter, there is a small probability of false positives. With the supplied filter, the configured false-positive probability is 0.001 (approximately 0.1%). In the 1 in 1000 chance that there is a false-positive, the user will simply have to choose another password. The original RockYou plaintext wordlist is not required at runtime. ## Creating your own filters Additional Bloom filters can be created with: ```sh pam_bloom_create WORDLIST OUTPUT NAME ``` For example: ```sh pam_bloom_create passwords.txt passwords.bloom passwords ``` The default false-positive rate is `0.001`, the same value used for the supplied RockYou filter. A different false-positive rate can be selected with `-p`: ```sh pam_bloom_create -p 0.000001 passwords.txt passwords.bloom passwords ``` Install the resulting filter by copying it into the filter directory: ```sh sudo cp passwords.bloom /etc/security/pam_bloom/filters.d/ ``` Multiple `.bloom` files may be installed at the same time. A password matching any installed filter is rejected. ## Adding multiple filters Multiple filters can be installed simply by copying additional `.bloom` files into the filter directory: ```text /etc/security/pam_bloom/filters.d/rockyou.bloom /etc/security/pam_bloom/filters.d/company.bloom /etc/security/pam_bloom/filters.d/banned-passwords.bloom ``` If the candidate password matches **any** filter, it is rejected. ## Removing a filter Remove the corresponding `.bloom` file: ```sh sudo rm /etc/security/pam_bloom/filters.d/rockyou.bloom ``` No rebuild of the PAM module is necessary. ## Uninstall uninstall the binaries: ```sh sudo make uninstall ``` `make uninstall` deliberately does not remove: ```text /etc/security/pam_bloom/filters.d/ ``` or any Bloom filters stored there. Administrator-created filters are preserved. Finally, update PAM configuration to remove `pam_bloom`: ```sh sudo pam-auth-update ``` Alternatively, edit `/etc/pam.d/common-password` to remove `pam_bloom` ## Security Bloom filters can produce false positives. The false-positive probability can be controlled when creating a filter with `pam_bloom_create -p`. The PAM module treats installed Bloom filters as trusted administrative data. Filter directories and files are checked for appropriate ownership and permissions before they are used. Malformed, inaccessible, or otherwise invalid filters cause the password check to fail closed rather than silently bypassing the password policy. ## Murmur3 The mmh3 implementation by Austin Appleby was referenced when implementing this. Appleby's implementation was released under the public domain.