mirror of
https://github.com/stalwartlabs/proxy.git
synced 2026-10-30 16:15:29 +00:00
168 lines
4.9 KiB
TOML
168 lines
4.9 KiB
TOML
# Migration proxy sample configuration.
|
|
#
|
|
# This is a starting template. Edit the destinations, mappings, TLS
|
|
# certificates and admin token to match your deployment, then start the
|
|
# service. The proxy refuses to boot until every referenced destination,
|
|
# certificate and credential path is valid (see SPEC section 8.4).
|
|
#
|
|
# Run with: proxy /etc/proxy/config.toml
|
|
# Or set: PROXY_CONFIG=/etc/proxy/config.toml
|
|
|
|
[server]
|
|
# Worker threads (0 = one per CPU).
|
|
threads = 0
|
|
# Hostname advertised in protocol greetings; defaults to the local IP.
|
|
hostname = "proxy.example.com"
|
|
shutdown_grace = "30s"
|
|
log_level = "info"
|
|
|
|
# TLS certificates used to TERMINATE inbound implicit-TLS and STARTTLS.
|
|
# Multiple certificates are selected by SNI. Mark one as the default.
|
|
[tls.certificate.default]
|
|
cert = "/etc/proxy/tls/fullchain.pem"
|
|
key = "/etc/proxy/tls/privkey.pem"
|
|
default = true
|
|
|
|
[tls.protocols]
|
|
min_version = "1.2"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Routing: which destination handles an identifier when it is missing or
|
|
# unmapped, and (optionally) where raw SMTP/25 and LMTP/24 traffic is sent.
|
|
# ---------------------------------------------------------------------------
|
|
[routing]
|
|
default_destination = "legacy"
|
|
# smtp_passthrough_destination = "stalwart"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Mappings: identifier -> destination id. Source is "file", "redis" or "sql".
|
|
# ---------------------------------------------------------------------------
|
|
[mapping]
|
|
source = "file"
|
|
normalize = "lowercase"
|
|
negative_ttl = "30s"
|
|
positive_ttl = "10m"
|
|
|
|
[mapping.file]
|
|
path = "/etc/proxy/mappings.tsv"
|
|
|
|
# [mapping.redis]
|
|
# url = "redis://10.0.0.5:6379"
|
|
# key_prefix = "route:"
|
|
|
|
# [mapping.sql]
|
|
# url = "postgres://user:pass@10.0.0.6/proxy"
|
|
# query = "SELECT destination FROM routes WHERE identifier = $1"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Destinations. The default destination must support every listener protocol
|
|
# declared below. Each destination lists the per-protocol backend port and the
|
|
# TLS mode the proxy must use on the OUTBOUND leg.
|
|
# ---------------------------------------------------------------------------
|
|
[destination.legacy]
|
|
host = "10.0.1.10"
|
|
tls_server_name = "mail.legacy.example.com"
|
|
proxy_protocol = true
|
|
|
|
[destination.legacy.protocol.imap]
|
|
port = 993
|
|
tls = "implicit"
|
|
[destination.legacy.protocol.pop3]
|
|
port = 995
|
|
tls = "implicit"
|
|
[destination.legacy.protocol.submission]
|
|
port = 587
|
|
tls = "starttls"
|
|
[destination.legacy.protocol.managesieve]
|
|
port = 4190
|
|
tls = "starttls"
|
|
[destination.legacy.protocol.http]
|
|
port = 443
|
|
tls = "implicit"
|
|
|
|
[destination.stalwart]
|
|
host = "10.0.1.20"
|
|
tls_server_name = "mail.new.example.com"
|
|
proxy_protocol = true
|
|
|
|
[destination.stalwart.protocol.imap]
|
|
port = 993
|
|
tls = "implicit"
|
|
[destination.stalwart.protocol.pop3]
|
|
port = 995
|
|
tls = "implicit"
|
|
[destination.stalwart.protocol.submission]
|
|
port = 587
|
|
tls = "starttls"
|
|
[destination.stalwart.protocol.managesieve]
|
|
port = 4190
|
|
tls = "starttls"
|
|
[destination.stalwart.protocol.http]
|
|
port = 443
|
|
tls = "implicit"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Listeners: one entry per protocol + TLS mode + bind set.
|
|
# tls = "implicit" | "starttls" | "plain".
|
|
# ---------------------------------------------------------------------------
|
|
[listener.imap]
|
|
protocol = "imap"
|
|
bind = ["0.0.0.0:993", "[::]:993"]
|
|
tls = "implicit"
|
|
|
|
[listener.imap-starttls]
|
|
protocol = "imap"
|
|
bind = ["0.0.0.0:143", "[::]:143"]
|
|
tls = "starttls"
|
|
|
|
[listener.pop3]
|
|
protocol = "pop3"
|
|
bind = ["0.0.0.0:995", "[::]:995"]
|
|
tls = "implicit"
|
|
|
|
[listener.submission]
|
|
protocol = "submission"
|
|
bind = ["0.0.0.0:587", "[::]:587"]
|
|
tls = "starttls"
|
|
|
|
[listener.submissions]
|
|
protocol = "submission"
|
|
bind = ["0.0.0.0:465", "[::]:465"]
|
|
tls = "implicit"
|
|
|
|
[listener.managesieve]
|
|
protocol = "managesieve"
|
|
bind = ["0.0.0.0:4190", "[::]:4190"]
|
|
tls = "starttls"
|
|
|
|
[listener.https]
|
|
protocol = "http"
|
|
bind = ["0.0.0.0:443", "[::]:443"]
|
|
tls = "implicit"
|
|
forwarded = "off"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# HTTP routing rules. First match wins. A rule pins a destination by path, or
|
|
# extracts an account identifier and routes it through the mapping store.
|
|
# ---------------------------------------------------------------------------
|
|
[[http.route]]
|
|
match = "/.well-known/**"
|
|
destination = "legacy"
|
|
|
|
[[http.route]]
|
|
match = "/**"
|
|
extract = { from = "authorization" }
|
|
fallback = "default"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Admin listener: the cache-integrity boundary. Bind to loopback or a dedicated
|
|
# management network only. TLS is mandatory; plaintext admin is rejected.
|
|
# ---------------------------------------------------------------------------
|
|
[admin]
|
|
bind = "127.0.0.1:9443"
|
|
tls = "implicit"
|
|
bearer_token_file = "/etc/proxy/admin.token"
|
|
min_token_len = 32
|
|
lockout_threshold = 5
|
|
lockout_duration = "5m"
|