Mango GL-MT300N-V2 specifically
Background
I recently picked up a Mango Travel Router by GLi.Net from Amazon . As of the time of publishing, these are being sold in the UK for around £25 – quite the deal, considering its feature set.
Refer to the GL.iNet website for more techy details.
The router was purchased as a method to connect to the internet while we travel and/or move – as we’re likely to have none when the latter actually occurs, at least for a short while at least.
The router itself comes pre-installed with OpenWRT , which makes it a very capable device – as long as you have space available, of course.
Which brings me to my first recommendation – grab yourself a Sandisk USB flash to increase the storage capacity, as you’ll need it if you’re following these instructions. Any USB flash will do (if you already have some), my preference is the Fit as it doesn’t protrude too much.
Assumptions
These instructions assume that you have a modicum of technical skills, and are comfortable in the CLI. You should only really follow this guide if you have the confidence as you can, and likely will break your new router.
Router recovery will likely require a reflash of the device. Consider yourself warned!
Also assumed is that your router has network connectivity, and can successfully download files from the internet.
####Initial Router Setup and Update
Follow the setup guide for your new router – include the latest firmware update, so that you start from the best possible position. Ensure that you create the root users password.
Next, check that you can connect to the new router via SSH.
$ ssh root@<xxx.xxx.xxx.xxx>
BusyBox v1.30.1 () built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 19.07.7, r11306-c4a6851c72
-----------------------------------------------------
root@ROUTER:~#
Run the upgrade command to get the latest file list:
root@ROUTER:~# opkg update
Downloading https://fw.gl-inet.com/releases/v19.07.7/packages-3.0/ ramips/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/glinet_packages
Downloading https://fw.gl-inet.com/releases/v19.07.7/packages-3.0/ramips/glinet/Packages.gz
Updated list of available packages in /var/opkg-lists/glinet_private
Downloading https://fw.gl-inet.com/releases/v19.07.7/kmod-3.0/ramips/mt76x8/Packages.gz
Updated list of available packages in /var/opkg-lists/glinet_kmod
You will need curl, ca-bundle and kmod-tun installed first:
root@ROUTER:~# opkg install curl ca-bundle kmod-tun
Some or all of these packages may already be installed – running the above command will not hurt.
If you haven’t already, go to the Tailscale Home Page and create yourself an account, and then log in.
Double check the routers’ architecture
root@ROUTER:~# cat /etc/openwrt_release
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='19.07.7'
DISTRIB_REVISION='r11306-c4a6851c72'
DISTRIB_TARGET='ramips/mt76x8'
DISTRIB_ARCH='mipsel_24kc'
DISTRIB_DESCRIPTION='OpenWrt 19.07.7 r11306-c4a6851c72'
DISTRIB_TAINTS='busybox override'
‘DISTRIB_ARCH=’ shows this as a mipsle_24kc device, so we’ll be looking for the mipsle static binary later.
By default, the router uses ‘vi’ as its editor. Nano is somewhat friendlier, and allows you to paste directly into the console, so we’ll install it now
root@ROUTER:~# opkg install nano
Package nano (5.5-1) installed in root is up to date.
Install USB Tools and Drivers
root@ROUTER:~# opkg install kmod-usb-storage kmod-usb-storage-uas usbutils
Package kmod-usb-storage (4.14.221-1) installed in root is up to date.
Package kmod-usb-storage-uas (4.14.221-1) installed in root is up to date.
Package usbutils (007-10) installed in root is up to date.
root@ROUTER:~# lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci-platform/1p, 12M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-platform/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
Confirm the available partitions/devices
root@ROUTER:~# opkg install block-mount
Package block-mount (2020-05-12-84269037-1) installed in root is up to date.
root@ROUTER:~# ls -la /dev/sd*
brw------- 1 root root 8, 0 Jan 1 1970 /dev/sda
brw------- 1 root root 8, 1 Jan 1 1970 /dev/sda1
root@ROUTER:~# block info | grep "/dev/sd"
/dev/sda1: UUID="YOUR-UUID-HERE" VERSION="1.0" MOUNT="/mnt/sda1" TYPE="ext4"
Install the required disk utilities
root@ROUTER:~# opkg install gdisk e2fsprogs kmod-fs-ext4
Installing gdisk (1.0.4-2) to root...
Downloading https://fw.gl-inet.com/releases/v19.07.7/packages-3.0/ramips/packages/gdisk_1.0.4-2_mipsel_24kc.ipk
Installing uclibcxx (0.2.5-3) to root...
Downloading https://fw.gl-inet.com/releases/v19.07.7/packages-3.0/ramips/packages/uclibcxx_0.2.5-3_mipsel_24kc.ipk
Configuring uclibcxx.
Configuring gdisk.
Package e2fsprogs (1.44.5-2) installed in root is up to date.
Package kmod-fs-ext4 (4.14.221-1) installed in root is up to date.
Out with the old and in with the new – creating the EXT4 partition on USB storage
Use gdisk to delete the current partition (which is likely to be FAT32), and create a new one (see the gdisk man page for more help with this). Mark the partition as Linux Filesystem (use code 8300 here).
Example output:
root@ROUTER:~# gdisk /dev/**your device**
GPT fdisk (gdisk) version 1.0.4
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): p
Disk /dev/sda: 60088320 sectors, 28.7 GiB
Model: SanDisk 3.2Gen1
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): YOUR-DISK-IDENTIFIER-HERE
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 60088286
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 60088286 28.7 GiB 8300 Linux filesystem
Command (? for help): w
Once saved (press ‘w’ to write changes and exit, or ‘q’ to quit without saving changes) , create the filesystem:
root@ROUTER:~# mkfs.ext4 /dev/sda1
Mounting the newly created partition
Create the /mnt/sda1 folder as the mount point, if it doesn’t already exist
root@ROUTER:~# mkdir -p /mnt/sda1
root@ROUTER:~# blkid
/dev/mtdblock5: TYPE="squashfs"
/dev/sda1: UUID="YOUR-UUID-HERE" TYPE="ext4" PARTLABEL="Linux filesystem" PARTUUID="YOUR-PARTUUID-HERE"
Set the partition so that it will automount
root@ROUTER:~# block detect | uci import fstab
root@ROUTER:~# uci set fstab.@mount[-1].enabled='1'
root@ROUTER:~# uci commit fstab
Reboot and check that everything is as expected – ensure that the /dev/sda1 folder is mounted.
root@ROUTER:~# uci show fstab
fstab.@global[0]=global
fstab.@global[0].anon_swap='0'
fstab.@global[0].anon_mount='0'
fstab.@global[0].auto_swap='1'
fstab.@global[0].auto_mount='1'
fstab.@global[0].delay_root='5'
fstab.@global[0].check_fs='0'
fstab.@mount[0]=mount
fstab.@mount[0].target='/mnt/sda1'
fstab.@mount[0].uuid='YOUR-UUID-HERE'
fstab.@mount[0].enabled='1'
Now you create the tailscale folder inside what will be the /opt folder later – we also create a state folder to save authentication between restarts
root@ROUTER:~# mkdir -p /mnt/sda1/opt/tailscale/state
Note: busybox may not support ‘mkdir -p’, in which case, create each directory individually
Create an /opt folder in the root directory
root@ROUTER:~# mkdir /opt
Create the symbolic link between these two folders
root@ROUTER:~# ln -s /mnt/sda1/opt /opt
Now we have the space, it’s time to install Tailscale
I also create an ‘archive’ folder to store the tailscale download file – keeps things tidy – it’s your choice, but is recommended.
root@ROUTER:~# mkdir /opt/tailscale/archive
Download the Tailscale Stable static binaries for the mipsle device (adjust the path if you didn’t create the archive folder).
root@ROUTER:~# curl -O https://pkgs.tailscale.com/stable/**latest version**_mipsle.tgz --output /opt/tailscale/archive/.
Unpack the archive (adjusting the archive name as required)
root@ROUTER:~# tar x -zvf /opt/tailscale/archive/**latest version**_mipsle.tgz -C /opt/
Move the files into the correct folder (adjusting folder name as required)
root@ROUTER:~# mv /opt/**latest version**_mipsle/* /opt/tailscale/.
Delete the now empty folder (adjusting folder name as required)
root@ROUTER:~# rm -r /opt/**latest version**_mipsle
The /opt/tailscale folder should now look like this:
root@ROUTER:~# ls -la /opt/tailscale
drwxr-xr-x 5 root root 4096 Jul 28 16:10 .
drwxr-xr-x 4 root root 4096 Jul 28 11:50 ..
drwxr-xr-x 2 root root 4096 Jul 28 16:01 archive
drwxr-xr-x 2 root root 4096 Jul 28 15:35 state
drwxr-xr-x 2 root root 4096 Jul 28 12:56 systemd
-rwxr-xr-x 1 root root 10866857 Jul 28 02:56 tailscale
-rwxr-xr-x 1 root root 16612381 Jul 28 02:56 tailscaled
Create the symbolic links to the tailscale application and daemon files
root@ROUTER:~# ln -s /opt/tailscale/tailscale /usr/sbin/tailscale
root@ROUTER:~# ln -s /opt/tailscale/tailscaled /usr/sbin/tailscaled
Create the service that controls Tailscale
Create the Tailscale service in /etc/init.d (using nano which you installed earlier)
root@ROUTER:~# nano /etc/init.d/tailscale
Paste the following script into the editor
1#!/bin/sh /etc/rc.common
2
3# Copyright 2020 Google LLC.
4# SPDX-License-Identifier: Apache-2.0
5
6USE_PROCD=1
7START=80
8
9start_service() {
10 local state_file
11 local port
12 local std_err std_out
13
14 config_load tailscale
15 config_get_bool std_out "settings" log_stdout 1
16 config_get_bool std_err "settings" log_stderr 1
17 config_get port "settings" port 41641
18 config_get state_file "settings" state_file /opt/tailscale/state/tailscaled.state
19
20 /usr/sbin/tailscaled --cleanup
21
22 procd_open_instance
23 procd_set_param command /usr/sbin/tailscaled
24
25 # Set the port to listen on for incoming VPN packets.
26 # Remote nodes will automatically be informed about the new port number,
27 # but you might want to configure this in order to set external firewall
28 # settings.
29 procd_append_param command --port "$port"
30
31 # OpenWRT /var is a symlink to /tmp, so write persistent state elsewhere.
32 procd_append_param command --state "$state_file"
33
34 procd_set_param respawn
35 procd_set_param stdout "$std_out"
36 procd_set_param stderr "$std_err"
37
38 procd_close_instance
39}
40
41stop_service() {
42 /usr/sbin/tailscaled --cleanup
43}
44
BASH
Exit nano using CTRL+X
, ensuring that you save the file on exit. Now to make the script executable
root@ROUTER:~# chmod +x /etc/init.d/tailscale
(Optional) You can create a config file for the service in /etc/config which can override the built in service settings
root@ROUTER:~# nano /etc/config/tailscale
1config settings 'settings'
2 option log_stderr '1'
3 option log_stdout '1'
4 option port '41641'
5 option state_file '/opt/tailscale/state/tailscaled.state'
FALLBACK
Tailscale has now been installed. Time to test that our work is functioning correctly…
root@ROUTER:~# cd /etc/init.d
root@ROUTER:~# service tailscale start
You should see some output relevant to your installation. As long as there are no serious errors (you may see a couple relating to logs that you may safely ignore) then you can bring Tailscale VPN online with the following command
Authenticating Tailscale for the first time
root@ROUTER:~# tailscale up
This will display some text on the screen, along with a URL to visit – at this point, you should already have an account with Tailscale , and have logged into their website. Visit the URL from the console to authenticate your router.
Now when you visit the Tailscale admin console , you should see your router added – note that the router here has ‘No Expiry’ set already – you can do this later by selecting the ellipsis (···) beside the device, and choosing Disable Key Expiry
:
Machines
[All | External] [Search machines... ]
MACHINE IP OS LAST SEEN
hello 100.101.102.103 Linux Connected
services@tailscale.com 1.12.1
[External][No expiry]
router xxx.xxx.xxx.xxx Linux Connected
your@email.address 1.12.1
[No expiry]
To check that the network is available, run the following command (use CTRL+C
to cancel)
root@ROUTER:~# tailscale ping hello.ipn.dev
pong from hello (100.101.102.103) via DERP(fra) in 659ms
pong from hello (100.101.102.103) via DERP(fra) in 54ms
pong from hello (100.101.102.103) via DERP(fra) in 101ms
pong from hello (100.101.102.103) via DERP(fra) in 54ms
pong from hello (100.101.102.103) via DERP(fra) in 54ms
^Ccontext canceled
Congratulations! You now have Tailscale installed and working correctly. However, it won’t start automatically yet, so there are two more commands that you need to enter before you reboot your router.
root@ROUTER:~# cd /etc/init.d
root@ROUTER:~# service tailscale enable
Reboot the router, then retest the ping using the command above. If it still works as before (and there’s no reason why it shouldn’t) then pat yourself on the back for a job well done – it’s been a trek! 😉
References
@PeeKay69 – Twitter
OpenWRT Home Page
OpenWRT Storage Page
Tailscale Admin Console
Thanks and Credits
This guide is an original work, with additional information included. However, as I used several sites as reference to get this functioning correctly, I wanted to credit their work also.
Will Angley : “How I set up Tailscale on my WiFi router”
OpenWRT Packages : Adaptation of the service/init and /etc/config/tailscale config files
Pat Regan : Pointed me in Wills direction – I originally used Pats service method prior to creating this better (IMHO) version
Tailscale : Let’s not forget Tailscale without whom I would never have embarked on this mission in the first place
Cristiaan Diels for additional proof reading and error spotting – thanks!