Description
Ingress connects Services to HTTP and HTTPS requests. Depending on the controller and load balancer configuration, access may come from the internet or an internal network. Verify that workloads intended for internal use are not publicly exposed.
Not every service needs an Ingress. Select only those that require external access and restrict the rest to internal communication.
Potential impact
- Internal services may become reachable from the internet or other external networks.
- Exposure without required authentication, rate limits or other protections can increase the attack surface.
- Incorrect routing can send external requests to unintended services.
Remediation
- Remove public Ingress routes for internal workloads or use an internal-only controller.
- Restrict exposed services and paths to those that need external access.
- Review authentication, access controls, TLS and rate limits, and test actual external reachability.
Examples
The first excerpt retains the historical extensions/v1beta1 format for illustration. Kubernetes stopped serving that Ingress API in 1.22; use the supported networking.k8s.io/v1 format for current deployments.
Before
yaml
apiVersion: v1
kind: Service
metadata:
name: app
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: 3000
selector:
app: app
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.acme.org
http:
paths:
- backend:
serviceName: app
servicePort: 3000
After
yaml
apiVersion: v1
kind: Service
metadata:
name: app
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: 3000
selector:
app: app
Explanation:
- Before: Defines a route through a controller to the
appService. Internet exposure also depends on controller configuration. - After: Retains only the internal
ClusterIPService. Omitting an Ingress from this file does not delete an existing resource; remove the existingapp-ingressand check for other public routes.