Skip to main content

TLS/SSL Configuration

Intermediate
  • TLS in Gateway API vs Nginx Ingress
  • Nginx Ingress - TLS Configuration
  • Gateway API - TLS Configuration
  • +29 more sections...

TLS/SSL Configuration

TLS (Transport Layer Security) configuration in Gateway API is handled at the Gateway level, providing centralized certificate management. This guide covers TLS setup and compares it to Nginx Ingress.

TLS/SSL Configuration Flow

How TLS termination and certificate management works in Gateway API

1. Certificate Management
Store TLS certificates as Kubernetes Secrets
kubectl create secret tls my-cert --cert=cert.pem --key=key.pem
2. Gateway Listener
Configure TLS listener on Gateway resource
listeners: - protocol: HTTPS, port: 443, tls: mode: Terminate
3. TLS Termination
Gateway terminates TLS and forwards HTTP to backends
Mode: Terminate - Gateway handles TLS, backends receive plain HTTP
4. Secure Connection
Client connects via HTTPS, Gateway validates certificate

TLS Modes

Terminate

Gateway terminates TLS and forwards plain HTTP to backends. Most common mode.

Passthrough

Gateway passes TLS traffic through to backends without termination. Backends handle TLS.

vs. Ingress: Gateway API provides more explicit TLS configuration with better certificate management. Ingress requires annotations for advanced TLS features.

TLS in Gateway API vs Nginx Ingress

Nginx Ingress - TLS Configuration

In Nginx Ingress, TLS is configured in the Ingress resource:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
      secretName: example-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-service
                port:
                  number: 80

Certificates are managed via Kubernetes Secrets.

Gateway API - TLS Configuration

In Gateway API, TLS is configured at the Gateway level, not the HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      allowedRoutes:
        namespaces:
          from: All

HTTPRoutes automatically use the Gateway's TLS configuration.

TLS Modes

Gateway API supports different TLS modes, but NGINX Gateway Fabric only supports TLS termination:

1. Terminate (TLS Termination)

TLS is terminated at the Gateway, and traffic to backends is unencrypted (HTTP).

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All

Use case: Most common pattern. Gateway handles TLS, backends receive plain HTTP.

NGINX Gateway Fabric Note: NGF only supports Terminate mode. TLS passthrough is not supported.

2. Passthrough (Not Supported by NGF)

⚠️ Not Supported by NGINX Gateway Fabric

TLS passthrough is part of the Gateway API specification but is not supported by NGINX Gateway Fabric. NGF focuses on Layer 7 (HTTP/HTTPS) routing and only supports TLS termination.

The example below shows how TLS passthrough would be configured in Gateway API, but this will not work with NGINX Gateway Fabric. If you need TLS passthrough, you would need to use a different Gateway API implementation that supports it.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https-passthrough
      protocol: TLS
      port: 443
      tls:
        mode: Passthrough
      allowedRoutes:
        namespaces:
          from: All

Use case: Backend services handle their own TLS certificates (e.g., for mTLS or when backends manage their own certificates).

Certificate Management

Creating TLS Secrets

TLS certificates are stored as Kubernetes Secrets, same as Nginx Ingress:

kubectl create secret tls example-tls \
  --cert=path/to/cert.crt \
  --key=path/to/cert.key

Or using cert-manager:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-cert
spec:
  secretName: example-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - example.com
    - www.example.com

Referencing Certificates in Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
            group: ""
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All

NGINX Gateway Fabric Limitation: NGF supports at most one TLS certificate reference per listener. If multiple certificates are specified in certificateRefs, only the first certificate will be used.

Multiple Certificates

Multiple Hostnames with Different Certificates

You can configure multiple listeners for different hostnames:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: multi-cert-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https-example
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All
    - name: https-api
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: api-tls
            kind: Secret
      hostname: api.example.com
      allowedRoutes:
        namespaces:
          from: All

Wildcard Certificates

Use wildcard certificates for multiple subdomains:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: wildcard-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-tls
            kind: Secret
      hostname: "*.example.com"
      allowedRoutes:
        namespaces:
          from: All

HTTP and HTTPS Listeners

You can configure both HTTP and HTTPS listeners:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: http-https-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: All
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      allowedRoutes:
        namespaces:
          from: All

HTTPRoutes can attach to either listener.

TLS Options

TLS Version and Cipher Suites

⚠️ Not Supported by NGINX Gateway Fabric

The listener.tls.options field is part of the Gateway API specification but is not supported by NGINX Gateway Fabric. If you specify TLS options in a Gateway resource, NGF will ignore them.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: tls-options-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
        options:
          # Implementation-specific options
          # Check your Gateway implementation docs

Note: TLS options are implementation-specific. Check your Gateway provider's documentation. Some Gateway API implementations support TLS options for configuring TLS versions and cipher suites, but NGF does not currently support this feature. For TLS configuration in NGF, you can use the NginxProxy custom resource if you need advanced TLS settings.

Mutual TLS (mTLS)

Mutual TLS requires both client and server certificates. This is typically handled via policies (see Policies documentation).

Complete Examples

Example 1: Basic HTTPS Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: https-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-route
spec:
  parentRefs:
    - name: https-gateway
  hostnames:
    - example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: my-service
          port: 80

Example 2: HTTP to HTTPS Redirect

Some implementations support automatic HTTP to HTTPS redirects. Check your Gateway provider's documentation.

For Nginx Gateway Fabric, you might configure:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: redirect-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: All
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      allowedRoutes:
        namespaces:
          from: All

Then use a redirect filter in HTTPRoute (see Request/Response Modifications).

Example 3: Multiple Domains

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: multi-domain-gateway
spec:
  gatewayClassName: nginx-gateway
  listeners:
    - name: https-example
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
            kind: Secret
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All
    - name: https-api
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: api-tls
            kind: Secret
      hostname: api.example.com
      allowedRoutes:
        namespaces:
          from: All

Comparison Table

FeatureNginx IngressGateway APINGINX Gateway Fabric
TLS LocationIngress resourceGateway resourceGateway resource
Certificate StorageKubernetes SecretsKubernetes SecretsKubernetes Secrets
TLS TerminationSupportedmode: Terminate✅ Supported (Terminate only)
TLS PassthroughSupportedmode: Passthrough❌ Not supported
Multiple CertificatesMultiple Ingress resourcesMultiple listeners✅ Multiple listeners (one cert per listener)
Wildcard CertificatesSupportedSupported✅ Supported
Certificate ManagementManual or cert-managerManual or cert-managerManual or cert-manager
TLS OptionsConfigMap annotationslistener.tls.options❌ Not supported

Best Practices

  1. Centralized TLS: Configure TLS at the Gateway level for centralized management
  2. Use cert-manager: Automate certificate provisioning and renewal
  3. Wildcard Certificates: Use wildcard certs for multiple subdomains when possible
  4. TLS Termination: Use TLS termination for most use cases (simpler backend setup)
  5. Certificate Rotation: Plan for certificate rotation and renewal
  6. TLS Versions: Ensure modern TLS versions (1.2+) are used
  7. Separate HTTP/HTTPS: Configure both HTTP and HTTPS listeners when needed

Common Patterns

Pattern 1: Single Domain HTTPS

Gateway with HTTPS listener → HTTPRoute with hostname

Pattern 2: Multiple Domains

Gateway with multiple HTTPS listeners (one per domain) → HTTPRoutes per domain

Pattern 3: HTTP to HTTPS Redirect

Gateway with HTTP and HTTPS listeners → HTTPRoute with redirect filter

Troubleshooting

Certificate Not Working?

  1. Verify the Secret exists: kubectl get secret example-tls
  2. Check certificate format (must be valid TLS secret)
  3. Verify certificateRef name matches Secret name
  4. Check Gateway status for certificate errors
  5. Ensure certificate is valid for the hostname

TLS Handshake Fails?

  1. Verify certificate is not expired
  2. Check certificate matches the hostname
  3. Verify TLS mode is correct (Terminate vs Passthrough)
  4. Check Gateway implementation logs

Multiple Certificates Not Working?

  1. Verify each listener has a unique hostname
  2. Check that certificates match their respective hostnames
  3. Ensure HTTPRoutes reference the correct Gateway listener

Next Steps

Now that you understand TLS configuration, let's learn about request and response modifications:

👉 Next: Request/Response Modifications →

Sources & References

Version Compatibility: This content is based on Gateway API v1 and NGINX Gateway Fabric 2.2.1. Please verify compatibility with your cluster's Gateway API implementation and version.