CiliumNetworkPolicy — allows egress to public destinations (outside cluster) and other pods in the same namespace
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
...
...
...