Files
bongo/docs/authentication.md
T
2026-07-18 17:52:04 +02:00

7.0 KiB

Authentication security

Bongo stores new account passwords with Argon2id. Existing PBKDF2 and legacy password records remain usable and are upgraded to Argon2id after a successful login. There is no default administrator password.

Time-based two-factor authentication is optional per account. A user enables it under Settings → Two-factor authentication by confirming the account password, scanning the QR code with an authenticator application and entering the current six-digit code. When two-factor authentication is disabled, the web login does not display or request a second field. When it is enabled, the second field appears only after the account password has been accepted.

Enabling TOTP creates ten one-time recovery codes. They are displayed only once and can be copied together with Copy all recovery codes. Copying puts the codes in the operating system clipboard; clear that clipboard after the codes have been placed in a password manager or another protected location. Bongo stores only Argon2id hashes of recovery codes. Each code is invalidated atomically when used.

The TOTP secret is encrypted with AES-256-GCM in userdb.sqlite. Its dedicated master key is auth.key in Bongo's DBF directory. The database and key are restricted to the Bongo service account and must be backed up together. The QR image is generated in memory and is not written to disk or included in logs.

App passwords use a random lookup identifier and an independently generated secret. Only the Argon2id hash is retained. They can be limited to IMAP, POP3, SMTP, ManageSieve, CalDAV or CardDAV, and optionally to an expiry time and a source IPv4 or IPv6 network. Requiring app passwords remains a separate, explicit per-user policy; enabling TOTP does not silently change mail-client authentication.

SMTP submission, IMAP, POP3 and ManageSieve use one GNU GSASL server layer. Its direct GSASL_VALIDATE_SIMPLE callback applies the same account lookup, service-specific app-password policy, source-network restriction and authentication audit trail to every protocol. Bongo does not configure a GSASL password-property fallback or a separate SASL user database. Password-bearing mechanisms are advertised only after TLS and the advertised list is generated from mechanisms that are both available in GSASL and enabled by Bongo. Clients cannot select an available mechanism that Bongo did not advertise. Bongo 0.7 enables PLAIN and LOGIN for TLS-protected compatibility clients; adding a mechanism requires implementing its credential callback, stored key material and policy first, not merely enabling another mechanism.

LDAP master authentication

LDAP can be enabled as the primary source for normal account passwords. It is independent of Bongo app passwords: service-scoped bap-... credentials are always verified locally first, while only a normal master password is sent to LDAP. Local Bongo users still need to be provisioned because their mailboxes, settings and security policy remain in Bongo.

When two-factor authentication is disabled, the LDAP master password is also accepted by IMAP, POP3, SMTP, ManageSieve, CalDAV and CardDAV. With TOTP enabled this remains possible until the user explicitly enables the separate "require app passwords" policy. That policy is unavailable while TOTP is off, so enabling LDAP alone cannot accidentally lock older mail clients out.

After a successful LDAP bind Bongo stores only a new Argon2id hash of that password, never the LDAP password itself. The hash may be used while LDAP is actually unavailable for a configurable period (48 hours by default). A definitive LDAP rejection never falls back to the cache. If LDAP rejects the same password that is currently cached, that cached credential is invalidated. Configuration and TLS errors also fail closed rather than enabling offline login.

Set the following properties in /etc/bongo/config.d/authentication:

AuthLdapEnabled = true
AuthLdapUri = ldaps://ldap.example.net
AuthLdapBaseDn = ou=people,dc=example,dc=net
AuthLdapUserAttribute = uid
AuthLdapTimeoutSeconds = 10
AuthLdapOfflineCacheHours = 48

For ldap:// URIs, StartTLS is required by default. Set AuthLdapStartTls = false only for a protected compatibility environment. Server certificates are verified. A private CA can be selected with AuthLdapCaFile. Directory search may be anonymous; otherwise set AuthLdapBindDn and put only the bind password in the file named by AuthLdapBindPasswordFile. That file must be a regular, non-symlink file with no group or world permissions. Setting AuthLdapOfflineCacheHours = 0 disables and removes the offline cache after the next successful LDAP login.

If an Active Directory, Azure-hosted directory or another LDAP service remains offline longer than planned, a local administrator can inspect and atomically extend every existing user cache:

bongo-admin ldap-cache status
bongo-admin ldap-cache extend-all
bongo-admin ldap-cache extend-all 72

The default extension is another 48 hours. Each invocation is limited to 744 hours, requires local root privileges and writes an authentication notice to the system log. Valid caches are extended from their current expiry; expired caches are deliberately reactivated from the current time. The operation does not create cache entries, change passwords or affect any app password. Users who have never completed a successful LDAP login remain unavailable until the directory returns.

Reverse proxies and Fail2ban

Bongo emits one structured log entry for every rejected Web, POP3, IMAP, SMTP or ManageSieve authentication attempt. The installed bongo-auth Fail2ban filter recognizes those entries. Its jail template is deliberately disabled until the administrator has reviewed ignoreip, especially on installations that provide a compatibility listener for trusted legacy devices.

On systemd systems, edit /etc/fail2ban/jail.d/bongo-auth.conf, review the trusted networks, set enabled = true, and reload Fail2ban. On an OpenRC system using a traditional syslog file, put these overrides in /etc/fail2ban/jail.d/bongo-auth.local:

[bongo-auth]
enabled = true
backend = auto
logpath = /var/log/messages

The Web service may listen on any unprivileged local port and can run behind Apache, nginx, or a chain of both. trusted_proxies in /etc/bongo/config.d/web accepts individual IPv4/IPv6 addresses and CIDR networks. Forwarded client addresses are ignored unless the direct peer is trusted. Proxy chains are processed from the trusted end so a client-supplied prefix cannot bypass the login limiter or cause Fail2ban to block an unrelated address.

The forwarded address header defaults to X-Forwarded-For. Load balancers using a single-address header can be configured, for example:

"trusted_proxies": ["127.0.0.0/8", "10.20.0.0/16"],
"client_ip_header": "X-Real-IP"

Other common values are CF-Connecting-IP and True-Client-IP. Configure the proxy to replace or correctly append that header and never trust proxy ranges that can contain ordinary clients.