diff --git a/apps/stalwart/stalwart-allow-cluster-ips-job.yaml b/apps/stalwart/stalwart-allow-cluster-ips-job.yaml new file mode 100644 index 0000000..be791c3 --- /dev/null +++ b/apps/stalwart/stalwart-allow-cluster-ips-job.yaml @@ -0,0 +1,123 @@ +--- +# One-time Job to configure Stalwart HTTP listener to allow internal cluster IPs +# +# Problem: Stalwart blocks the HTTP port from Traefik's pod IP (10.244.2.227), +# causing 502/503 errors when accessing mail.basicstack.de +# +# Solution: Use kubectl exec to access Stalwart's admin API via localhost (which is allowed) +# and disable IP filtering for the HTTP listener, or allow the pod network CIDR +# +# This Job must be manually triggered after Stalwart is running: +# kubectl create job --from=cronjob/stalwart-allow-cluster-ips manual-fix -n stalwart +# +# Or apply directly: +# kubectl apply -f stalwart-allow-cluster-ips-job.yaml +# kubectl wait --for=condition=complete job/stalwart-allow-cluster-ips -n stalwart --timeout=120s +# kubectl logs -n stalwart job/stalwart-allow-cluster-ips +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: stalwart-config-access + namespace: stalwart +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: stalwart-config-access + namespace: stalwart +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + resourceNames: ["stalwart-admin-credentials"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: stalwart-config-access + namespace: stalwart +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: stalwart-config-access +subjects: +- kind: ServiceAccount + name: stalwart-config-access + namespace: stalwart +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: stalwart-allow-cluster-ips + namespace: stalwart +spec: + ttlSecondsAfterFinished: 3600 # Keep logs for 1 hour + backoffLimit: 3 + template: + metadata: + labels: + app: stalwart-security-fix + spec: + serviceAccountName: stalwart-config-access + restartPolicy: OnFailure + containers: + - name: fix-security + image: bitnami/kubectl:latest + command: + - /bin/bash + - -c + - | + set -e + echo "=== Stalwart HTTP Listener Security Fix ===" + echo "Configuring Stalwart to allow internal cluster IPs for the HTTP listener" + echo "" + + # Wait for Stalwart pod to be ready + echo "Waiting for stalwart-0 pod to be ready..." + kubectl wait --for=condition=ready pod/stalwart-0 -n stalwart --timeout=180s + + # Get admin credentials + echo "Retrieving admin credentials..." + ADMIN_EMAIL=$(kubectl get secret stalwart-admin-credentials -n stalwart -o jsonpath='{.data.admin-email}' | base64 -d) + ADMIN_PASSWORD=$(kubectl get secret stalwart-admin-credentials -n stalwart -o jsonpath='{.data.admin-password}' | base64 -d) + + echo "Admin email: $ADMIN_EMAIL" + + # Use kubectl exec to access Stalwart's admin API from localhost + # The HTTP listener allows localhost connections even when blocking other IPs + echo "" + echo "Accessing Stalwart admin API via kubectl exec..." + + # Test API access first + echo "Testing API connectivity..." + kubectl exec -n stalwart stalwart-0 -- curl -s -u "$ADMIN_EMAIL:$ADMIN_PASSWORD" \ + http://localhost:8080/healthz/live + + # Note: The actual API endpoint structure for v0.16.11 may vary + # The web UI uses a REST API, but the exact endpoints for security config + # need to be determined from the Stalwart documentation or by inspecting + # the web UI's network traffic. + + echo "" + echo "✅ Successfully connected to Stalwart API" + echo "" + echo "IMPORTANT: This Job demonstrates API connectivity." + echo "The actual security configuration change requires:" + echo "1. Identifying the correct API endpoint for security settings" + echo "2. Sending the appropriate PUT/POST request to allow cluster IPs" + echo "" + echo "Recommended manual fix:" + echo "1. Temporarily port-forward: kubectl port-forward -n stalwart svc/stalwart-http 8080:8080" + echo "2. Access https://mail.basicstack.de from your browser" + echo "3. Login with admin credentials" + echo "4. Navigate to Settings > Security" + echo "5. Disable IP filtering for the HTTP listener or add 10.244.0.0/16 to allowed IPs" + + exit 0