This repository include development shell (using nix develop) in which it is easy to test how apiserver-network-proxy components works and how to reuse them in own code.
To run development shell locally first nix have to be installed locally. Even the included flake.nix provides reproducible builds, to properly simulate environments it depends on presence of network namespaces and iptables which are available on linux environments.
clients/ dir contains example go implementation of grpc/tcp clients which dials into proxy server and pass net.Conn interface to private ns endpoint connection constructor. This article in my opinion is a good description of tunnel approach. Clients will be available in development shell as proxy-grpc
and proxy-tcp
.
services/ dir contains example rust implementation of grpc and tcp servers. They will be available in development shell as endpoint-grpc
and endpoint-tcp
.
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ │ │ │
│ ┌────────────┐ │ │ ┌───────────┐ │
│ │proxy-server├────┼────────────────────tunnel (grpc / http)───────────────────┼─┤proxy-agent├──────┐ │
│ └───▲───▲────┘ │ │ └─────────┬─┘ │ │
│ │ │ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ │
│ │ │ │ │ │ │ │ │ │ ┌──────▼──────┐ │
│ ┌───────────┐ │ │ │ │ 10.10.10.1│ │10.10.10.2 │ │ │ │grpc-endpoint│ │
│ │grpc-client├─┘ │ x─────┼────┼────x x────┼───┼─────x x────┼────┼────x │ └─────────────┘ │
│ └───────────┘ │ 2.2.2.2│ │2.2.2.1 │ │ 192.168.1.1│ │192.168.1.2│ │
│ │ │ │ │ │ │ │ │ ┌─────────────┐ │
│ ┌───────────┐ │ │ │ netns rtr-pub │ │ netns rtr-priv │ │ └─►http-endpoint│ │
│ │http-client├─────┘ │ └──────────────────────┘ └──────────────────────┘ │ └─────────────┘ │
│ └───────────┘ │ │ │
│ │ │ │
│ netns public │ │ netns private │
└─────────────────────────────┘ └─────────────────────────────┘
Clone repo and enter directory
$ git clone https://github.com/michalskalski/demo-proxy-grpc
$ cd demo-proxy-grpc
Enter dev shell (install nix if you haven't done that yet)
$ nix develop
or if you using direnv and direnv-nix
$ direnv allow
Create setup consisting of public and private network namespaces (and two extra ns simulating internet connections)
prepare.sh -r
it will create four network namespaces
$ ip netns ls
public
private
rtr-pub
rtr-priv
verify that you can connect from private namespace to public
$ in_ns.sh private ping -c 1 2.2.2.2
but not from public to private
in_ns.sh public ping -c 1 192.168.1.2
start proxy server in public ns
in_ns.sh public proxy-server $PROXY_SERVER_CERTS --mode http-connect
run proxy agent in private ns, it will connect to proxy server and create a tunnel which will allow communication from public to private
in_ns.sh private proxy-agent $PROXY_AGENT_CERTS --agent-id demo --proxy-server-host 2.2.2.2
run grpc endpoint in private ns
in_ns.sh private endpoint-grpc -a 192.168.1.2 -p 4001
and try to reach it from public using proxy server
in_ns.sh public proxy-grpc $PROXY_CLIENT_CERTS --request-host 192.168.1.2 --request-port 4001 --request-client-name demo
run tcp endpoint in private ns
in_ns.sh private endpoint-tcp -a 192.168.1.2 -p 8080
and try to reach it from public using proxy server
in_ns.sh public proxy-http $PROXY_CLIENT_CERTS --request-endpoint http://192.168.1.2:8080/ok
run dnsmasq in private ns to test requesting endpoint by it local dns name
in_ns.sh private dnsmasq -d -q -a 192.168.1.2 --host-record=local-server.svc,192.168.1.2
verify it resolves in private ns
in_ns.sh private nslookup local-server.svc
but not in public ns
in_ns.sh public nslookup local-server.svc
because name resolution happen on agent end it still should be possible to request endpoint by dns name from public ns
in_ns.sh public proxy-http $PROXY_CLIENT_CERTS --request-endpoint http://local-server.svc:8080/ok
once you finished you can run cleanup
prepare.sh -c