General configuration
The general section defines infrastructure settings shared across all listeners. Individual services can override ssl per-listener with their own ssl: block.
How numeric settings read
The defaults in these pages are the binary's, and the Helm chart's values. carries the same numbers. From 2.4.2:
- A key left out keeps its default, in
yarilo.and in each entry of a list (yaml oauth2,quota_,warnings mail_).servers - An explicit
0turns a setting off (a cache, a delay, a limit, an interval that may stop), as each table says. Where off makes no sense (a timeout that must bound, a pool size, a poll interval), an explicit0stops the process at startup with the key's name. - A negative value is refused, except where a page says otherwise (
lmtp_is unlimited).user_ concurrency_ limit: -1
hostname (top level)
What this installation calls itself.
hostname
- Default
- the host's own name (
os.Hostname()) - Type
- string
The name yarilo answers with and stamps into mail. It sits at the top level of yarilo., not inside general:, because more than one section reads it.
Four things read it:
- the domain part of a
Message-IDsynthesised at delivery (see LMTP), - the LMTP
LHLObanner, - the
Received:header added at delivery, - submission's banner and
Message-IDdomain — unlessprotocol.is set, which overrides submission alone.submission. hostname
hostname: mail.example.comSet it on a cluster. The default is each process's own hostname, which is right for a single node and wrong for several: every pod would answer with a different name, and the identifiers they write would disagree about where the mail came from. The correct value is the name your mail is seen under, and it is a decision that cannot be defaulted into.
Leaving it explicitly empty is possible and produces a placeholder name in those headers. That is deliberate: a missing setting should be visible in the mail rather than silently plausible.
chart_version (top level, chart-managed)
Written by the Helm chart, not by an operator. It carries the chart's own version so a process can say whether the ConfigMap beside it was rendered by the same release it was built from — helm upgrade --set image. pairs a binary with whatever chart is on disk, and a chart older than the binary silently fails to render keys the binary reads.
chart_version
- Default
- none
- Type
- string
Advanced: this should not normally be changed.
Written by the Helm chart, never by an operator. A process compares it with the chart version it was built from and warns at start when they differ.
Do not set it. There is no such value in values., so a Helm deployment cannot reach it. A hand-written yarilo. that carries a different value gets a warning at start and nothing else: refusing to start over a version string would be a worse failure than the one being reported.
general.ssl
Shared TLS certificate. Used by every TLS-enabled listener that does not define its own ssl: override.
ssl_server_cert_file
- Default
- none
- Type
- string
- Also accepted as
tls_cert- See also
ssl_server_key_file
Path to the PEM certificate, or the full chain. ${ENV_ is expanded at startup.
ssl_server_key_file
- Default
- none
- Type
- string
- Also accepted as
tls_key- See also
ssl_server_cert_file
Path to the PEM private key that matches ssl_.
ssl_server_alt_cert_file
- Default
- none
- Type
- string
- Also accepted as
tls_alt_cert- See also
ssl_server_alt_key_file
Optional second certificate, for example ECDSA beside RSA, chosen per client by SNI.
ssl_server_alt_key_file
- Default
- none
- Type
- string
- Also accepted as
tls_alt_key- See also
ssl_server_alt_cert_file
Private key for ssl_.
ssl_min_protocol
- Default
TLS1.2- Type
- string
- Values
TLS1.2TLS1.3- Also accepted as
tls_min_version
Minimum TLS version a client may negotiate.
ssl_prefer_server_ciphers
- Default
false- Type
- boolean
- Also accepted as
prefer_server_ciphers
Use the server's cipher-suite preference order instead of the client's.
TLS ALPN matching (the reference parity). TLS listeners advertise ALPN protocol identifiers per IANA RFC 7301: imap for IMAP/IMAPS, pop3 for POP3/POP3S, smtp for Submission/Submissions. Clients that send ALPN must match — mismatching connections are refused. Clients without ALPN are accepted (backward-compatibility). LMTP is internal-only and does not enforce ALPN.
general:
ssl:
ssl_server_cert_file: /etc/ssl/yarilo/cert.pem
ssl_server_key_file: /etc/ssl/yarilo/key.pem
ssl_server_alt_cert_file: /etc/ssl/yarilo/ecdsa.pem # optional
ssl_server_alt_key_file: /etc/ssl/yarilo/ecdsa.key
ssl_min_protocol: TLS1.2
ssl_prefer_server_ciphers: false${ENV_ substitution is supported in all path values — no secrets in config files.
general.haproxy
HAProxy PROXY protocol v1/v2. When haproxy_ is set on a service, the real client IP is extracted from the PROXY header. Connections from addresses outside haproxy_ ignore the header (the TCP source IP is used instead).
timeout
- Default
3- Type
- integer, seconds
Time to wait for the PROXY header. The connection is closed when it does not arrive in time.
haproxy_trusted_networks
- Default
127.0.0.1/32, 10.0.0.0/8- Type
- list
- Also accepted as
trusted_nets
CIDRs whose PROXY headers are accepted. A connection from anywhere else keeps its TCP source address.
general:
haproxy:
timeout: 3
haproxy_trusted_networks:
- 127.0.0.1/32
- 10.0.0.0/8
- 172.16.0.0/12Enable per-listener with haproxy_ in the service config. See Services configuration.
general.xclient
SMTP XCLIENT command for trusted relay infrastructure. A relay behind which yarilo sits can pass the real client IP, hostname, and helo string via XCLIENT before the mail transaction begins.
Only a peer inside trusted_ is believed. The same list decides who is told about XCLIENT at all: submission-login and lmtp-login list XCLIENT in their EHLO/LHLO reply only to such a peer. A peer outside it that sends XCLIENT anyway gets the same reply as a trusted one, and its address is not applied, so the reply does not reveal who is trusted.
Supported XCLIENT attributes: ADDR, PORT, HELO, LOGIN, PROTO, SESSION, TTL, FORWARD, plus the reference extensions DESTADDR (alias: DESTIP) and DESTPORT for the destination the client originally connected to (load-balancer awareness).
trusted_nets
- Default
[]- Type
- list
- Changed 2.4.4
- The default was
127.0.0.1/32, 10.0.0.0/8; it now trusts nobody.
CIDRs of the proxies and relays allowed to issue XCLIENT. Empty trusts none.
Name your proxies' networks:
general:
xclient:
trusted_nets:
- 10.0.0.0/8Enable per-listener with xclient_ in the service config. See Services configuration. A listener with xclient_ while trusted_ is empty logs a warning at start: no forwarded address will be believed. The same applies to the JMAP backend's trust mode 2, which reads this list.
Upgrading
An installation that relied on the earlier default 127. without writing it out now trusts nobody. A chart-rendered config writes the list explicitly, so it keeps what its values say.
general.limits
mail_max_userip_connections
- Default
10- Type
- integer
Simultaneous connections per user and IP pair, counted across all IMAP and POP3 listeners. 0 is unlimited. A userdb field of the same name overrides it per user.
general:
limits:
mail_max_userip_connections: 10general.startup_dial_retries
startup_dial_retries
- Default
3- Type
- integer
Attempts to reach an external dependency, such as warden or Redis, at startup before the process gives up.
general:
startup_dial_retries: 3login.login_proxy_timeout
Read by the IMAP, POP3, Submission and ManageSieve login proxies.
login_proxy_timeout
- Default
30- Type
- integer, seconds
- Helm
login.login_proxy_timeout
Time a login proxy may spend reaching the user's backend and bringing the session up there: the connect, re-routes to another backend, the preamble and the backend's greeting, with every retry inside the same window. Past it the client gets a temporary failure (NO [UNAVAILABLE] on IMAP) and may log in again. A user's proxy_ (see Authentication) replaces it.
login:
login_proxy_timeout: 30login transient retries
Read by the IMAP, POP3, Submission and ManageSieve login proxies.
transient_retries
- Default
3- Type
- integer
- Helm
login.transientRetries- See also
transient_relogin_cap
Extra attempts a transient failure gets (auth temporary failure, auth dial, backend session setup) before the client is told the service is unavailable. 0 fails on the first error.
transient_relogin_cap
- Default
3- Type
- integer
- Helm
login.transientReloginCap- See also
transient_retries
Once the retries are spent, the proxy answers NO [UNAVAILABLE] and keeps the connection open for another login. This many such answers close the connection. Independent of auth_. 0 closes on the first.
Startup waits
A process that starts while a dependency rolls waits for it instead of exiting into a restart loop. The wait applies at startup only; requests do not use it.
auth_startup_wait
- Default
30- Type
- integer, seconds
- Helm
components.auth.startup_wait
Time to wait for yarilo-auth at startup. 0 does not wait.
locks_client_startup_wait
- Default
30- Type
- integer, seconds
- Helm
components.locks.client.startup_wait
Time to wait for yarilo-locks at startup. 0 does not wait.
auth_client pool
Userdb lookups from session processes reuse pooled connections to yarilo-auth.
auth_client_pool_size
- Default
4- Type
- integer
- Helm
components.auth.client.pool_size
Connections to yarilo-auth kept open for userdb lookups. 0 dials per lookup. On shutdown each connection still serving a lookup is waited for up to a second.
auth_client_pool_idle_timeout
- Default
300- Type
- integer, seconds
- Helm
components.auth.client.pool_idle_timeout
Time an unused pooled connection is kept. 0 never closes one for idleness.
internal_tls session resumption
session_cache_size
- Default
64- Type
- integer
- Helm
internalTLS.sessionCacheSize
TLS sessions an internal client keeps for resumption. 0 turns resumption off.
session_cache_ttl
- Default
0- Type
- integer, seconds
- Helm
internalTLS.sessionCacheTtl
Time a cached session may be resumed. 0 keeps it until the cache evicts it.
A negative value is refused at startup for every key above.