Use context: kubectl config use-context k8s-c1-H
There was a security incident where an intruder was able to access the whole cluster from a single hacked backend Pod.
To prevent this create a NetworkPolicy called np-backend
in Namespace project-snake
. It should allow the backend-*
Pods only to:
- connect to
db1-*
Pods on port 1111 - connect to
db2-*
Pods on port 2222
Use the app
label of Pods in your policy.
After implementation, connections from backend-*
Pods to vault-*
Pods on port 3333 should for example no longer work.
Implementing Network Policies in Kubernetes: Securing Egress Traffic
Network policies in Kubernetes provide a way to control the communication between Pods. By default, all Pods in a Kubernetes cluster can communicate with each other. However, as your application grows, you may need to restrict this communication to improve security. In this guide, we’ll create a NetworkPolicy to restrict outgoing traffic from a backend Pod to only specific database Pods.
Step 1: Understanding the Current Pod Communication
Before implementing a NetworkPolicy, it’s important to understand the current state of communication between Pods. Let’s first inspect the existing Pods and their labels in the project-snake
namespace:
1 2 3 |
kubectl -n project-snake get pod -L app |
Example output:
1 2 3 4 5 6 7 8 9 |
NAME READY STATUS RESTARTS AGE APP backend-0 1/1 Running 0 3m15s backend db1-0 1/1 Running 0 3m15s db1 db2-0 1/1 Running 0 3m17s db2 vault-0 1/1 Running 0 3m17s vault |
Next, we’ll test the current connections from the backend Pod:
1 2 3 4 5 6 7 |
kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.25:1111 # db1 kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.23:2222 # db2 kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.22:3333 # vault |
All connections are currently unrestricted, which we can confirm from the outputs:
1 2 3 4 5 6 7 |
database one database two vault secret storage |
Step 2: Creating the NetworkPolicy
Now, we’ll create a NetworkPolicy to restrict the backend Pod’s egress traffic so that it can only communicate with db1 on port 1111 and db2 on port 2222.
First, create a YAML file for the NetworkPolicy:
1 2 3 |
vim 24_np.yaml |
Edit the file as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: np-backend namespace: project-snake spec: podSelector: matchLabels: app: backend policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: db1 ports: - protocol: TCP port: 1111 - to: - podSelector: matchLabels: app: db2 ports: - protocol: TCP port: 2222 |
This NetworkPolicy allows egress traffic from the backend Pod only to the db1 and db2 Pods on specific ports. This ensures that the backend Pod cannot communicate with any other services, including the vault service.
Apply the NetworkPolicy:
1 2 3 |
kubectl apply -f 24_np.yaml |
Step 3: Testing the NetworkPolicy
With the NetworkPolicy in place, let’s test the communication again from the backend Pod:
1 2 3 4 5 6 7 |
kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.25:1111 # db1 kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.23:2222 # db2 kubectl -n project-snake exec backend-0 -- curl -s 10.44.0.22:3333 # vault |
The expected results should be:
1 2 3 4 5 6 7 |
database one database two ^C # no response from vault, indicating blocked traffic |
The backend Pod can still communicate with the db1 and db2 Pods on the allowed ports, but the connection to the vault service is now blocked, as expected.
Step 4: Avoiding Common Mistakes
It’s important to carefully structure your NetworkPolicy rules to avoid unintended traffic. For example, the following NetworkPolicy would still allow communication to db2 on port 1111, which is not desired:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: np-backend namespace: project-snake spec: podSelector: matchLabels: app: backend policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: db1 - podSelector: matchLabels: app: db2 ports: - protocol: TCP port: 1111 - protocol: TCP port: 2222 |
This policy applies OR logic to pods and ports within a single rule, leading to unintended behavior. Always ensure each rule in your NetworkPolicy is well-defined with specific conditions.
Conclusion
NetworkPolicies are a powerful way to control communication in your Kubernetes cluster, enhancing security by restricting traffic between Pods. By carefully crafting and testing your policies, you can ensure that only the necessary communication paths are open, minimizing the attack surface of your applications.