The Kubernetes Ingress resource and its associated controllers are how external traffic enters your cluster. They terminate TLS, route requests, and often provide the first layer of security filtering. A misconfigured Ingress is not just a availability risk, it is a security exposure that gives attackers a direct path into your cluster services.
Most Ingress security documentation focuses on getting traffic flowing. This guide focuses on making sure that traffic is handled securely.
TLS Configuration
Force HTTPS Everywhere
Every Ingress resource should redirect HTTP to HTTPS. With the NGINX Ingress Controller, annotate your Ingress:
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
Without these annotations, the Ingress controller accepts plain HTTP traffic, sending credentials, tokens, and sensitive data in the clear.
Configure Modern TLS
Default TLS configurations often support legacy protocols and cipher suites. Restrict your Ingress controller to TLS 1.2 and 1.3 with strong cipher suites.
For the NGINX Ingress Controller, configure through the ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
data:
ssl-protocols: "TLSv1.2 TLSv1.3"
ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
Use cert-manager for Certificate Automation
Manual certificate management leads to expired certificates. Use cert-manager with Let's Encrypt or your internal CA to automate certificate issuance and renewal:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
Rotate TLS Secrets
Even with automated certificate management, audit your TLS secrets regularly. Check for certificates that are about to expire, certificates using weak keys, and certificates for domains you no longer serve.
Request Filtering
Enable Rate Limiting
Without rate limiting, your Ingress is vulnerable to brute-force attacks, credential stuffing, and denial-of-service:
metadata:
annotations:
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "5"
Set rate limits based on your expected traffic patterns. Too restrictive and you block legitimate users; too permissive and the rate limiting is ineffective.
Restrict Request Size
Large request bodies can be used for denial-of-service or to exploit vulnerabilities in body parsing:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "1m"
Set the maximum body size to the largest legitimate request your application expects. For most APIs, this is well under 10 MB.
Configure Timeouts
Long-running connections consume resources. Set appropriate timeouts for your application:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-connect-timeout: "5"
nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
Add Security Headers
The Ingress controller can inject security headers that browsers enforce:
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Access Control
Restrict Source IPs
If your Ingress serves internal services, restrict access to known IP ranges:
metadata:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12"
Enable Client Certificate Authentication
For service-to-service communication, mutual TLS (mTLS) provides strong authentication:
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-tls-secret: "namespace/ca-secret"
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
External Authentication
Integrate with external authentication services for user-facing applications:
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/verify"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/login"
Common Misconfigurations
Default Backend Exposure
The default backend handles requests that do not match any Ingress rule. If it returns detailed error information or has its own vulnerabilities, it exposes your cluster. Configure a custom default backend that returns a minimal error page.
Wildcard Ingress Rules
An Ingress without a host specification matches all hostnames. This can expose internal services if DNS records are pointed at your Ingress controller:
# Risky - matches all hostnames
spec:
rules:
- http:
paths:
- path: /
backend:
service:
name: my-service
# Secure - matches only the specified hostname
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api
backend:
service:
name: my-service
Path Traversal Through Ingress
Some Ingress controller versions have been vulnerable to path traversal attacks where specially crafted paths bypass routing rules and reach unintended backends. Keep your Ingress controller updated and review CVEs specific to your controller version.
Annotation Injection
Custom annotations can sometimes inject raw configuration into the underlying proxy. The NGINX Ingress Controller has had CVEs related to annotation injection. Validate annotations and restrict who can create or modify Ingress resources.
Monitoring
Monitor your Ingress controller for security-relevant events: 4xx and 5xx error spikes, unusual traffic patterns, certificate warnings, and backend health check failures. The NGINX Ingress Controller exports Prometheus metrics that can drive alerting rules.
How Safeguard.sh Helps
Safeguard.sh monitors the security posture of your Kubernetes deployments, including the software components that make up your Ingress controllers and the applications behind them. It identifies vulnerabilities in Ingress controller images, tracks the dependencies of your backend services, and generates SBOMs that provide complete visibility into your cluster's software supply chain. When a new vulnerability affects your Ingress controller or any service it routes to, Safeguard.sh alerts you immediately.