The tailscale.com/tsnet package in Go [1] is really useful if you've not looked at it before: you can make single binary HTTP or whatever servers that are only exposed inside your tailnet.
Their golink project [2] is a good example (and useful itself), but I've used it to build "peer to peer" comms for one application, and to host an API and Svelte SPA to control some other things in a tailnet.
Check out OpenZiti - https://openziti.io/. It looks like Tailscale but is open source, takes zero trust principles to its logical conclusion, and includes a whole suite of SDKs (alongside host based tunnelers and VMs) making it super easy to embed private, obsfucated, secure connectivity directly into your apps. Heck, you don't even need listening ports on the host OS network, therefore you app cannot be found or attacked from network/IP. Here is a good blog using Go SDK as an example - https://blog.openziti.io/go-is-amazing-for-zero-trust
If you're a rust fan we make a similar library, that's all-in on "p2p-QUIC", with pre-baked protocols to import on top: https://github.com/n0-computer/iroh
That’s super cool, I was going to say “nat punching and public relays are a requirement for me” but you already do that! Definitely filing this away for future projects.
How difficult it is to use? Right now I’m working on orchestrating dev-local service clusters here I bind plenty of hosts to mimick real world. I’m using proxy tunneling to punch in but I’d love to have Tailscale endpoint which I could use to connect external devices (like mobile clients or non-technical stakeholders for show and tell).
It’s pretty simple, I’ve not updated my package version in a while but iirc you give it a state directory, an auth key, and you get a Dial-like interface you can use with the stdlib http libraries
I've been using Tailscale for awhile now and even developed a few internal apps using tsnet as well but I had no idea about golink and it's awesome. Thanks for sharing that!
You don't actually need tsnet for that. tailscale cli itself running the subcommand serve will allow you to share a specific port on your machine either with your tailnet or use funnel and share it out to the internet.
I pulled tsnet out of my go application and switched entirely to `tailscale serve` and just use the header that adds to auth my family into apps I write. I love it.
funnel and serve are also awesome, but in this case the use case necessitated a single binary that worked without the full package installed/didn’t touch the routing table or tun device
I've been using tailscale/tailscale-caddy[1] successfully to serve applications only on my tailnet. It says highly experimental, but it's worked just fine for me.
Absolutely. You can run a go process that becomes a Tailscale client without any other dependencies. This is what I use it for issuing JWT for service authentication: https://github.com/AltaCoda/tailbone
For replacing port forwarding, OpenZiti definitely works. zrok, which is built on top of OpenZiti, could also be a great option for sharing resources - https://zrok.io/
Their golink project [2] is a good example (and useful itself), but I've used it to build "peer to peer" comms for one application, and to host an API and Svelte SPA to control some other things in a tailnet.
[1] https://pkg.go.dev/tailscale.com/tsnet
[2] https://github.com/tailscale/golink