YouTube 16 July 2021
hosted by Duffie Cooley
netkat is a netcat clone that uses raw sockets to avoid iptables and/or other OS filtering mechanisms.
Kubernetes environments have a LOT of iptables, hence the necessity to bypass iptables sometimes, for testing, debugging, troubleshooting, …
netkat works as the original netcat, but using raw sockets, so it is not affected by the netfilter hooks.
A RAW socket receives a copy of all packets, however, we don't need all of them, just the ones used by the netkat connection.
On the socket we filter the packets that we don't WANT On ingress we filter the packets that we WANT, so the host doesn't close our connection
Netkat can obtain the tuple of the connection in advance, so it can filter using BFP and the socket SO_ATTACH_FILTER option, and the traffic control eBPF filtering capability.
The packets received on the socket, are raw packets (with ethernet headers), but since they are bypassing the kernel TCP/IP stack, something need to reassemble the packets and obtain a data stream. This is achieved using an userspace TCP/IP stack https://pkg.go.dev/gvisor.dev/gvisor/pkg/tcpip/stack
At high level, the code does:
As result, we have a new version of netcat that bypass iptables (needs CAP_NET_RAW) It has a bonus, with the -d flag it has a sniffer XD
I really like that Antonio wrote tests for this let's check them out.
The loadbalancer has externalTrafficPolicy: Local
so it should only be able to work
if the traffic is directed to the nodes that contains pods belonging to that Service.
Get the nodes IPs
example: pod is in kind-worker2 with ip 172.18.0.2 and loadbalancer IP 10.111.111.129
externalTrafficPolicy: Cluster
it works … but the source IP is not preservedexternalTrafficPolicy: Local
againWe think it shoudn't work because we are in a node without pods, however, since the traffic comes from a node within the cluster the traffic is considered internal and externalTrafficPolicy doesn't apply. The reason is that kube-proxy installs some iptables rules that capture the traffic from within the node.
This causes a problem to test LoadBalancers, because it requires traffic to be sent from an external node, something that is not easy: Kubernetes cluster use to be isolated, expose apiserver endpoint e2e should not assume direct connectivity from the e2e binary
we can see it preserves the source ip