Skip to content

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.yaml carries the same numbers. From 2.4.2:

  • A key left out keeps its default, in yarilo.yaml and in each entry of a list (oauth2, quota_warnings, mail_servers).
  • An explicit 0 turns 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 explicit 0 stops the process at startup with the key's name.
  • A negative value is refused, except where a page says otherwise (lmtp_user_concurrency_limit: -1 is unlimited).

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.yaml, not inside general:, because more than one section reads it.

Four things read it:

  • the domain part of a Message-ID synthesised at delivery (see LMTP),
  • the LMTP LHLO banner,
  • the Received: header added at delivery,
  • submission's banner and Message-ID domain — unless protocol.submission.hostname is set, which overrides submission alone.
yaml
hostname: mail.example.com

Set 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.tag=X 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.yaml, so a Helm deployment cannot reach it. A hand-written yarilo.yaml 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_VAR} 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_server_cert_file.

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

ssl_min_protocol ​

Default
TLS1.2
Type
string
Values
TLS1.2 TLS1.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.

yaml
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_VAR} substitution is supported in all path values — no secrets in config files.


general.haproxy ​

HAProxy PROXY protocol v1/v2. When haproxy_protocol: true is set on a service, the real client IP is extracted from the PROXY header. Connections from addresses outside haproxy_trusted_networks 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.

yaml
general:
  haproxy:
    timeout: 3
    haproxy_trusted_networks:
      - 127.0.0.1/32
      - 10.0.0.0/8
      - 172.16.0.0/12

Enable per-listener with haproxy_protocol: true 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_nets 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:

yaml
general:
  xclient:
    trusted_nets:
      - 10.0.0.0/8

Enable per-listener with xclient_protocol: true in the service config. See Services configuration. A listener with xclient_protocol: true while trusted_nets 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.0.0.1/32, 10.0.0.0/8 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.

yaml
general:
  limits:
    mail_max_userip_connections: 10

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

yaml
general:
  startup_dial_retries: 3

login.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_timeout (see Authentication) replaces it.

yaml
login:
  login_proxy_timeout: 30

login 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_max_attempts. 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.