tproxy-pod

command module
v0.0.0-...-76e8ecf Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2024 License: Apache-2.0 Imports: 19 Imported by: 0

README

tproxy-pod

Container that implements a transparent TLS direct and reverse proxy to be used as a sidecar solution to implement mTLS across Pods.

** NOTE: Not Service mesh, this is just about mTLS between Pods **

 bin/tproxy -h
Usage: tls-tproxy [options]

  -cert string
        certifcate
  -key string
        certificate key
  -tcp-port int
        port to listen on TCP (default 1)
  -tls-port int
        port to listen on TLS (default 2)
  -v value
        number for the log level verbosity

The container requires CAP_NET_ADMIN privileges and uses multiple technologies in the Kernel to transparently proxy mTLS:

The proxy implements two behaviors:

  • Ingress traffic to the Pod: The traffic is transparently redirected on the ingress path (netfilter PREROUTING hook) to the mTLS proxy (TPROXY) that listens by default on the TCP port 2. After doing the TLS handshake, the content is proxied to the internal application. TODO: This is not yet conserving the original IP, so the end application sees the connection from the Pod.

  • Egress traffic from the Pod: The traffic that is originated inside the Pod namespace and destined outside is recirculated on the OUTPUT path (ip rule fwmark 0xa) so it can be transparently redirected to the TCP proxy (TPROXY) that listens by default on the TCP port 1. The proxies initiates the mTLS connection with the destination, and if succesful it forwards the connection from the client.

TODO

  • Retain source IP and Port on the Ingress traffic
  • Webhook injection example
  • Do a proper demo with certificates mounted on the Pod and associated to the Service account, per example https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
  • UDP support
  • Filter to apply mTLS to a specific set of addresses
  • Handle TCP And HTTP kubelet probes
  • Run TCP benchmarks encrypted vs un-encrypted
  • IPv6

References

Demo

  1. Install a kubernetes cluster, in this case we are using kind
kind create cluster
  1. Install the tproxy-pod using the manifest in this repo
make kind-image

or

kubectl apply -f install.yaml

The manifest will install two pods, each Pod contains a webserver and a sidecar container with the mTLS proxy

  1. Install a pod with an https webserver
kubectl apply -f https://gist.githubusercontent.com/aojea/38c6ec34141882c0664caafa50db33ad/raw/961cbff7eac8121cad928bb2085eff9f6031123b/https.yaml
  1. Check the IPs assigned to the Pods
kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
https-server-7585448b5c-s8lrj   1/1     Running   0          3h39m   10.244.2.21   kind-worker2   <none>           <none>
tproxy-6bfccf88fb-sq789         2/2     Running   0          68m     10.244.1.24   kind-worker    <none>           <none>
tproxy-6bfccf88fb-sv75h         2/2     Running   0          68m     10.244.2.26   kind-worker2   <none>           <none>
  1. Check that from one application pod inside the tproxy-pods we can reach: Internet, the https-server, the other tproxy Pods and the internal application
$ kubectl exec -it tproxy-6bfccf88fb-sq789 -c app bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

bash-5.0# curl www.google.es
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos a

In this test the certificates are only allowing localhost, so all the other mTLS connections in the Pod fail with the following error

$ kubectl exec -it tproxy-6bfccf88fb-sq789 -c app bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

bash-5.0# curl http://10.244.2.21:443/clientip
curl: (56) Recv failure: Connection reset by peer
$ kubectl logs tproxy-6bfccf88fb-sq789  -c proxy

I0729 15:34:17.034015       1 main.go:211] Accepting TCP connection from 10.244.1.24:42018 with destination of 10.244.2.21:443
I0729 15:34:17.034036       1 main.go:220] Connecting to [10.244.2.21:443]
I0729 15:34:17.036041       1 main.go:224] Failed to connect to original destination [10.244.2.21:443]: tls: failed to verify certificate: x509: certificate is valid for 127.0.0.1, ::1, not 10.244.2.21
$ kubectl logs tproxy-6bfccf88fb-sq789  -c proxy

curl http://10.244.2.26/clientip
curl: (56) Recv failure: Connection reset by peer
I0729 15:44:26.823295       1 main.go:211] Accepting TCP connection from 10.244.1.24:52044 with destination of 10.244.2.26:80
I0729 15:44:26.823320       1 main.go:220] Connecting to [10.244.2.26:80]
I0729 15:44:26.825429       1 main.go:224] Failed to connect to original destination [10.244.2.26:80]: tls: failed to verify certificate: x509: certificate is valid for 127.0.0.1, ::1, not 10.244.2.26
  1. Check that an external connection to the exposed app uses TLS
root@kind-worker:/# curl -k https://10.244.1.26:80/clientip
curl: (56) OpenSSL SSL_read: OpenSSL/3.0.11: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0

root@kind-worker:/#  curl  http://10.244.1.24:80/clientip
curl: (52) Empty reply from server

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL