Note: I built a self-hosted tailscale setup solution for the purpose of being able to use an external network at the office and still be able to use it remotely very simply.
What is Tailscale?
Tailscale is a VPN service that makes the devices and applications you own accessible anywhere in the world, securely and effortlessly. It enables encrypted point-to-point connections using the open source WireGuard protocol, which means only devices on your private network can communicate with each other.
What is ionscale?
While the Tailscale software running on each node is open source, their centralized "coordination server" which act as a shared drop box for public keys is not.
ionscale aims to implement such lightweight, open source alternative Tailscale control server.
First, we need to configure the DNS of 1 public domain/subdomain to the IP VPS address we will use to deploy this solution.
You can use dig to make sure that DNS records are propagated:
dig ionscale.example.com
Next, you need to rename the ionscale configuation located in the ./ionscale
folder:
mv config.yaml.example config.yaml
Modify this config to your options setup:
listen_addr: ":443"
public_addr: "ionscale.example.com:443" # change to your domain/subdomain
stun_public_addr: "ionscale.example.com:3478" # change to your domain/subdomain
tls:
acme: true
acme_email: "[email protected]" # not required
keys:
system_admin_key: "sha256(randomstring)" # Ex: tr -dc A-Za-z0-9 </dev/urandom | head -c 13 | sha256sum
database:
url: "/data/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
logging:
level: info
Modify file docker-compose.yml:
...
environment:
- PUBLIC_ADDR= # public address in public_addr
- WARP_LICENSE_KEY= # License key for Warp+ (not required)
...
environment:
- PUBLIC_ADDR= # public address in public_addr
Next, i created the file ./run.sh by mistake and optimizes it when you execute it into the container
chmod +x ./run.sh
./run.sh init
Next, before creating an auth key, you need to create a tailnet first:
./run.sh tailnet create <name for tailnet>
Ex:
./run.sh tailnet create troller
Once we have created the tailnet, we will now create auth key mapping into that tailnet
./run.sh auth create <name for machine> <name for tailnet>
Ex:
./run.sh auth create warp-exit-node troller
./run.sh auth create nord-exit-node troller
Once you have auth, you can authenticate for 2 urls https://ionscale.example.com/a/r/<string>
To see the machines that have joined the tailnet:
./run.sh auth list <name for tailnet>
Ex:
./run.sh auth list troller
Now need to enable exit-node for 2 machines: warp, nordvpn
./run.sh enable_exit_node <ID of machines>
Ex:
./run.sh enable_exit_node 117216020300564994
./run.sh enable_exit_node 117216000016910850
Finally, you need to enable nordvpn
chmod +x nord.sh
./nord.sh login
Here i have configured Nordvpn's manual login, without 2FA to create API Token on the dashboard
Visit the url and login your Nordvpn account there
You copy the callback link that Nordvpn returns containing the exchange token for you
./nordvpn login --callback "nordvpn://login?action=login&exchange_token="
Connect vpn:
./nord.sh connect Vietnam
Now you can use your personal computer and join these tailnet networks
- Windows: https://github.com/juanfont/headscale/blob/main/docs/windows-client.md
- Linux:
tailscale up --accept-dns=true --accept-routes=true --login-server=https://ionscale.example.com
https://support.nordvpn.com/hc/en-us/articles/20465811527057-How-to-build-the-NordVPN-Docker-image