Resolving Hostname Validation in mTLS Environments
In a Kubernetes environment where Istio or a similar service mesh enforces strict mutual TLS (mTLS), the spec.tls.hosts field in the Ingress manifest should not be automatically populated with the internal service FQDN (e.g., api.myapp.svc.cluster.local). Instead, the Ingress TLS configuration is intended for the external-to-internal boundary. Internal service-to-service communication is handled by the mesh's sidecar proxies, which use their own identity certificates independent of the Ingress resource.
The Role of Ingress TLS vs. Service Mesh mTLS
There is a critical distinction between the Ingress TLS (which secures traffic from the public internet to the cluster) and mTLS (which secures traffic between pods). Omitting the hosts entry in the Ingress TLS block typically defaults the Ingress controller to serve the first certificate found in the referenced secret. While this works for wildcard certificates, it can cause validation failures if the client expects a specific Subject Alternative Name (SAN) that is missing from the certificate.
Risks of Omitting Host Entries
- Certificate Mismatch: If the Ingress controller serves a certificate that does not include the requested FQDN in its SAN list, the TLS handshake will fail during hostname validation.
- Routing Ambiguity: Without explicit
hosts mapping, some controllers may fail to route traffic to the correct backend service when multiple services share a single IP.
- Strict Validation Failures: In strict mTLS or high-security environments, clients will reject any certificate that does not explicitly match the requested hostname, leading to
SSLHandshakeException or CERT_COMMON_NAME_INVALID errors.
Verification and Alignment Steps
To ensure your Ingress TLS hosts align with your certificate SANs, use the following scoped commands:
- Verify the Ingress Manifest: Check if the host is explicitly defined.
kubectl get ingress <app-name>-ingress -o yaml
- Inspect the Certificate SANs: Extract the certificate from the secret to verify the SAN list includes your FQDN.
kubectl get secret <app-name>-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout | grep -A 1 "Subject Alternative Name"
- Test the Handshake: Simulate a request using the specific Host header to trigger validation.
curl -v -H "Host: api.myapp.com" https://<load-balancer-ip>
Recommendation
Users should rely on cert-manager to manage SANs. Rather than modifying the JHipster generator to inject internal FQDNs (which would be incorrect for an Ingress resource), you should configure a Certificate resource in cert-manager that explicitly lists all required DNS names for both internal and external access.
Diagnostic Detail Needed: Are the failing internal calls occurring between two pods in the same cluster, or from an external client hitting the Ingress gateway?