Using traefik without tls passthrough?

Your question

So according to the official docs for a setup with traefik as its reverse proxy, you’d need to let traefik pass through the “tls connection” to for example smtps. Is it possible to terminate every TLS for clients at the proxy? This would simplify the setup significantly in my opinion :eyes:

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

Yes, this is supported and actually the recommended simple approach. Here’s the summary:

For HTTP/HTTPS (WebUI, JMAP, IMAP over HTTP): Traefik can terminate TLS and forward plain HTTP to Stalwart’s HTTP listener on port 8080. This is the “recommended for simplicity” pattern and requires no TLS configuration on the Stalwart side.

For raw mail protocols (SMTP, SMTPS, IMAP, IMAPS, POP3S): These are TCP protocols, so a proxy like Traefik terminating TLS on their behalf and forwarding plaintext creates a protocol mismatch - what Stalwart receives on its SMTPS/IMAPS listener would be unencrypted bytes that it still expects to perform a TLS handshake on (or STARTTLS). The practical way to handle this is to configure Stalwart’s mail listeners with useTls: false on listeners that are meant to receive already-decrypted traffic from the proxy, effectively making them plaintext listeners. Traefik handles the client-facing TLS; Stalwart gets plain TCP from Traefik.

Important caveat - Proxy Protocol: Regardless of the TLS setup, you should enable the Proxy Protocol so Stalwart sees real client IPs rather than Traefik’s address. Without it, SPF/DMARC checks, rate limiting, and auto-banning all operate against the proxy’s IP instead of the actual client. On the Stalwart side, set the listener to accept Proxy Protocol and mark Traefik’s IP as a trusted network.

The useTls field is per-listener on the NetworkListener object (settable in the WebUI under Settings > Network > Listeners). Set it to false on any listener that will receive already-decrypted connections from Traefik.

Relevant docs:

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

For raw mail protocols (SMTP, SMTPS, IMAP, IMAPS, POP3S): These are TCP protocols, so a proxy like Traefik terminating TLS on their behalf and forwarding plaintext creates a protocol mismatch - what Stalwart receives on its SMTPS/IMAPS listener would be unencrypted bytes that it still expects to perform a TLS handshake on (or STARTTLS). The practical way to handle this is to configure Stalwart’s mail listeners with useTls: false on listeners that are meant to receive already-decrypted traffic from the proxy, effectively making them plaintext listeners. Traefik handles the client-facing TLS; Stalwart gets plain TCP from Traefik.

Wait, so I can simply just pass each “decrypted-protocol” to its respective “unencrypted port”?

For example with SMTPS: After TLS terminated at the reverse proxy, I can simply pass the decrypted content to the SMTP port of the stalwart docker container?

Yes for the HTTP/WebUI/JMAP side: terminate TLS at Traefik and forward plain HTTP to Stalwart’s HTTP listener on 8080. That’s the simpler, supported pattern, no passthrough needed (stalw.art/docs/server/reverse-proxy).

For the raw mail listeners your restated understanding is basically right, but the target listener has to actually be plaintext (tls_implicit: false) for that port. You can’t forward decrypted bytes into the implicit-TLS SMTPS(465)/IMAPS(993) listeners, since those still expect a TLS handshake; point Traefik at a plaintext SMTP/IMAP (or STARTTLS) port instead. Two caveats: terminating mail TLS at the proxy loses the real client IP unless you also enable Proxy Protocol (proxyTrustedNetworks), which SPF/DMARC/rate-limiting rely on; and that’s exactly why the docs default to passthrough.