CiliumNetworkPolicy — allows egress to public destinations (outside cluster) and other pods in the same namespace

Jbn1233
3 min readOct 18, 2024

--

For this example, allow internet access (HTTPS only), deny access to another pod in other namespaces ,but allow to kube-dns (UDP port 53 only)

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-external-and-within-namespace
namespace: jail
spec:
egress:
#set1
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s:k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
#set2
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: jail
toPorts:
- ports:
- port: "8080"
protocol: TCP
#set3
- toCIDR:
- 0.0.0.0/0
toPorts:
- ports:
- port: "443"
protocol: TCP
endpointSelector:
matchLabels: {}

POC1:

Access to internet only https (TCP port 443)

$ k exec -it  -n jail deployments/debug  -- bash
root@debug-5fc65cd4f6-678tj:/#
root@debug-5fc65cd4f6-678tj:/# curl -vk -sS -m1 -o /dev/null http://www.google.com
* Host www.google.com:80 was resolved.
* IPv6: (none)
* IPv4: 172.217.25.196
* Trying 172.217.25.196:80...
* Connection timed out after 1002 milliseconds
* Closing connection
curl: (28) Connection timed out after 1002 milliseconds


root@debug-5fc65cd4f6-678tj:/# curl -vk -sS -m1 -o /dev/null https://www.google.com
* Host www.google.com:443 was resolved.
* IPv6: (none)
* IPv4: 172.217.25.196
* Trying 172.217.25.196:443...
* Connected to www.google.com (172.217.25.196) port 443
* ALPN: curl offers h2,http/1.1
...
...
...
} [5 bytes data]
> GET / HTTP/2
> Host: www.google.com
> User-Agent: curl/8.5.0
> Accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [282 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [282 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
< HTTP/2 200
...
...
...
<
{ [5495 bytes data]
* Connection #0 to host www.google.com left intact
root@debug-5fc65cd4f6-678tj:/#

POC2:

Allow only the same namespace (jail) port 8080. 10.96.140.143:80 is svc ip:port ,but actual pod listen on port 8080

$ k exec -it  -n jail deployments/debug  -- bash
root@debug-5fc65cd4f6-678tj:/# curl -vk -sS -m1 -o /dev/null https://kubernetes.default.svc.cluster.local
* Host kubernetes.default.svc.cluster.local:443 was resolved.
* IPv6: (none)
* IPv4: 10.96.0.1
* Trying 10.96.0.1:443...
* Connection timed out after 1003 milliseconds
* Closing connection
curl: (28) Connection timed out after 1003 milliseconds
root@debug-5fc65cd4f6-678tj:/#
root@debug-5fc65cd4f6-678tj:/# curl -vk -sS -m1 -o /dev/null http://echo.jail.svc.cluster.local
* Host echo.jail.svc.cluster.local:80 was resolved.
* IPv6: (none)
* IPv4: 10.96.140.143
* Trying 10.96.140.143:80...
* Connected to echo.jail.svc.cluster.local (10.96.140.143) port 80
> GET / HTTP/1.1
> Host: echo.jail.svc.cluster.local
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 18 Oct 2024 13:36:47 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< Server: echoserver
<
{ [523 bytes data]
* Connection #0 to host echo.jail.svc.cluster.local left intact

POC3:

Allow only UDP port 53 to kube-dns. return fail on tcp lookup

$ k exec -it  -n jail deployments/debug  -- bash
root@debug-5fc65cd4f6-678tj:/# timeout 3 host -U www.google.com
www.google.com has address 172.217.25.196
root@debug-5fc65cd4f6-678tj:/#
root@debug-5fc65cd4f6-678tj:/# timeout 3 host -T www.google.com
root@debug-5fc65cd4f6-678tj:/#

That is all.

Update1:

Chat toCIDR for limit access to private ip only

  - toCIDR:
- 192.168.0.0/16
- 10.0.0.0/8
- 172.16.0.0/12

L7 sample:

Allow HTTP GET /public from ANY to app=echo

$ k get ciliumnetworkpolicies.cilium.io  -o yaml rule1 
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "Allow HTTP GET /public from ANY to app=echo"
endpointSelector:
matchLabels:
app: echo
ingress:
- toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/public"

$ k exec -it console -- curl http://echo
Access denied
$ k exec -it console -- curl -X POST http://echo/public
Access denied
$ k exec -it console -- curl http://echo/public

Hostname: echo-75688c445c-ksjpp

Pod Information:
node name: cks-worker1
pod name: echo-75688c445c-ksjpp
pod namespace: default
pod IP: 10.169.6.128
...
...
...

--

--

Jbn1233
Jbn1233

Written by Jbn1233

Very short and simple notes for CKA/SRE and may not works on your environment | jbn1233@gmail.com | Bangkok, Thailand |

No responses yet