Pular para o conteúdo principal

Network Security Policies

Para essa sessão podemos rever o material do CKA. Somente irei colocar a diferença de conteúdo.

  • São as regras de firewall no Kubernetes.
  • Implementados pelo CNI, nem todos os Network Plugins suportam.
  • Nível de namespace.
  • Restringe o ingress e o egress para um grupo de pods baseado em certas condições.
  • Network Policies.

Nesse primeiro cenário estamos aplicando uma regra de saída estamos negando tudo, ao menos que passe em uma regra. Como não temos regras, tudo é negado.

alt text

Aqui já temos regras de saída.

alt text

Podemos criar várias network policies para os mesmo pods. Praticamente um merge.

  • Se um pod possui mais de uma NP
    • Então teremos a união de todas as NP aplicadas a ele.
    • A ordem não importa, o resultado é sempre o mesmo.

Sabendo disso podemos criar um NP para negar tudo em cada namespace e somente ir permitindo aquilo que é necessário.

Vamos rodar dois pods no namespace default e vamos conferir se conseguem se enxergar.

root@cks-master:~# kubectl get pods
No resources found in default namespace.

root@cks-master:~# k run frontend --image=nginx
pod/frontend created

root@cks-master:~# k run backend --image=nginx
pod/backend created

root@cks-master:~# k expose pod frontend --port 80
service/frontend exposed

root@cks-master:~# k expose pod backend --port 80
service/backend exposed

root@cks-master:~# k get pod,svc
NAME READY STATUS RESTARTS AGE
pod/backend 1/1 Running 0 46s
pod/frontend 1/1 Running 0 59s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend ClusterIP 10.111.182.74 <none> 80/TCP 20s
service/frontend ClusterIP 10.104.14.250 <none> 80/TCP 27s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 44h

# executando um curl dentro do frontend para o backend

root@cks-master:~# k exec frontend -- curl backend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 73652 0 <!DOCTYPE html>-- --:--:-- 0
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
--:--:-- --:--:-- --:--:-- 76875

root@cks-master:~# k exec backend -- curl frontend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 221k 0 --:--:-- --:--:-- --:--:-- 300k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Podemos observar que existe a comunicação. Vamos criar uma NP default e somente permitir o que é necessário.

Crie um arquivo e aplique no cluster.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
root@cks-master:~# mkdir default
root@cks-master:~# cd default/
root@cks-master:~/default# vi np-default-deny.yaml
root@cks-master:~/default# kubectl apply -f np-default-deny.yaml
networkpolicy.networking.k8s.io/default-deny created

root@cks-master:~/default# k get networkpolicies
NAME POD-SELECTOR AGE
default-deny <none> 48s
root@cks-master:~/default# k describe networkpolicies default-deny
Name: default-deny
Namespace: default
Created on: 2024-08-17 17:33:21 +0000 UTC
Labels: <none>
Annotations: <none>
Spec:
PodSelector: <none> (Allowing the specific traffic to all pods in this namespace)
Allowing ingress traffic:
<none> (Selected pods are isolated for ingress connectivity)
Allowing egress traffic:
<none> (Selected pods are isolated for egress connectivity)
Policy Types: Ingress, Egress

# Se tentar a comunicação novamente vemos que não conseguimos mais a página do nginx.

root@cks-master:~/default# k exec frontend -- curl backend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:14 --:--:--
root@cks-master:~/default#

Vamos permitir o pod frontend saír para o backend.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend
namespace: default
spec:
podSelector:
matchLabels:
run: frontend # Quando rodando o comando run temos essa label padronizada
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
run: backend

Vamos criar e aplicar essa policy.

root@cks-master:~/default# vim np-frontend.yaml
root@cks-master:~/default# kubectl apply -f np-frontend.yaml
networkpolicy.networking.k8s.io/frontend created
root@cks-master:~/default# k exec frontend -- curl backend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0

Não conseguimos ainda a conexão pois o pod backend está negando tudo, vamos então liberar a entrada dele.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend
namespace: default
spec:
podSelector:
matchLabels:
run: backend # Quando rodando o comando run temos essa label padronizada
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
run: frontend

Vamos liberar a entrada para os pods do frontend no backend e testar.

root@cks-master:~/default# vim np-backend.yaml

root@cks-master:~/default# kubectl apply -f np-backend.yaml
networkpolicy.networking.k8s.io/backend created

# Ainda não conseguimos
root@cks-master:~/default# k exec frontend -- curl backend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:--

root@cks-master:~/default# k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
backend 1/1 Running 0 26m 192.168.1.3 cks-worker <none> <none>
frontend 1/1 Running 0 26m 192.168.1.2 cks-worker <none> <none>

# Tentando direto pelo IP conseguimos
root@cks-master:~/default# k exec frontend -- curl 192.168.1.3
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
100 615 100 615 0 0 399k 0 --:--:-- --:--:-- --:--:-- 600k

O que esta acontecendo é que não conseguimos resolver os nomes pois não tem acesso ao core-dns. Precisamos liberar isso em todos os pods do namespace. Para que isso seja fácil podemos aplicar esta regra em todos os pods de uma única vez. Podemos alterar o nosso default-deny ou criar outro NP. Vamos extender o default-deny e permitir somente o egress para a porta 53.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
ports:
- port: 53
protocol: TCP
- port : 53
protocol: UDP
root@cks-master:~/default# vim np-default-deny.yaml

root@cks-master:~/default# k apply -f np-default-deny.yaml
networkpolicy.networking.k8s.io/default-deny configured

# Funcionando
root@cks-master:~/default# k exec frontend -- curl backend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 268k 0 --:--:-- --:--:-- --:--:-- 300k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

# E só para constar, não permitimos que o backend se comunique com o frontend
# Também não permitimos entrdadas no frontend. Só permitimos uma direção frontend > backend.

root@cks-master:~/default# k exec backend -- curl frontend
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0^C
root@cks-master:~/default# k exec backend -- curl 192.168.1.2
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0^C
root@cks-master:~/default#