Securing Ingress Resources in Kubernetes with TLS

Updated: January 30, 2024 By: Guest Contributor Post a comment

Introduction

Welcome to this comprehensive guide on securing Ingress resources in Kubernetes using TLS. As traffic to your applications becomes more complex, providing secure and encrypted connections is paramount to protect sensitive data from eavesdropping and tampering. In this tutorial, we’ll guide you through the process of setting up TLS for your Ingress resources, ensuring that your Kubernetes deployments are safe and secure.

Prerequisites

  • A Kubernetes cluster with Ingress controller installed (e.g., nginx-ingress or traefik)
  • kubectl command-line tool, configured to communicate with your cluster
  • A domain name for which you can configure DNS records
  • Certificates for your domain (either from a Certificate Authority (CA) or self-signed for testing purposes)

Basic TLS Setup for Ingress

First, let’s start with the basic setup of a TLS-secured Ingress resource. We will use a self-signed certificate in this example. To generate a self-signed certificate, run:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=yourdomain.com/O=yourdomain.com"

Next, create a Kubernetes Secret to store your TLS certificate and private key:

kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt

Here is a simple Ingress definition with TLS:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - yourdomain.com
    secretName: my-tls-secret
  rules:
  - host: yourdomain.com
    http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 80
        path: /

With the above Ingress definition, any traffic to yourdomain.com will be served over HTTPS, using the TLS certificate stored in my-tls-secret.

Using Cert-Manager for Automatic Certificate Management

Managing certificates manually can be error-prone and insecure if not done properly. To automate this process, we can use Cert-Manager, a Kubernetes add-on which automates the management and issuance of TLS certificates from various issuing sources such as Let’s Encrypt.

First, install Cert-Manager to your cluster:

kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.yaml

Then, you’ll need to create an Issuer or ClusterIssuer resource. For Let’s Encrypt, you might use:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-staging-private-key
    solvers:
    - http01:
        ingress:
          class: nginx

With the ClusterIssuer configured, you can define your Ingress resource to use automatic certificate provisioning:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-staging
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - yourdomain.com
    secretName: my-tls-cert
  rules:
  - host: yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

The cert-manager.io/cluster-issuer annotation tells Cert-Manager to manage certificates for this Ingress. Any required certificates will be automatically created and renewed.

Advanced Configuration and Best Practices

For more control over TLS behavior in your Ingress, you can specify additional TLS settings through annotations. For example, to enforce strong ciphers and TLS versions:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-ciphers: 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256'
    nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers: 'true'
    nginx.ingress.kubernetes.io/ssl-protocols: 'TLSv1.2 TLSv1.3'

It is also a good practice to redirect all HTTP traffic to HTTPS, which can be done using an annotation:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'

Use multiple TLS secrets for different hosts under the same Ingress (if necessary) by adding more entries under spec.tls.

Security Considerations

Be aware of the security implications of using self-signed certificates in production. It’s generally recommended to use certificates from a trusted CA. Keep private keys secure; they should never be committed to version control or left exposed.

Maintain good certificate hygiene by rotating certificates regularly and monitoring expiration dates to avoid service outages.

Debugging Common Issues

Common issues with TLS Ingress can include incorrect DNS configuration, certificate misconfiguration, or improper Ingress controller setup. To debug your Ingress TLS setup, you can inspect the running Ingress pods for logs, verify your DNS setup for correctness, and ensure that the Secret with your TLS data is correctly formatted and applied to the cluster.

To verify certificate installation using the command line, you can use:

openssl s_client -connect yourdomain.com:443

Which should output information about your server’s SSL certificate.

Conclusion

By securing your Ingress resources with TLS, you improve the security posture of your entire Kubernetes deployment. This guide serves as a springboard to deploy TLS in your clusters effectively. With automation tools like Cert-Manager, handling TLS is easier and more reliable. Take the steps outlined to ensure encrypted and trusted communication for your cluster services.