Password hashing — SHA512 → Bcrypt/Blowfish

BOA's default Linux account password hashing is SHA512 (via PAM pam_unix). You can upgrade to Bcrypt/Blowfish via pam_unix2 for stronger hashing, at the cost of a delicate PAM transition. For most BOA hosts SHA512 is sufficient; this page is for operators who specifically need Bcrypt for compliance or hardening.

State of the art

  • MD5 ($1$) — broken since the early 2000s. BOA stopped defaulting to MD5 after BOA-2.0.8.
  • SHA512 ($6$) — current Linux default. Strong, slow, unbroken.
  • Bcrypt/Blowfish ($2a$) — constant-work-factor hashing designed to resist GPU-accelerated brute force.

BOA's 90-day password-rotation policy means even on a SHA512 host all passwords cycle on a fast schedule, limiting the value of any offline cracking attempt.

Why upgrade

Bcrypt resists GPU-accelerated brute force better than SHA512. For a host that handles especially sensitive data the upgrade is a reasonable hardening step. For a typical BOA hosting host, SHA512 + 90-day rotation + key-based SSH is enough — do not migrate just because you can.

Critical pre-requisite — working root SSH key access

Before touching PAM, verify you have working ed25519 SSH keys for direct root access (no sudo), and confirm a key-based root login actually succeeds. If you misconfigure the PAM transition, password-based authentication can stop working for every account on the host, including root — and SSH key auth (which bypasses PAM) becomes your only fallback. Do not proceed until a key-based root login is proven to work.

The migration

# Install pam_unix2 (the Bcrypt-capable PAM module)
apt-get install libpam-unix2 -y

# Clone the unix PAM config to unix2 and modify
cp -af /usr/share/pam-configs/unix /usr/share/pam-configs/unix2
sed -i "s/^Name: Unix/Name: Unix2/g"  /usr/share/pam-configs/unix2
sed -i "s/pam_unix.so/pam_unix2.so/g" /usr/share/pam-configs/unix2
sed -i "s/nullok_secure//g"           /usr/share/pam-configs/unix2
sed -i "s/obscure//g"                 /usr/share/pam-configs/unix2
sed -i "s/sha512//g"                  /usr/share/pam-configs/unix2
sed -i "s/rounds//g"                  /usr/share/pam-configs/unix2

# Pure-FTPd PAM config switched to use unix2 too
sed -i "s/pam_unix.so/pam_unix2.so/g" /etc/pam.d/pure-ftpd

# pam_unix2 defaults: switch from des/sha512 to blowfish, 8 rounds
sed -i "s/^CRYPT=des.*/CRYPT=blowfish/g" /etc/security/pam_unix2.default
sed -i "s/^BLOWFISH_CRYPT_FILES=.*/BLOWFISH_CRYPT_FILES=8/g" /etc/security/pam_unix2.default

# Run the PAM auth-update dialog
pam-auth-update

The pam-auth-update dialog will show:

[*] Unix2 authentication
[*] Unix authentication

Both must stay enabled. If you disable Unix authentication ("clean up after migration"), every existing SHA512-hashed password stops working — including root — because pam_unix2 cannot validate $6$ SHA512 hashes. Use Arrow + Space to toggle, Tab to focus <Ok>, Enter to confirm.

Testing

Update root's password and a test tenant's password with passwd, then check /etc/shadow:

Hash prefix Algorithm
$1$... MD5 (legacy, insecure)
$6$... SHA512 (BOA default)
$2a$08$... Bcrypt/Blowfish, 8 work-factor (target)

A line that now begins with $2a$08$ proves the migration worked for that account. Then test the practical effect:

  1. Log out of root.
  2. SSH back as root using the password (not the key). Should work.
  3. Log in as oN.ftp via SSH and via FTPS. Should work.

If any test fails, do not log out of your existing session — diagnose and fix while you still have access.

Why both PAM modules must stay enabled

pam_unix validates $6$ SHA512 hashes. pam_unix2 (BOA-added) validates $2a$ Bcrypt hashes. Existing accounts have $6$ hashes until they next change passwords; new accounts and post-migration password changes get $2a$ hashes.

If only pam_unix2 is enabled, new Bcrypt-hashed passwords work but all existing SHA512-hashed passwords fail. You cannot migrate all accounts to Bcrypt at once because BOA's 90-day rotation has not cycled yet for all accounts, and some accounts may carry manually-set passwords predating the transition. So both must stay enabled until every account has cycled its password at least once (90 days minimum).

BOA's automatic rotation interaction

BOA rotates account passwords every 90 days via manage_ltd_users.sh (see lshell + manage_ltd_users). After the PAM migration, each rotation lands a $2a$ Bcrypt hash; within 90 days every active account is on Bcrypt. manage_ltd_users.sh has no per-account "force reset" sub-command — to land a Bcrypt hash on one account sooner, set its password directly with the standard tool:

# Re-hash one account immediately (lands a $2a$ Bcrypt hash post-migration)
passwd oN.ftp

The next scheduled manage_ltd_users.sh rotation will likewise emit a $2a$ hash for every account it touches.

Failure mode

The historical horror story: an operator disabled Unix authentication after enabling Unix2, then could not log in as anyone and had to boot from a rescue CD. If your only access path is password-based and you broke PAM, you would need the vendor's web console, out-of-band recovery (rescue CD, KVM-over-IP), or a parallel SSH key that bypasses PAM. This is why the pre-requisite above is non-negotiable. The migration is straightforward, but the failure mode is brutal.

Related