Security: Encryption and Hashing
TOTP secret encryption
Authenticator app (TOTP) secrets are encrypted at rest using AES-256-GCM. The encryption key is configured in admin/config.php:
$ENCRYPTION_KEY = '';
If left empty, a random 256-bit key is auto-generated and stored outside the web root at /var/www/secrets/.encryption-key (Docker volume mount required — see docker-compose.yml). Existing installs that have the key at admin/.encryption-key will auto-migrate it to the secure location on next load. The /var/www/secrets/ directory should have chmod 700 permissions and all key files within it chmod 600.
The contact form captcha secret is also stored in this directory at /var/www/secrets/.captcha-key, auto-generated on first use.
/var/www/secrets/ securely.
Recovery code hashing
Recovery codes are hashed with bcrypt (cost 10). Older accounts may have SHA-256 hashes — the login system handles both transparently.
Server-level security
server-init.sh configures:
- fail2ban — 3 failed SSH attempts = 1-hour ban, with persistent bans across reboots
- UFW firewall — only SSH, HTTP, and HTTPS are open
- SSH hardening — root login disabled, max 3 auth tries
- Unattended upgrades — security and stable updates applied automatically