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

136 lines
7.0 KiB
Markdown

# 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.