As I’ve written in previous posts, I really like WireGuard as a means to securely connect networks. Recently I’ve been using Tailscale a lot more. Tailscale makes WireGuard even easier than it already is and provides additional security: key rotation and single sign-on.

While I’ve been using it on each of my systems - Linux, macOS, and iOS, I wanted to shift the endpoint to the edge of my network to make connectivity a little bit easier.

At present, you can’t have simultaneous Tailscale logins, and I’m finding that I need to access a corporate network with Tailscale as well as my home playthings, so until simultaneous account logins are supported, this is my workaround.

My edge router at home is, aptly, a Ubiquiti EdgeRouter 4. Under the hood of the EdgeRouter is a MIPS CPU running a Linux-based operating system forked from VyattaOS. You can SSH in and turn all sorts of knobs not exposed via the web UI. Since Tailscale offers MIPS binaries (as well as ARM!) I can treat the router just like any Linux system and connect it to Tailscale.

These instructions are very similar to what you’d do to run Tailscale on an EC2 instance or other cloud-based system acting as a gateway.

Let’s go about making the EdgeRouter a gateway for external systems to access internal networks:

  1. SSH to the EdgeRouter and download the latest MIPS binaries:
$ ssh you@router
router$ curl https://pkgs.tailscale.com/unstable/tailscale_1.7.403_mips.tgz -o tailscale.tgz
  1. Extract the package:
router$ tar xzvf tailscale.tgz
  1. Relocate files to proper locations on the router and create directories needed for log data and runtime socket file:
router$ sudo bash
router# cd tailscale_1.7.403_mips
router# mv tailscale* /usr/sbin
router# mv systemd/tailscaled.service /etc/systemd/system
router# mv systemd/tailscaled.defaults /etc/default/tailscaled
router# mkdir /var/lib/tailscale /run/tailscale
  1. Start it up! Pay close attention to line 2, where we’re passing subnet routes. This list (comma-separated) is a list of networks you want other clients to be able to reach via this router:
router# systemctl enable --now tailscaled
router# tailscale up --advertise-routes=192.168.0.0/24

When you start Tailscale, it’ll present you with a URL to visit that allows you to authenticate the device to your Tailscale account. Once you do this, your router will show up under the “Machines” list in the admin UI.

If you’ve made it this far, you should be able to ping other Tailscale nodes bidirectionally. There’s one step left to get those routes propagated to other Tailscale clients: head to the Tailscale admin interface, find the router you just configured, and click “Enable Subnet Routes” from the “…” menu on the far right. You’ll also want to disable key expiry, or your router will eventually stop communicating.

Once you enable subnet routes, you should try to ping something on the exposed subnet (in this example, 192.168.0.x) - it should work! If your clients are Linux, you’ll have to explicitly accept routes by running tailscale up --accept-routes as accepting routes is disabled by default.

If you’d like hosts behind the EdgeRouter to communicate to other Tailscale clients outside the local network, you’ll want to add a NAT so that traffic knows where to go (without one, you’ll only have inbound access to devices on the network). To do this, you can add it via CLI:

router$ configure
router# set service nat rule 5012 description Tailscale
router# set service nat rule 5012 outbound-interface tailscale0
router# set service nat rule 5012 protocol all
router# set service nat rule 5012 type masquerade

…or find it in the Ubiquiti web UI under “Firewall/NAT” and click a few options. The tailscale0 interface will not show up in the dropdown list, so you must choose “Other” and type in tailscale0.

Finally, Tailscale has a new feature that allows for any Tailscale instance to serve as an “exit node”, which allows you to tell your Tailscale client to send all otherwise-public traffic to a specific node which will then NAT your traffic out to the Internet. Using an exit node makes sense if you’re at a hotel, coffee shop, or other untrusted network - or if you just want to source your traffic from a different network. In order to tell clients that a particular node is willing to handle traffic as an exit node, you need to pass the flag --advertise-exit-node in addition to any other flags you pass to the tailscale up command. You’ll also need to toggle it as an exit node from the Tailscale Admin UI.