Best Practices for Kubernetes Network Policies
Remember to enable a CNI that supports network policies when deploying the cluster!
A good policy should restrict ingress access:
- The default Kubernetes policy is “any-any-any allow” so every namespace should have a deny all policy to correct this insecure default
- No service should allow incoming traffic from external IPs unless it has a load-balancer or ingress attached to it
- Services with a load-balancer or ingress should only allow access from the load-balancer IPs:
- GKE: 22.214.171.124/22 and 126.96.36.199/16
- EKS: 188.8.131.52/16
- AKS: ?
- Services should only accept traffic on the protocol/port that is served by its pods. For example, a web service should only access incoming traffic on HTTP (and never on its admin port!).
- Services should only accept traffic from other services (pods) that consume them, either in the same namespace or from another namespace.
In order to write an ingress policy from a pod in another namespace, you need add a label to the namespace.
- The Kubernetes DNS service should only allow ingress access on UDP 53 from other pods (not from external IPs).
A good policy should restrict egress to a minimum:
Egress policies are more difficult to configure than ingress for several reasons:
- People often don’t know which external services their pods need to consume (typically cloud services like storage, key management, message queues etc.)
- Consuming services outside of the cluster is often based on a DNS name which isn’t supported by Kubernetes network policies (only IP addresses).
- When enforcing egress policies, you must be careful not to block connectivity to essential services like the Kubernetes DNS service
You should prohibit outbound traffic from pods that don’t need to connect externally. This can help prevent data exfiltration and downloading of malicious binaries.
Start by detecting the external services your service consumes. You can easily do this with Tufin SecureCloud.
If your service depends on external services, make sure you understand what they are and whether they are really needed and then apply policies to allow the connections.
If your pod needs to connect to a DNS (FQDN) name that doesn’t have a fixed IP address, you cannot do it with Kubernetes policies. Instead, you‘ll need to allow egress access to any IP address (excluding your pod subnet) and then to use an external firewall or proxy to restrict access to the DNS name.
For more details about network policies, see my blog post.