Skip to content

Instantly share code, notes, and snippets.

@lg
Last active April 11, 2024 07:44
Show Gist options
  • Save lg/6f80593bd55ca9c9cf886da169a972c3 to your computer and use it in GitHub Desktop.
Save lg/6f80593bd55ca9c9cf886da169a972c3 to your computer and use it in GitHub Desktop.
Add tailscale to an EdgeRouter and surviving system upgrade

Adding tailscale to an EdgeRouter (and surviving system upgrades)

I suggest you run sudo bash on all of these so you're the root user.

Installing

  1. Download tailscale and put the files in /config/. Find the latest stable or unstable version for your EdgeRouter's processor (ex. ER4 is mips and ERX is mipself)
sudo bash    # if you havent already
curl https://pkgs.tailscale.com/unstable/tailscale_XYZ_mips.tgz | tar xvz -C /tmp
cp /tmp/tailscale_*/* /tmp/tailscale_*/systemd/* /config/
  1. Create the /config/scripts/firstboot.d/tailscale.sh file which gets run once every system upgrade. Reminder that /config survives upgrades. Don't forget to set the execute flag on the script inside firstboot.d
cat << EOF > /config/scripts/firstboot.d/tailscale.sh
#!/bin/sh
ln -s /config/tailscaled.service /lib/systemd/system/tailscaled.service
ln -s /config/tailscaled.defaults /etc/default/tailscaled
ln -s /config/tailscale /usr/bin/tailscale
ln -s /config/tailscaled /usr/sbin/tailscaled
mkdir -p /var/lib/tailscale/
touch /config/auth/tailscaled.state
chmod 0400 /config/auth/tailscaled.state
ln -s /config/auth/tailscaled.state /var/lib/tailscale/tailscaled.state
systemctl enable --now tailscaled
EOF
chmod +x /config/scripts/firstboot.d/tailscale.sh
  1. And run this script now to get things going (or manually run the commands if you'd like), and then run tailscale up to login. Feel free to use other parameters like tailscale up --advertise-routes=10.0.1.0/24
/config/scripts/firstboot.d/tailscale.sh
tailscale up
  1. That's it, you're done! If you found this useful, i'd super appreciate if you could Star up top. Like everyone, I like Internet points too! :)

 

Upgrading to a new version

  1. Download the version you want into a folder like /tmp and then copy the binaries over. Perhaps in future versions there may be more/less files or config changes, so make sure you take a look at what's now.
sudo bash    # if you havent already
curl https://pkgs.tailscale.com/unstable/tailscale_XYZ_mips.tgz | tar xvz -C /tmp
systemctl disable --now tailscaled
cp /tmp/tailscale_*/{tailscale,tailscaled} /config/
systemctl enable --now tailscaled

 

Removing

  1. Stop the service if its still running
sudo bash    # if you havent already
systemctl disable --now tailscaled
  1. Delete all the files tailscale uses
rm /lib/systemd/system/tailscaled.service
rm /etc/default/tailscaled
rm /usr/bin/tailscale
rm /usr/sbin/tailscaled
rm -rf /var/lib/tailscale
  1. Remove your configs and persistent files (this includes your tailscaled.state which has your private key)
rm /config/tailscale*
rm /config/auth/tailscaled.state
rm /config/scripts/firstboot.d/tailscale.sh
@rtrainer
Copy link

Is this for EdgeOS v1.x or v2.x?

@lg
Copy link
Author

lg commented Dec 29, 2020

Is this for EdgeOS v1.x or v2.x?

this is on 2.x (EdgeRouter.ER-e300.v2.0.9.5346345.201028.1647). are people keeping legacy firmware on these things?

@rtrainer
Copy link

LOL...Just checking as there are people that have not moved to v2.x

@joeshaw
Copy link

joeshaw commented Dec 31, 2020

I made a couple tweaks locally.

I moved all the tailscale stuff into a /config/tailscale directory that has the same directory structure as the tarball.

#!/bin/sh
ln -s /config/tailscale/systemd/tailscaled.service /etc/systemd/system/tailscaled.service
ln -s /config/tailscale/systemd/tailscaled.defaults /etc/default/tailscaled
ln -s /config/tailscale/tailscale /usr/bin/tailscale
ln -s /config/tailscale/tailscaled /usr/sbin/tailscaled
mkdir -p /var/lib/tailscale/
touch /config/auth/tailscaled.state
chmod 0400 /config/auth/tailscaled.state
ln -s /config/auth/tailscaled.state /var/lib/tailscale/tailscaled.state
systemctl enable --now tailscaled

This way, when a new release comes out, I can do:

$ sudo mv /config/tailscale /config/tailscale-prev
$ sudo mv tailscale_1.3.95_mips /config/tailscale

and in general reduces clutter in the main /config directory.

@ovizii
Copy link

ovizii commented Jan 20, 2021

does anyone know if the same procedure also works on the UDM (not the pro one though)?

@sashkavas
Copy link

sashkavas commented Jan 22, 2021

ovizii, I managed to make it work on Unifi USG3&Pro and presume it should work on UDM/Pro as well. The issue with lg’s instructions above is that USG uses the old way of starting services and does not support systemctl. I spend few hours trying to make it work and start tailscaled as a service, but in the end, I gave up. Instead, I have modified the script to start tailscaled as a background process to open the tun and then initiate tailscale connection. Here is what you should do:

  1. if you have not done so go to www.tailscale and create new user and logon.
  2. shh to USG and execute sudo su
  3. Install MIPS talscale version following lg’s instructions as described above
  4. create the tailscale.sh script in root home directory (you can create it wherever you whish given you know where it is)
#!/bin/sh
ln -s /config/tailscale /usr/bin/tailscale
ln -s /config/tailscaled /usr/sbin/tailscaled
mkdir -p /var/lib/tailscale/
touch /config/auth/tailscaled.state
chmod 0400 /config/auth/tailscaled.state
ln -s /config/auth/tailscaled.state /var/lib/tailscale/tailscaled.state
sudo tailscaled > /dev/null 2>&1 &
disown
sudo tailscale up --advertise-routes=192.168.X.0/24 --accept-routes 

where 192.168.X.0/24 is the internal LAN network behind your USG, which you would like to be accessible by all other tailscale hosts (say you logon to tailscale using your phone or tablet and want to see all you computers, like NAS, hubs etc. from your local network). You can skip “--advertise-routes=192.168.X.0/24” option if you do not want to expose any internal networks, or you can add multiple subnets/vlans by separating them with commas.

  1. chmod +x tailscale.sh to make it executable (presuming you are in the same directory where the script is)
  2. create /config/scripts/post-config.d directory if it does not exists and copy the tailscale.sh script in there! This is necessary since we do not start "tailscaled" as a service, but as a background process and which needs to be started each time after system reboots/provisions (and it should survive system upgrades as well).
  3. run the script by “./tailscale.sh”. If this is the first time you logon from this USG you will be asked to authenticate by getting a link that you need to paste in you browser and logon using your tailscale credentials. To check if everything go back to your shh console and run execute “tailscale status”. If all is OK you should see all other hosts in your tialscale network as well information about their IP addresses and networks they expose.
  4. Open your web browser and go to tailscale, logon and open your admin console. If all is OK you should see your USG as a new host, click the 3 dots on the right and disable key expiry and accept subnet routes you are exposing by clicking “review subnet routes” and enable the exposed subnet route(s).

This is all you need to do for a single USG, which will make sure that your USG opens persistent connection to your tailscale network, which survives provisions/reboots/upgrades.

If you have two sites managed by USG you can build taiscale/wireguard VPN tunnel between them, by installing tailscale on both USGs following the instructions above for each of the USGs, where the only difference being the internal networks that each USG is exposing, say USG1 exposes 192.168.X1.0/24, while USG2 exposes 192.168.X2.0/24, then you need to modify the last line in the script respectively. Next to it you need to add a static route in each of the USGs telling the rest of the hosts in the respective local networks how they can find hosts in the other network. To do so, for each of the USGs you need to logon in their respective Unifi controllers via the web interface, select the site where respective USG is sitting and go to routing & firewall section. There you need to add a new static route: say you at USG1 site, then you need to create new static route for 192.168.X2.0/24 network with a next hop being the tailscale IP address of USG1 (which you can see in tailscale admin console). You can do similar thing for USG2, where you add static route for 192.168.X1.0/24 network with next hop being the tailscale IP address of USG2. After your USGs get provision, both local networks should be able to see each other as if you have created automatic IPsec site-to-site VPN, with advantage being that the connection will be much faster and secure and that both USGs can reside on two different Unifi controllers.

@blumberg-git
Copy link

1.4 update is throwing errors:
2021/01/27 21:52:03 GotNotify: Version mismatch! frontend="1.4.0-t3d7cff91b-g62ff3b5c4" backend="1.2.10-te480f8ddf-g7b8c9553a"
2021/01/27 21:52:03 GotNotify: Version mismatch! frontend="1.4.0-t3d7cff91b-g62ff3b5c4" backend="1.2.10-te480f8ddf-g7b8c9553a"

@dtel
Copy link

dtel commented Feb 12, 2021

Issues on UDM using v1.4.3. After executing sudo tailscale up --advertise-routes=192.168.1.0/24 --accept-routes i do not get a url to authenticate, but just blocks and prints nothing. I have tries adding tskey, but facing same issue.

Looked at tail scaled logs and getting a batch of errors:

control: authRoutine: backoff: 30573 msec
logtail: dial "log.tailscale.io:443" failed: dial tcp 34.210.105.16:443: connect: network is unreachable (in 1ms)
logtail: upload: log upload of 12664 bytes compressed failed: Post "https://log.tailscale.io/c/tailnode.log.tailscale.io/103733847adf5a4cdd580c6773e6985700820d8b5dcb24123d023c3e6f8b684c": dial tcp 34.210.105.16:443: connect: network is unreachable
logtail: backoff: 43662 msec
control: authRoutine: state:authenticating; wantLoggedIn=true
control: direct.TryLogin(token=false, flags=0)
control: doLogin(regen=false, hasUrl=false)
Received error: TryLogin: fetch control key: Get "https://login.tailscale.com/key": dial tcp [2a05:d014:386:203:f8b4:1d5a:f163:e187]:443: connect: network is unreachable
control: authRoutine: backoff: 22231 msec
control: authRoutine: state:authenticating; wantLoggedIn=true
control: direct.TryLogin(token=false, flags=0)
control: doLogin(regen=false, hasUrl=false)
Received error: TryLogin: fetch control key: Get "https://login.tailscale.com/key": dial tcp [2a05:d014:386:203:f8b4:1d5a:f163:e187]:443: connect: network is unreachable
control: authRoutine: backoff: 29072 msec
logtail: dial "log.tailscale.io:443" failed: dial tcp 34.210.105.16:443: connect: network is unreachable (in 17ms)
logtail: upload: log upload of 12664 bytes compressed failed: Post "https://log.tailscale.io/c/tailnode.log.tailscale.io/103733847adf5a4cdd580c6773e6985700820d8b5dcb24123d023c3e6f8b684c": dial tcp 34.210.105.16:443: connect: network is unreachable
logtail: backoff: 37215 msec

Please assist.

@sashkavas
Copy link

I had the same issue with v1. 4.3 on USG, routes were not advertised. So, I have reverted back to v1.2.10, which works quite stable for now.

@sashkavas
Copy link

sashkavas commented Feb 16, 2021

Just installed version 1.6.0 on 2 USG and for now all works fine including routes. To update:
ssh to USG/UDM and

  1. sudo su
  2. curl https://pkgs.tailscale.com/stable/tailscale_1.6.0_mips.tgz | tar xvz -C /tmp
  3. cp /tmp/tailscale_1.6*/{tailscale,tailscaled} /config/
  4. reboot

NB. 1.4.4 also worked fine for about 1.5 months without a crush. Quite pleased so far and much better when compared with defualt USG IPSec

@ecard0
Copy link

ecard0 commented Aug 4, 2022

Any reason why you are not using the mips64 version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment