Another weekend project.
In short, this is like ngrok, or like so many other tunneling softwares out there. But I got bored, so here we are.
WARNING: NO TESTS, NO LUBE, WORKS FOR ME, USE AT YOUR OWN RISK
See example.config.yaml
for reference. You will need to generate your own CA and peer certificates. However, client/gateway TLS will be issued via Let's Encrypt, so there will be no need for configurations on the client side.
t
uses Hashicorp's:
- memberlist for peer discovery, state synchronization (updating the peer graph), and failure detection.
t
also uses the following for multiplexing:
t
supports these protocols for creating logical streams between peers and clients, and clients can be connected to any one of the peers, and the gateway on any of the peers will route the HTTPS request to the client's forwarding port.
Because of the architecture, peers and clients can be connected to each other with different protocols. This allows for complex networking environments where some peers are not able to communicate via QUIC because of buggy cloud firewall configuration, while other peers are able to communicate via QUIC.
The peers have to be publicly accessible on the Internet (they are the gateway, after all).
- First you need a publicly accessible host. You can run one for $5 a month or cheaper from your favorite cloud/vps providers;
- Configure RFC2136 settings. This is for completing the
dns-01
challenge for Let's Encrypt as we will be requesting for wildcard certificate; - Configure the rest of
config.yaml
, then run theserver -config config.yaml
with your favorite manager (e.g. Systemd); - Run
t-client-${GOOS}-${GOARCH} tunnel -where tunnel.example.com -forward http://127.0.0.1:3000
, and you should see a FQDN hostname ready to be used to tunnel HTTPS request to your apps running locally.
NAME:
client - t tunnel client for amd64 on linux
USAGE:
client [global options] command [command options]
VERSION:
dev
DESCRIPTION:
like ngrok, but ambitious
COMMANDS:
tunnel Create a new tunnel to an application of your choosing
connect Proxy TCP connection through the tunnel via stdin/stdout
forward Listen for connections locally and forward them via the tunnel
GLOBAL OPTIONS:
--debug Enable verbose logging and disable TLS verification (default: false)
--help, -h show help (default: false)
--version, -v print the version (default: false)
COPYRIGHT:
Rachel Chen (@zllovesuki), licensed under MIT.
You will need Go 1.17+ for non-Android targets. Building for Android requires NDK and Go 1.16.x.
# building the server
CGO_ENABLED=0 go build -tags 'osusergo netgo' -ldflags '-s -w -extldflags "-static"' -a -o bin/server ./cmd/server
# building the client
CGO_ENABLED=0 go build -tags 'osusergo netgo' -ldflags '-s -w -extldflags "-static"' -a -o bin/client ./cmd/client
This will build static binary ready for distribution.
- Configure your
config.yaml
, firewall rules, peer certificates, etc, then use Let's Encrypt staging environment on one node and start the server. - If it created a new account and requested a new certificate, your configuration is good to go!
- Remove the
accounts.json
andbundle.json
, as they are for testing only. - Change the Let's Encrypt dirctory to
production
, then start the first node again. - Depending on your DNS, it may fail authorization for the initial tries. However, once the cert has issued successfully, you can now start up other nodes one by one.
- They will be synchronized on startup. The client and gateway now should see a valid certificate issued by Let's Encrypt.
- You can run just one node as well. Clustering is optional.
- Write the damn tests
Makenow withclient
command less painful to use-where
auto discovery- Multi-peer support from the client for HA. The plumbing is there to support it.
- Make leader determination and ACME management less painful