--- # 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