Tailscale on My GL.iNet Mango OpenWrt Router

| Comments

Last month, I discovered GL.iNet and their line of routers. They have a lineup of hardware that starts with a $20 travel router up to $400 industrial routers, and they have all sorts of options in between. The best part is that every one of their routers ships with OpenWrt!

I knew I had to order one to replace my aging RAVPower Filehub Plus. The GL.iNet Mango was both the cheapest and smallest of their offerings, so I figured I would give it a shot.

I’ve been doing my best to install Tailscale on all my machines. When the Mango arrived, I wondered if I could get Tailscale running on it?

There were some problems!

The MIPS build of Tailscale was broken. It wasn’t compiled with floating point emulation, so it wouldn’t run on any common OpenWRT routers with MIPS processors. This made me put this idea on hold for a while.

Tailscale for MIPS ships with two binaries: tailscale and tailscaled. They add up to a combined total of 24 megabytes. My Mango router only has 16 megabytes of flash. That’s the total. There’s no room to properly install Tailscale on this thing!

I knew a working build would be available soon, but it was no longer at the top of my list of projects. I didn’t think to check back for a working Tailscale binary until last week!

I’ve discovered that you really only need the tailscaled binary to get connected and running, but that’s still more than 14 megabytes.

Memory is tight, too. This little guy only has 128 megabytes of RAM. Tailscale on my desktop has an RSS of about 20 megabytes. I figured it would fit, but I was still worried.

Hey Pat! Why aren’t you just following Will Angley’s awesome instructions?!

The simple answer is that Will’s excellent Tailscale on OpenWrt/LEDE guide didn’t exist when I started this journey. Even if it had, it wouldn’t have helped me too much. Will’s router has significantly more flash storage than mine. He seems to have more than 70 megabytes free, whereas I have quite a bit less than 3 megabytes free.

If you have a newer, bigger, fancier, more expensive OpenWrt router, you should absolutely follow Will’s guide! It is fantastic.

What I’ve done is rather quick and dirty.

I had to install a kernel module

Tailscale uses tun network device, and this isn’t install by default with OpenWrt. You can install it from the LuCI GUI interface, or you can install it from the command line:

opkg update
opkg install kmod-tun

The module should be loaded automatically after it is installed, and it should be available each time you reboot.

My first test

I copied the Tailscale binaries to my Mango’s temp directory. I wasn’t confident this would work. Tailscale was probably going to need 20 megabytes of RAM just to run, and I was eating up another 24 megabytes by storing the binaries in memory.

I was worried over nothing. It worked just fine! I was connected, pinging, and connecting to my other machines using ssh within a few minutes!

Will Angley’s blog post says that you need the tailscale binary to find the URL to authorize your new device. It didn’t even occur to me to use it. I was just watching the output of tailscaled, and I saw a line mentioning the authentication URL. I just copied it from there.

A more permanent solution

It would be awesome if I could build a Tailscale package for OpenWrt, but neither my Mango or my house’s aging OpenWrt router have enough storage for something this large. If I’m going to put Tailscale on the router, I’m going to have to get creative.

I thought about fetching the Tailscale binary from the Internet and dropping it in the temp directory each time the router boots up. Depending on how you look at it, this may have been a cleaner way to go, but I didn’t want to waste 15% of my poor little router’s RAM like this!

I decided it would be best to make use of the Mango’s USB port and put the Tailscale binaries on a random USB flash drive.

Could I have chosen a more gigantor flash drive?

On my first attempt, I tried using one of Brian Moses’s little flash drives that have his face on them. It seemed to work just fine.

I formatted the flash drive with an ext3 filesystem, copied the Tailscale binaries to the drive, and I plugged the drive into the Mango. OpenWrt automatically mounted the drive, and I had no trouble manually firing up Tailscale.

I added some Tailscale commands to the router’s startup script, then restarted the router. It wouldn’t mount the flash drive. In fact, the Linux kernel didn’t even see that there was a device plugged in. If I pulled out the drive and plugged it back in, it would mount right away.

Turns out that the Mango just didn’t like Brian’s drive. I used another random flash drive, and it mounts automatically when the Mango boots up.

My commands in rc.local did run on every boot, but Tailscale wouldn’t start. This is the line I added to my /etc/rc.local file:

(sleep 10; /mnt/sda1/tailscale/tailscaled -state /mnt/sda1/tailscale/tailscale.state > /dev/null 2>&1) &

The USB drive I’m using is comically large. If I were smart, I would have ordered the GL.iNet Creta instead of the Mango. It is only a few dollars more, but it includes a microSD slot.

I was thinking that I wanted the smallest, lightest, cheapest OpenWrt router I could find to carry in my laptop bag. It didn’t even occur to me to put Tailscale on it until after I opened the box!

Debugging solved the problem

This was a weird problem. Tailscale seemed to exit immediately when run by rc.local, but if I pasted in the same command, it ran just fine. I redirected Tailscale’s output to /tmp/tailscale.log, rebooted the router, and it started up flawlessly!

I was expecting to have to troubleshoot something I found in the log file. Nope. It was even easier than that!

Tailscale was just mad that stdout or stderr wasn’t pointed at anything. I redirected it to /dev/null, and Tailscale connects just fine when the router reboots!

Routing a subnet over Tailscale

To tell you the truth, I would have been happy to stop here. I don’t really need Tailscale on this router, but being able to ssh in and configure it remotely via Tailscale seems like it could come in handy.

I’ve come this far, though. I may as well figure out how to get Tailscale to route to my Mango’s subnet, right?!

It was extremely easy. I just followed the directions on the Tailscale site.

Once you have routing configured, I do not believe you need the tailscale binary any longer. If you happen to have just barely enough room on your router’s flash storage to fit the tailscaled binary, leaving the tailscale binary out might be a good option!

What the heck am I going to do with this?!

In the old days, I used to set up dynamic DNS on all my OpenWrt routers, disable password authentication on ssh, and open up the ssh port to the world. If I ever left anything at home, this would come in handy. If my one of my parents were having trouble, I could ssh to their router to check things out, too.

This is a much better solution to the same problem. It doesn’t rely on DNS. It doesn’t rely on the router being plugged into a real network. The router could be plugged in behind a NAT. It could be connected to my phone via WiFi or USB. Either way, I will be able to ssh in or hit the router’s web interface.

If you’re more nefarious than me, I’m sure you could come up with a creative use for a Linux box with Tailscale that only weighs a few ounces, is powered via USB, and costs only $20.

The GL.iNet 300M Mango vs. my home router

The Mango is an inexpensive, low-end travel router. Aside from its lack of 802.11ac and a few gigabit Ethernet ports, it is quite comparable to the router in my network cupboard at home. They both have the same amount of CPU, RAM, and flash.

My home router was already old when I bought it. I only intended to use it to add 802.11ac to our old apartment, but it can do NAT at around 450 megabits per second, so it is doing a find job on our FiOS connection. If you’re curious, it is an oddly shaped D-Link DIR-860L, and it doesn’t fit well in my cupboard!

My D-Link OpenWrt router has nearly 8 megabytes of storage free, while the GL.iNet Mango has less than 2 megabytes. Why is that?!

The Mango is built on top of OpenWrt/LEDE and the LuCI GUI, but they also have their own interface sitting in front of LuCI. I’m sure that takes up a bit of space, but surely not the entire 6 megabyte difference.

The Mango also has a button that allows you to reinstall the factory firmware. I assume that firmware image is sitting on an unused partition somewhere.


This is working quite well. Well enough that I may need to get Tailscale up and running the same way on my home router. Nearly everything in my house that I’d ever want to access remotely is already running Tailscale, but maybe I’ll have a weird reason to want to reach the PS4, Nintendo Switch, or one of the Amazon Fire TV devices remotely someday.