136 lines
7.0 KiB
Markdown
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.
|