datalink_relay is a library written in go for the purpose of allowing servers behind a firewall to listen for connections on an untrusted relay server. The library exports the net.Listener and net.Dialer interfaces for convenience of use, for servers and clients.
- Relay starts listening for connection/listen requests
- Server registers a listen request with Relay and maintains persistent connection
- Client registers connect request at Relay and waits on request
- Relay forwards Client's connection request to Server over persistent connection
- Server dials back to Relay
- Relay completes connection and starts forwarding data
Note: MTLS secures the data connection (step 6) end-to-end, so the relay only ever sees ciphertext. The control messages with the relay are plaintext by default, but the routing metadata (client/server IDs) can optionally be sealed to the relay's public key so on-path observers cannot see who is connecting to whom (the relay still reads it in order to route). See WithRelayKey.
The server's long-lived registration connection to the relay can additionally be moved onto an mTLS control endpoint, which encrypts it and lets the relay verify that a server is entitled to the id it registers. See WithRelayControlTLS.
Go 1.25 or newer.
-
From the project root directory run:
go build -o bin/ ./... -
The compiled executables will be in the bin/ directory
-
Now from 3 separate terminals run in order:
./relay ./server ./client
-
The client will echo single words back via the terminal
To run a basic demo in a single executable run ./all. It runs all three entities at once and has a few clients print basic messages at the server. Instructions for the MTLS versions are similar. Note that all demos run on localhost with hardcoded values that can be found here.
Documentation of the public facing API can be found here.