diff --git a/apps/stalwart/ISSUE-2026-07-13-smtp-imap-external-access.md b/apps/stalwart/ISSUE-2026-07-13-smtp-imap-external-access.md index 09b3ddb..1774f3f 100644 --- a/apps/stalwart/ISSUE-2026-07-13-smtp-imap-external-access.md +++ b/apps/stalwart/ISSUE-2026-07-13-smtp-imap-external-access.md @@ -176,7 +176,37 @@ Provision actual Hetzner Cloud LoadBalancers via hcloud-cloud-controller-manager ## Fix Applied -**NONE YET** - Awaiting approval on approach. +**UPDATE 2026-07-13 20:10 UTC**: Investigation revealed that k3s ServiceLB was **working correctly all along** via hostPort bindings! + +**Commit**: ae3f16498736ed6ba0733e6656d82cb47d8eb5a6 +**Applied**: 2026-07-13 20:07 UTC (ArgoCD sync) + +The confusion was caused by misunderstanding the `EXTERNAL-IP` field showing `10.42.1.1` (flannel pod network IP): +- k3s ServiceLB does NOT route traffic through that VIP +- Instead, it creates svclb DaemonSet pods with hostPort bindings on each node's public IP +- External traffic to `178.105.17.239:25` → hostPort binding → service ClusterIP → pod + +**Verification**: +```bash +# All ports responding correctly: +$ nc -zv 178.105.17.239 25 587 465 143 993 +Connection to 178.105.17.239 25 port [tcp/smtp] succeeded! +Connection to 178.105.17.239 587 port [tcp/submission] succeeded! +Connection to 178.105.17.239 465 port [tcp/submissions] succeeded! +Connection to 178.105.17.239 143 port [tcp/imap] succeeded! +Connection to 178.105.17.239 993 port [tcp/imaps] succeeded! + +# Stalwart responding correctly: +$ echo "QUIT" | nc 178.105.17.239 25 +220 mail.basicstack.de Stalwart ESMTP at your service +221 2.0.0 Bye. +``` + +**Change Made**: Added `externalTrafficPolicy: Local` to both LoadBalancer services in git. + +**Why This Matters**: With `externalTrafficPolicy: Local`, traffic only routes to nodes where the pod is actually running. With the default `Cluster` policy, ArgoCD would create svclb pods on all nodes even when Stalwart is only on one node, causing potential routing issues. + +**Root Cause of Confusion**: ArgoCD continuously reverted manual `kubectl patch` changes because `externalTrafficPolicy: Local` was not in the git manifest. Now it's committed to git, so ArgoCD won't revert it. ## Verification Plan