System settings
A few settings describe the server as a whole, and many other features depend on them. The hostname, for example, appears in every SMTP session, in the DNS records the server generates and in its public URL. These settings are grouped on the SystemSettings singleton (found in the WebUI under Settings › Network › Services, Settings › Network › General).
The setup wizard fills in the hostname and the default domain. The other settings have defaults that suit a single server. They are mainly changed in three situations: when the server is published under several names, when it runs behind a load balancer, and when it needs a different memory or connection budget.
Hostname and default domain
Section titled “Hostname and default domain”defaultHostname is the name the server uses for itself, and it appears in many places:
- In the SMTP greeting and in
EHLO - In the
ReceivedandMessage-IDheaders, and in DSNs and reports - As the target of the CNAME and SRV records the server generates
- As the base of the public HTTPS URL, unless
STALWART_PUBLIC_URLsets another one or the JMAP entry ofservices, described below, has a host name of its own
Remote mail servers compare this name with the reverse DNS name of the server’s IP address, so the two should match.
defaultDomainId names the default domain. The server uses it for authentication and for the reports it sends.
Mail exchangers and advertised services
Section titled “Mail exchangers and advertised services”The server publishes two kinds of name. Mail exchangers are the hosts that other mail servers deliver to, and services are the hosts that clients connect to. Each is configured in its own list.
mailExchangers lists the hosts that receive mail for the server’s domains. Each entry has a priority and an optional hostname, and an entry without a hostname uses the default hostname. The list determines several things at once: the MX records and SPF records the server generates for each domain, the TLSA records for port 25, and the names included in ACME certificate orders. A server published under several MX names therefore lists each of them here.
services describes each client protocol: IMAP, POP3, SMTP submission, JMAP, CalDAV, CardDAV, WebDAV and ManageSieve. For each protocol it gives the hostname under which clients reach it and whether a cleartext port is advertised. The entries feed the following:
- The SRV records
- The autoconfiguration responses
- The names in ACME certificate orders
- The TLSA records of ports 993, 995, 465 and 443
- The host names the server accepts for OAuth sign-in
Only the implicit-TLS ports are advertised by default. Turning on the cleartext flag of an entry adds the cleartext port, 143, 110 or 587, to the advertisements. The flag changes only what is advertised, however. Clients can connect to those ports only when a listener exists for them.
providerInfo supplies the provider name, logo, contact address and documentation URLs that autoconfiguration documents include.
Connection limit
Section titled “Connection limit”maxConnections limits the number of concurrent connections of each listener that does not set its own maxConnections. The limit is 8192 unless changed.
The limit applies to every listener separately, which means that the server as a whole can hold the sum of the listener limits. The process file descriptor limit must cover that sum, as described in System requirements.
A connection that arrives while its listener is at the limit is closed immediately and logged as a limit.concurrent-connection event. Changes to the limit take effect after a restart.
Memory budget
Section titled “Memory budget”Messages and blobs in transit are held in memory: messages being received over SMTP, and message contents being sent to IMAP, POP3, JMAP and DAV clients. maxBufferedMemory caps the memory they may use.
When the field is unset, the budget is one quarter of the memory available to the server. That is the container memory limit when one is set, and the physical memory otherwise. The budget cannot be set below 16 MiB. When the available memory cannot be determined, the server uses 1 GiB and logs the warning Unable to detect the available memory, using 1 GiB for maxBufferedMemory.
When the budget is exhausted, new transfers are refused with a temporary error, which clients retry later. Each protocol reports it in its own way:
- SMTP replies
452 4.3.1. - JMAP and DAV answer HTTP
503withRetry-After. - IMAP replies
NO [UNAVAILABLE]. - POP3 replies
-ERR [SYS/TEMP].
Each refusal logs a limit.memory-budget event. Sizing memory explains how to size the budget against the caches.
Trusted proxies
Section titled “Trusted proxies”A load balancer or proxy in front of the server hides the address of the original client, because the server sees only the proxy’s connection. The PROXY protocol solves this: the proxy sends a header with the original client address at the start of each connection. PROXY protocol describes the mechanism.
proxyTrustedNetworks lists the networks of the proxies that send this header, and the server takes the client address from the header only on connections from them. Every connection from these networks must begin with a PROXY header, otherwise it is dropped. A listener can replace the list with its own overrideProxyTrustedNetworks.
The networks listed on SystemSettings are also exempt from auto-ban, which blocks addresses after repeated failures, and from IP blocking. The exemption ensures that the proxy itself is never banned. The per-listener list does not grant it.
The two uses of the list pick up changes at different times. A changed list reaches the exemption at the next settings reload, while the listeners apply it only after a restart.
Worker threads
Section titled “Worker threads”The server runs its network and protocol work on a pool of worker threads, by default one per CPU. The TOKIO_WORKER_THREADS environment variable sets the pool size. It is read at start and described in Environment variables.
The RocksDB and SQLite data stores run their disk operations on a separate pool, sized by the store’s poolWorkers setting. By default that pool has one thread per CPU, and at least four. Data store tuning describes when to change it.
Secrets in API responses
Section titled “Secrets in API responses”The management API hides passwords, keys and other secret values in its responses. includeSecrets turns this protection off. Enable it only for the duration of an export of the configuration that must carry the secrets, for example a migration to another server, and disable it again afterwards.
Running as an unprivileged user
Section titled “Running as an unprivileged user”Binding ports below 1024 requires privileges. On Linux, the installation script and the container image grant the binary the CAP_NET_BIND_SERVICE capability, so the server runs as an unprivileged user from the start.
Where this is not possible, for example on FreeBSD, the server can be started as root with the RUN_AS_USER environment variable set, and optionally RUN_AS_GROUP. The server then binds its listeners first and switches to that user and group afterwards. The FreeBSD service script written by the installer uses this method.