๐Ÿ” Fixing HTTPS Connectivity from AWS ALB to NGINX Ingress Controller in Kubernetes

๐Ÿงฉ Problem Summary

We encountered an issue while setting up HTTPS traffic from an AWS Application Load Balancer (ALB) to our NGINX Ingress Controller deployed in a private EKS cluster. Specifically:

  • โœ… HTTPS โž HTTP (ALB terminates SSL, sends plain HTTP to NGINX): Worked
  • โŒ HTTPS โž HTTPS (ALB forwards SSL directly to NGINX): Did not work

โš ๏ธ Symptoms

  • ALB health checks were failing on port 443
  • Browsers showed SSL handshake or bad certificate errors
  • NGINX logs showed no SSL negotiation happening
  • Direct access to the NGINX NodePort via HTTPS worked fine

โš™๏ธ Initial Setup

โœ… ALB Listener (Working Case)

  • Port 443 โ†’ Target group on port 80 (HTTP)
  • SSL is terminated at ALB level

This worked because the NGINX Ingress was listening on HTTP internally, and the ALB decrypted HTTPS before forwarding it.

โŒ ALB Listener (Failing Case)

  • Port 443 โ†’ Target group on port 443 (HTTPS)
  • SSL passthrough from ALB to NGINX Ingress

This failed because NGINX Ingress was not configured to present a certificate by default when the ALB initiated a TLS handshake.

๐Ÿ› ๏ธ The Fix

To solve this, we added the following flag to the NGINX Ingress Controller deployment:

--default-server-tls-secret=aptia-ov3-dev/ov3-fe-dev-tls

๐Ÿ“Œ What This Does

  • Configures the default SSL certificate that NGINX Ingress will serve during TLS handshakes.
  • This is essential when:
    • The ALB is configured for HTTPS in the target group.
    • The Ingress Controller receives TLS connections directly.
    • No specific Ingress rule is matched yet (like for health checks or root path).

๐Ÿ” Why Is This Required?

By default, NGINX Ingress only presents a certificate if a matching TLS Ingress resource is hit. However, during:

  • ALB health checks (to /),
  • or initial TLS handshakes before routing,

NGINX has no cert to present unless a default is defined.

๐Ÿงพ Sample Secret Definition

Make sure you have a Kubernetes TLS secret created like:

apiVersion: v1
kind: Secret
metadata:
  name: ov3-fe-dev-tls
  namespace: aptia-ov3-dev
type: kubernetes.io/tls
data:
  tls.crt: <base64_cert>
  tls.key: <base64_key>

๐Ÿงฑ Updated Ingress Controller Args

In your Helm values or manifest:

controller:
  extraArgs:
    default-server-tls-secret: "aptia-ov3-dev/ov3-fe-dev-tls"

Or, if you’re using raw manifests:

args:
  - --default-server-tls-secret=aptia-ov3-dev/ov3-fe-dev-tls

โœ… Final Result

After setting the --default-server-tls-secret:

  • ALB to NGINX via HTTPS โž HTTPS worked correctly.
  • Health checks succeeded.
  • Browsers received valid TLS responses.
  • No more handshake or certificate errors.

๐Ÿง  Key Takeaways

LessonExplanation
ALB cannot connect via HTTPS unless NGINX has a default certBecause TLS handshake fails without a cert
NGINX must serve a certificate even when no Ingress is matchedRequired for root path/health checks
Always define --default-server-tls-secret when using HTTPS passthroughEspecially with ALBs on private EKS clusters

๐Ÿ”— References

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top