How to Use a Tailscale VPN to Embrace Remote Work and Explore the World
Remote work has taken off since the COVID-19 pandemic and further spawned what some refer to as “digital nomads”. Many have begun to realize that for some positions, coming into the office is actually not necessary at all and perhaps even less productive than working from home. Moreover, it’s becoming apparent to some that they don’t necessarily need to stay at home every single day of the year. For some, that 12 days (or even 24 days) of PTO is not enough. So, why not switch it up and work from somewhere new, whether that be another state in the U.S. or a whole new country?
Why a self-hosted VPN?
Most companies have I.T. departments that monitor things like IP addresses and thus your location. One of the reasons for this monitoring is to ensure foreign intruders are detected and thwarted appropriately. Obviously it’s no one’s business where you’re working from, and all that really matters (and what your boss cares about) is that the work gets done. And so, the way we can appear somewhere that we truly aren’t is by using a VPN (virtual private network). But not just any VPN… you need to self-host your own VPN at your home. Developed I.T. departments will have software to detect commercial VPN providers by referencing a large list of pre-known IP addresses from companies like NordVPN. It’s also good to tunnel your traffic to avoid malicious snooping. You may also choose to host the server (or even a backup) at a nearby family member’s house, wherever you can achieve the fastest internet speeds.
How?
Basically, you will use your own travel router between your personal/work device and the local Airbnb/hotel’s internet router. On the travel router, you will use Tailscale or Wireguard as well as on the VPN server at home to host the “exit node” (Tailscale). Technically, Tailscale is not a VPN, but rather an overlay network where we route the internet traffic through our own IP address at home. Wireguard is the VPN protocol, which Tailscale uses. Using plain Wireguard is the preferred VPN method.
WireGuard Method (Recommended as primary VPN)
Equipment Needed:
- Server: GL.iNet Brume 2 (aluminum version, affordable, no Wi-Fi).
*GL.iNet Flint (Only if you want to replace your current home router)
**GL.iNet Flint 2 (max. Wireguard speeds) - Travel router: GL.iNet Beryl AX (~$90) or Slate AX (if you need extra LAN port)
Wireguard GL.iNet Setup Tutorial
However, given that a regular Wireguard server has the ability to be blocked or not work at all for some users (those with home networks behind CGNAT), Tailscale is the option that will be described here.
Note that in some cases, the connection to your Tailscale server will not be direct, but will need to use one of Tailscale’s “DERP” relay servers, which will throttle your internet speeds and add some latency to your connection. Additionally, in the case of a DERP-relayed connection, if one were to run a “traceroute” on your connection, they would see the public DERP relay server IP address, since it is routing your traffic in the middle. This IP obviously belongs to a commercial/enterprise IP block, but it’s only visible by running a traceroute which is able to see every “hop” your traffic makes. Whether or not your employer’s telemetry would pick up on this is what would determine whether this method would still work for you or not. There are a few last ditch effort things you can do to try get peer-to-peer direct connection as opposed to relay servers. For more information on bare Wireguard vs. Tailscale use-cases, performance, and why I use Wireguard as my primary and Tailscale as my backup, see my other Medium article (5-min read):
A brief technical description on Tailscale: Tailscale IS Wireguard, but with some add-ons. Wireguard is the VPN protocol. You should read about Wireguard’s known limitations, specifically the fact that it is subject to detection via Deep Packet Inspection (DPI) via its packet headers. This is not really a concern for us since we use a travel router which doesn’t allow the Wireguard packet headers to be seen by the work VPN client’s DPI. Additionally, DPI still isn’t used that often except for sophisticated I.T. departments such as ones in FAANG companies. A few nice advantages of Tailscale are that we don’t have to port forward on our home router nor use a dynamic DNS (DDNS) service to prevent a dynamic public IP at home from killing our server connection; Tailscale handles all of this for us. While using bare Wireguard is still recommended and will have better performance (throughput) all of the time, reasons to choose Tailscale include:
- The local firewall you connect to while traveling blocks your Wireguard port (default: 51820)
- Your home ISP uses CGNAT, which would NOT allow bare Wireguard to work. Cellular network providers also often use CGNAT. In cases where either end of the connection (client or server) uses CGNAT, Tailscale would still work but it would use the previously mentioned public DERP relay servers (reducing your throughput unfortunately due to throttling).
- You do not have admin access to the primary ISP router, and thus cannot port foward.
Now, there is a way to host your own DERP relay server which would ensure full tunneling at nearly full performance through your home IP and without the use of any public servers, but it is a bit complex for someone inexperienced with networking.
NOTE: If your work laptop uses Zscaler or Cisco Umbrella for example, you will be likely be forced through these DERP relay servers and thus have a severely reduced internet speed and increased latency. For more information regarding VPN compatibility with Tailscale go here. For an alternative VPN method (increased difficulty level) to ensure a direct connection and full tunnel to your home VPN and the fastest speeds, follow this guide to setup a normal Wireguard VPN instead.
Before I continue with the technical implementation, a quick disclaimer: I am not liable for any troubles you cause yourself or your company including but not limited to: termination of employment due to policy violation, failure to obey tax compliance laws, protection of customer data, country data requirements in your respective country.
REMINDER: A regular Wireguard VPN server using a GL.iNet router is recommended for maximum performance. The following guide is for Tailscale only and is better as a back-up server, unless you are unable to port forward (i.e., home network behind CGNAT).
Equipment needed:
- Server: Raspberry Pi 4B or 5 (or any Linux “thin client” will do, $50–100). OR, you can now use Apple TV to host an exit node!
- Server (easier alternative): GL.iNet router (recommended model: Brume 2). Skip to Step 3.5
Note: Tailscale on GL.iNet devices is still in beta release. This is why for the server side, Raspberry Pi is preferred. For a how-to guide on a Wireguard VPN server w/ a GL.iNet router click here. - Storage: 32GB (or larger) micro SD card for Raspberry Pi
- Travel router: GL.iNet Beryl AX or Slate AX (if you need extra LAN port)
- Misc: Thunderbolt and/or USB-C Ethernet adapter for laptop (if required), 2–3 ethernet cables of varying sizes.
One cable for Pi <-> Home Router LAN, one cable for Laptop <-> Travel router LAN, and an optional 10ft cable for Travel router WAN <-> Local network router (at your Airbnb, hotel, etc.) - (Optional) Portable battery for powering your travel router on the go when a wall outlet is not accessible. And a fan for your Pi server.
The following models are compatible with Tailscale: GL-AX1800 (Flint), GL-A1300 (Slate Plus), GL-AXT1800 (Slate AX), GL-MT3000 (Beryl AX), GL-MT2500/GL-MT2500A (Brume 2) and GL-X3000 (Spitz AX).
A travel router is needed because we are unable to install 3rd party software, let alone a VPN client, onto our work machine. So we will connect the work computer to the travel router like a normal Wi-Fi network, and the router will point everything to our VPN server. Think of the travel router as a repeater that takes your Airbnb/hotel Wi-Fi network and re-broadcasts it to your device. Of course, we will only use a wired ethernet connection from the laptop to the travel router, never Wi-Fi as this can expose our location.
Basic steps:
1. Flash your microSD card using the official Raspberry Pi imager on your laptop or desktop.
Insert the microSD card into your laptop using whatever adapter necessary. Install the official Raspberry Pi Imager and go follow the steps to flash the OS to your microSD. Don’t forget these things:
- Choose Raspberry Pi OS (aka “Raspbian”) and select the 64 bit version (preferably non-desktop version)! (64 bit OS will give you ~44% faster throughput than 32 bit OS)
- Set hostname to “raspberrypi.local” to make logging in easier than remember the IP which you set later.
- Enable SSH in the Advanced Options!
- Configure your Wi-Fi network for the Pi to connect to, OR use internet sharing (Mac)
Once you finish flashing the microSD, insert it into the Raspberry Pi and power the Pi. Then, attach an ethernet cable between the Pi and your computer (you may need a Thunderbolt or USB-C to Ethernet adapter). Turn off Wi-Fi on your Mac so we can only connect to the Pi.
Navigate to your command prompt or terminal (on Mac/Linux, or for Windows open start menu and type “command prompt”) and connect to the Pi by running ‘ssh username@hostname’. Below, we use the default ‘pi’ username and the ‘raspberrypi.local’ hostname. Alternatively, you can use the Pi’s IP for the hostname assuming your laptop has a built-in DHCP server (it should).
ssh pi@raspberrypi.local
or if that doesn’t work (due to new the way the new Raspberry Pi OS works), use the Pi’s IP address:
ssh pi@your-Pi-IP-address
You can find the Pi IP address a number of ways. One way is to go into Network settings on Mac and view the IPv4 address on the Thunderbolt/Ethernet connection. Or type “ifconfig” in the terminal.
Note that as you type in the password you will not see the characters show on the screen. This is normal. If you are having problems with the SSH login, it’s possible you have a bad cable.
Once you’ve logged into the Pi via SSH, run the following:
systemctl enable ssh
systemctl start ssh
These two commands will permanently enable SSH on the Pi and start the service. This really shouldn’t be necessary since the imager should already run this for you, but it doesn’t hurt.
And lastly, disable Wi-Fi since we don’t need it and to reduce power draw.
rfkill block wifi
Simply re-run this command but with “unblock” if you wish to re-enable it ever.
2. Configure a static IP for the Raspberry Pi for an ethernet connection to your local network.
First, we need the subnet to match the local internet’s. So, verify whether your router at home uses 192.168.1.x or 10.0.0.x addresses (remember x is only 1–254). To do this, open a terminal window on your laptop connected to the Wi-Fi and type ifconfig and then look for the IPv4 addresses to the right of en0:. Alternatively, go to your network settings and view the IPv4 address. Also take note of the router IP, you will need that in a second.
Next, we will modify /etc/network/interfaces and add some code. Use your preferred editor by typing “sudo nano /etc/network/interfaces” or “sudo vi /etc/network/interfaces”.
Add the below block of code, where “??”, is any number (0–254) that is not a currently used IP on your network. Next, 10.0.0.1 is the IP of the Xfinity home router in my case. Replace this with whatever your router IP. This is set to both the gateway and dns-nameservers entries as shown below. 8.8.8.8 is an additional DNS entry and happens to be Google’s server.
#static IP address for eth0
auto eth0
iface eth0 inet static
post-up /sbin/ethtool --set-eee eth0 eee off
address 10.0.0.??
netmask 255.255.255.0
gateway 10.0.0.1
dns-nameservers 10.0.0.1 8.8.8.8
eth0 at the top specifies that we are using an ethernet connection to our router’s LAN port. Using an ethernet/wired connection to your home’s internet service ensures the fastest possible speeds.
Lastly, switch to standard Debian networking:
sudo systemctl enable networking
Reboot for the changes to take effect.
sudo reboot
Now, plug the Pi into one of your home router’s LAN port and ensure the green light is blinking.
3. SSH into your Raspberry Pi, install Tailscale, and enable exit node
Now that we’ve set a static IP for the Raspberry Pi and connected the Pi to the router, we should be able to access it by using SSH on the local network. Using your laptop (connected to the home Wi-Fi) open a terminal window and type:
ssh pi@raspberrypi.local
OR
ssh pi@static-IP-you-set (ex. 10.0.0.?? or 192.168.1.??)
If you are successfully able to access your Pi, then congrats for making it this far! If not, there could be a problem with the IP you set. Go verify your /etc/network/interfaces again.
We’re ready to install Tailscale on the server to create the VPN, or what Tailscale calls an “exit node”. To install on your Rasp Pi running Linux, simply run the following command:
curl -fsSL https://tailscale.com/install.sh | sh
If this doesn’t work, then determine the particular OS you are running on the Pi. If you don’t remember, simply run the command below and read the first line of hte output:
cat /etc/os-release
You’ll see the Linux distro name on your Pi. Using this info, try a manual install by following instructions here.
Once installed, follow the Tailscale documentation in order to set up your exit node. Be sure to select the “Linux” instructions in order to properly configure your Raspberry Pi’s operating system. Do Step 2 and Step 3: https://tailscale.com/kb/1103/exit-nodes/
Run the IP-forwarding commands:
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
NOTE: In Step 2 of the link above, run the command instead as:
sudo tailscale up --advertise-exit-node --accept-routes
This way we can allow the GL-iNet’s subnets which we will advertise in Step 5. If you missed this, don’t worry, you can always run this command again on your Pi later.
Once finished, give your Tailscale web admin panel a look-over to confirm everything is configured correctly as the documentation instructs. For example, click the 3 dots button all the to the right of the “raspberrypi” exit node and click on “Edit route settings…” and make sure exit node is switched ON.
Your Tailscale machines page should now show your Raspberry Pi and your Travel Router as such:
Don’t forget to click the 3 dots on the right side for both the Pi and the GL router and “disable key expiry” for both the Pi and your GL.iNet router. This is extremely important to ensure we maintain authenticated. For example, if the key expires on the exit node and you are out of the country, you will be unable to regenerate a key without manually being present at the Raspberry Pi.
In general, Tailscale documentation is very good so it’s good to refer to it often throughout the process.
3.5. (ONLY if using GL.iNet router as server/exit node)
Plug an ethernet cable between your personal laptop and the GL.iNet server router’s LAN port (keep Wi-Fi turned on so you have an internet connection). Then, open a browser tab and navigate to the gateway IP addresses that is written on the provided card.
Next, navigate to the Applications -> Tailscale.
Follow the binding instructions here:
Don’t forget to disable key expiry!
Once you’ve confirmed added the device to your Tailscale account, open up Terminal (on Mac/Linux), or if you’re on Windows open start menu and type “command prompt”:
- SSH into the router by running
ssh root@[ip or hostname of router]
(e.g.ssh root@192.168.8.1
). You can also use its tailnet IP or hostname assuming you’ve already connected it to your Tailscale account as shown later. - Enter your GL.iNet’s router password and hit enter/return
- Run this command to install “nano” editor.
opkg update && opkg install nano
- Edit the
gl_tailscale
config file by runningsudo nano /usr/bin/gl_tailscale
- Scroll down line 73 (as of
4.2.1
), which currently reads:/usr/sbin/tailscale up --reset $param --timeout 3s
- Add in
--advertise-exit-node
aftertailscale up
. It should now read:/usr/sbin/tailscale up --advertise-exit-node --reset $param --timeout 3s
- Save and exit by hitting your esc key, and typing Control+X and hitting “y” and your enter/return key
Restart your GL.iNet router (server) and verify that it’s available as an exit node by connecting back to your local Wi-Fi network checking in the Tailscale devices internet web admin page. You may need to enable it in “route settings”.
4. Connect to your GL.iNet travel router and configure it to point to your exit node
Once your exit node is live and all settings are correct based on Tailscale documentation, we can configure the travel router.
Simply connect an ethernet cable between the powered GL.iNet router’s LAN port and your personal laptop. Then, open a browser and type 192.168.8.1 to see the login screen.
Once you’ve logged in, enable the Repeater function on the “Internet” page, and connect the router to your cellphone hotspot or some Wi-Fi network other than the one you’re hosting the Raspberry Pi exit node off of.
Next, navigate to the Applications page and at the bottom enable Tailscale. If you don’t see Tailscale and/or the installation of the Tailscale plugin fails, try upgrading the firmware on your GL.iNet first.
Follow the binding instructions here:
Enabling Tailscale will allow us to force all Internet traffic coming into the router (i.e., from your work laptop) to pass through your VPN server (aka “exit node”) back at home.
Once you’re finished with this step, you can confirm the router has Tailscale installed and connected to your account by viewing the Tailscale web admin page to see “Connected” with the green dot as shown below:
Lastly, enable “Custom Exit Nodes” and select your exit node IP and apply.
5. Adding subnets on the GL-iNet router
OK, so you’ve enabled Tailscale on the GL-iNet router in the Applications section. Now, in order to allow our work laptop (or any device) connected to the router’s LAN to access Tailscale, we must add subnets. It might sound a little tricky at first, but it’s very easy.
First, SSH into your router. Remember to use the password to your router this time, not your laptop or Raspberry Pi password. Open a Terminal window on your Mac/Linux laptop (or use PuTTY for Windows) and type:
ssh root@gl-mt3000
where “gl-mt3000” is the hostname of the GL-iNet router YOU are using.
Alternatively, you can use the router’s Tailscale IP address instead. It should look like 100.x.y.z
ssh root@your-ROUTER-Tailscale-IP
Once logged into the router via SSH, we will use this Tailscale documentation to add subnets. I’ve included the relevant commands for your convenience below.
1. Advertise the IPv4 subnet routes for this GL-iNet router:
sudo tailscale up --reset --advertise-routes=192.168.8.0/24 --accept-routes
It will likely spit back a longer command. Copy and paste the one it gives you and run that command.
NOTE: There is a small chance you may have a subnet conflict, and you will need to use something other than “192.168.8.0/24” above such as “192.168.10.0/24”, etc.
2. Enable the subnet routes from the Tailscale web admin console.
Open the Machines page of the admin console, and locate the GL-iNet router. Click the 3 dots button on the right side and “Edit route settings…”
Click Approve all, so that Tailscale distributes the subnet routes to the rest of the nodes on your Tailscale network. Alternatively, you can approve the route individually by clicking the toggle to the left of the route.
Once you’ve enabled subnets, you should verify that the “edit route settings” for your GL-iNet router in the Tailscale web admin look like this:
If you are using the Slate AX (GL-A1300): Set your Firewall settings as described here: https://forum.openwrt.org/t/help-to-configure-tailscale-as-a-proxy-service/142428/2 in | System | Advanced Settings | Network | Firewall.
6. Edit LuCI settings on GL.iNet travel router
For some reason, this step doesn’t seem to be required for everyone, but if you’re not seeing your home IP while connected through the Tailscale exit node then this is probably the solution.
Go to System -> Advanced Settings and click the link to the LuCI admin pane. Then select Network -> Firewall.
By default, below you will see 3 zones:
- lan > wan
- wan > REJECT
- guest > wan
Click on “EDIT” on the second one ( wan > REJECT), then click on the second tab “Advanced Settings” and in the covered devices select tailscale0. Save, Save and Apply.
7. Confirm your client device (ex. work computer) is showing your home IP
Now that you’ve turned on the Tailscale exit node on your travel router, connect your client laptop to the travel router using the Repeater function. Then run the following Linux command:
dig -4 +short myip.opendns.com @resolver1.opendns.com
If that command doesn’t output anything, then try this one:
curl ifconfig.co
Obviously if you’re on your work computer with Windows and cannot use the above Linux command, then alternatively you can just go to any web browser and navigate to whatsmyip.com to view your IPv4 address from back home.
Remember that the maximum DOWNLOAD speed you will be able to achieve at your work computer when connected to the Tailscale exit node will be your home internet’s UPLOAD speed. If this doesn’t make sense, try drawing out on a piece of paper the connection including acknowledgements/requests between your client computer and the Internet (via your exit node).
Recommended DNS Settings
For the server GL.iNet router, you may use your ISP or server’s DNS servers by setting Mode: Automatic (recommended for Wireguard), or set Mode: Manual to use Google or Cloudflare DNS servers (recommended for Tailscale). Encrypted works too if it’s compatible with your equipment, but it’s not necessary.
Don’t forget you will also need to enable “Remote Access LAN” in the Global Options of the server router on the VPN Dashboard page.
For the client GL.iNet travel router, you should use your Wireguard server’s IP address in the profile config. To edit the profile config, go to Wireguard Client and edit the “DNS = ” line to equal your server IP (ex. 10.0.0.1).
Then, set the DNS mode to “Automatic”. This uses the DNS servers configured on your Wireguard server and ensures your server router’s DNS cache is checked before sending the DNS requests to whatever server you chose.
For Tailscale setups, change the travel router DNS settings above to Manual and add Cloudflare and/or Google servers. Then do the same on the Tailscale website under Nameservers as shown below:
And turn OFF MagicDNS.
Manually upgrade Tailscale version
An awesome admin over on the GL.iNet forum created a super useful script to force a Tailscale update to the GL.iNet routers since the firmware’s Tailscale version is outdated (security flaw!).
https://forum.gl-inet.com/t/script-update-tailscale-on-nearly-all-devices/37582
Simply SSH into your routers and run this command (make sure your router has an internet connection) and follow the prompts:
wget -O update-tailscale.sh https://raw.githubusercontent.com/Admonstrator/glinet.forum/main/scripts/update-tailscale/update-tailscale.sh \ && sh update-tailscale.sh
Additional (mandatory) Tips
- Turn off Wi-Fi, Bluetooth, and location services on your laptop. Connect your client computer to the travel router via Ethernet only.
- Set your system clock to the time zone you are pretending to be in
- If you are using a corporate phone, turn off cellular data, Wi-Fi, Bluetooth, and location services. You may, however, use your personal phone as a cellular hotspot as a primary or secondary/failover source of Internet to your travel router.
- Maintain a strict wall between your work and personal devices. Your work device should not have access to any of your personal accounts, including your system-level Microsoft account or Apple ID. Do not do personal surfing or chatting on your work device.
Lastly, if you’re interested in finding Airbnb’s with guest-submitted/verified internet speeds to ensure a smooth digital nomad experience, go check out my website https://thewirednomad.com Still in development and growing!
For paid assitance in self-hosting your own VPN, see the Silver Tier on my website page here: https://thewirednomad.com/tiers
https://www.paypal.com/donate/?hosted_button_id=UWSK6NVAEN2TG