Setting up a firewall with Network Policies
While setting up the network policy, you may need to refer to the namespace created earlier. In order to being abel to referred to, namespace should have a label. Lets update the namespace with a label.
file: instavote-ns.yaml
kind: Namespace
apiVersion: v1
metadata:
name: instavote
labels:
project: instavote
apply
kubectl get namespace --show-labels
kubectl apply -f instavote-ns.yaml
kubectl get namespace --show-labels
Now, define a restrictive network policy which would,
- Block all incoming connections from any source except for pods from the same namespace
- Block all outgoing connections
+-----------------------------------------------------------+
| |
| +----------+ +-----------+ |
x | | results | | db | |
| | | | | |
| +----------+ +-----------+ |
| |
| |
| +----+----+--+ |
| | worker | |
| | | |
| +----+-------+ |
| |
| |
| +----------+ +-----------+ |
| | vote | | redis | |
x | | | | | |
| +----------+ +-----------+ |
| |
+-----------------------------------------------------------+
file: instavote-netpol.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
apply
kubectl get netpol
kubectl apply -f instavote-netpol.yaml
kubectl get netpol
kubectl describe netpol/default-deny
Try accessing the vote and results ui. Can you access it ?
Setting up ingress rules for outward facing applications
+-----------------------------------------------------------+
| |
| +----------+ +-----------+ |
=====> | results | | db | |
| | | | | |
| +----------+ +-----------+ |
| |
| |
| +----+----+--+ |
| | worker | |
| | | |
| +----+-------+ |
| |
| |
| +----------+ +-----------+ |
| | vote | | redis | |
=====> | | | | |
| +----------+ +-----------+ |
| |
+-----------------------------------------------------------+
To the same file, add a new network policy object.
file: instavote-netpol.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: public-ingress
namespace: instavote
spec:
podSelector:
matchExpressions:
- {key: role, operator: In, values: [vote, results]}
policyTypes:
- Ingress
ingress:
- {}
where,
instavote-ingress is a new network policy which,
- defines policy for pods with vote and results role
- and allows them incoming access from anywhere
apply
kubectl apply -f instavote-netpol.yaml
Exercise
- Try accessing the ui now and check if you are able to.
- Try to vote, see if that works? Why ?
Setting up egress rules to allow communication between services from same project
When you tried to vote, you might have observed that it does not work. Thats because the default network policy we created earlier blocks all outgoing traffic. Which is good for securing the environment, however you still need to provide inter connection between services from the same project. Specifically vote, worker and results apps need outgoing connection to redis and db. Lets allow that with a egress policy.
+-----------------------------------------------------------+
| |
| +------------+ +-----------+ |
=====> | results | ------>| db | |
| | | | | <-------+ |
| +------------+ +-----------+ | |
| | |
| | |
| +----+----+---+ |
| | worker | |
| | | |
| +----+--------+ |
| | |
| | |
| +----------+ +-----------+ | |
| | vote | | redis | <-------+ |
=====> | | ------> | | |
| +----------+ +-----------+ |
| |
+-----------------------------------------------------------+
Edit the same policy file and add the following snippet,
file: instavote-netpol.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: instavote
egress:
- to:
- namespaceSelector:
matchLabels:
project: instavote
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: public-ingress
namespace: instavote
spec:
podSelector:
matchExpressions:
- {key: role, operator: In, values: [vote, results]}
policyTypes:
- Ingress
ingress:
- {}
where,
instavote-egress is a new network policy which,
- defines policy for pods with vote, worker and results role
- and allows them outgoing access to any pods in the same namespace, and that includes redis and db
Project
The above network policies are a good start. However you could even further restrict access by creating a granular network policy for each application.
Create network policies with following specs,
vote
- allow incoming connections from anywhere, only on port 80
- allow outgoing connections to redis
- block everything else, incoming and outgoing
redis
- allow incoming connections from vote and worker, only on port 6379
- block everything else, incoming and outgoing
worker
- allow outgoing connections to redis and db
- block everything else, incoming and outgoing
db
- allow incoming connections from worker and results, only on port 5342
- block everything else, incoming and outgoing
results
- allow incoming connections from anywhere, only on port 80
- allow outgoing connections to db
- block everything else, incoming and outgoing