Stalwart + Bulwark mail server deployment with OIDC, TLS cert, vault secrets. Beam design service. Pingora config cleanup. SeaweedFS replication fix. Kratos values tweak. Migration scripts for mbox/messages /calendars from La Suite to Stalwart.
149 lines
4.8 KiB
YAML
149 lines
4.8 KiB
YAML
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: stalwart-config
|
|
namespace: stalwart
|
|
data:
|
|
# DOMAIN_SUFFIX is replaced by sed at deploy time.
|
|
# Secrets (%{env:VAR}%) are injected via environment variables in the Deployment.
|
|
#
|
|
# Only LOCAL keys belong in this file (store.*, storage.*, server.*, directory.*,
|
|
# tracer.*, cluster.*, certificate.*, authentication.fallback-admin.*).
|
|
# Everything else (OIDC, DKIM, spam, etc.) is configured via the Stalwart
|
|
# web admin UI and stored in the database.
|
|
config.toml: |
|
|
# Force http.url to be read from this file (not the database).
|
|
config.local-keys.0000 = "store.*"
|
|
config.local-keys.0001 = "directory.*"
|
|
config.local-keys.0002 = "tracer.*"
|
|
config.local-keys.0003 = "server.*"
|
|
config.local-keys.0004 = "!server.blocked-ip.*"
|
|
config.local-keys.0005 = "!server.allowed-ip.*"
|
|
config.local-keys.0006 = "authentication.fallback-admin.*"
|
|
config.local-keys.0007 = "cluster.*"
|
|
config.local-keys.0008 = "config.local-keys.*"
|
|
config.local-keys.0009 = "storage.*"
|
|
config.local-keys.0010 = "certificate.*"
|
|
config.local-keys.0011 = "http.url"
|
|
config.local-keys.0012 = "http.use-x-forwarded"
|
|
|
|
# Expression-quoted public URL (inner single quotes required).
|
|
http.url = "'https://mail.DOMAIN_SUFFIX'"
|
|
http.use-x-forwarded = true
|
|
|
|
[server]
|
|
hostname = "mail.DOMAIN_SUFFIX"
|
|
max-connections = 1024
|
|
|
|
[server.listener."smtp"]
|
|
bind = ["0.0.0.0:25"]
|
|
protocol = "smtp"
|
|
|
|
[server.listener."submission"]
|
|
bind = ["0.0.0.0:587"]
|
|
protocol = "smtp"
|
|
tls.implicit = false
|
|
|
|
[server.listener."smtps"]
|
|
bind = ["0.0.0.0:465"]
|
|
protocol = "smtp"
|
|
tls.implicit = true
|
|
|
|
[server.listener."imap"]
|
|
bind = ["0.0.0.0:143"]
|
|
protocol = "imap"
|
|
tls.implicit = false
|
|
|
|
[server.listener."imaps"]
|
|
bind = ["0.0.0.0:993"]
|
|
protocol = "imap"
|
|
tls.implicit = true
|
|
|
|
[server.listener."jmap"]
|
|
bind = ["0.0.0.0:8080"]
|
|
protocol = "http"
|
|
|
|
[server.listener."managesieve"]
|
|
bind = ["0.0.0.0:4190"]
|
|
protocol = "managesieve"
|
|
|
|
[certificate."default"]
|
|
cert = "%{file:/etc/stalwart-tls/tls.crt}%"
|
|
private-key = "%{file:/etc/stalwart-tls/tls.key}%"
|
|
|
|
# ── Storage backends ─────────────────────────────────────────────────────
|
|
|
|
[store."postgresql"]
|
|
type = "postgresql"
|
|
host = "postgres-rw.data.svc.cluster.local"
|
|
port = 5432
|
|
database = "stalwart_db"
|
|
user = "stalwart"
|
|
password = "%{env:DB_PASSWORD}%"
|
|
timeout = "15s"
|
|
|
|
[store."postgresql".pool]
|
|
max-connections = 20
|
|
|
|
[store."s3"]
|
|
type = "s3"
|
|
bucket = "sunbeam-stalwart"
|
|
endpoint = "http://seaweedfs-filer.storage.svc.cluster.local:8333"
|
|
region = "us-east-1"
|
|
access-key = "%{env:S3_ACCESS_KEY}%"
|
|
secret-key = "%{env:S3_SECRET_KEY}%"
|
|
key-prefix = "v1/"
|
|
timeout = "60s"
|
|
|
|
[store."opensearch"]
|
|
type = "elasticsearch"
|
|
url = "http://opensearch.data.svc.cluster.local:9200"
|
|
index = "stalwart"
|
|
|
|
[store."redis"]
|
|
type = "redis"
|
|
urls = ["redis://valkey.data.svc.cluster.local:6379/7"]
|
|
|
|
# ── Storage role assignments ─────────────────────────────────────────────
|
|
|
|
[storage]
|
|
data = "postgresql"
|
|
blob = "postgresql"
|
|
fts = "opensearch"
|
|
lookup = "redis"
|
|
directory = "hydra"
|
|
|
|
# ── Directories (user stores) ──────────────────────────────────────────
|
|
|
|
# Internal directory for locally-managed accounts (admin, service accounts).
|
|
[directory."internal"]
|
|
type = "internal"
|
|
store = "postgresql"
|
|
|
|
# OIDC directory — validates Hydra-issued bearer tokens via userinfo.
|
|
# When a JMAP client presents a Bearer token, Stalwart calls Hydra's
|
|
# userinfo endpoint to map it to a user identity.
|
|
[directory."hydra"]
|
|
type = "oidc"
|
|
timeout = "15s"
|
|
endpoint.url = "http://hydra-public.ory.svc.cluster.local:4444/userinfo"
|
|
endpoint.method = "userinfo"
|
|
fields.email = "email"
|
|
fields.username = "email"
|
|
fields.full-name = "name"
|
|
|
|
# ── Authentication ───────────────────────────────────────────────────────
|
|
|
|
[authentication.fallback-admin]
|
|
user = "admin"
|
|
secret = "%{env:ADMIN_PASSWORD}%"
|
|
|
|
# ── Logging ──────────────────────────────────────────────────────────────
|
|
|
|
[tracer."stdout"]
|
|
type = "stdout"
|
|
level = "info"
|
|
ansi = false
|
|
enable = true
|
|
|