Tailscale creates a virtual network between hosts. It can be used as a simple mechanism to allow remote administration without port forwarding or even be configured to allow peers in your virtual network to proxy traffic through connected devices as an ad-hoc vpn.

You can read more about how Tailscale works here.

opkg update
opkg install tailscale

After installing Tailscale, run the command below and finish device registration by pasting the given link into a web browser and authenticating via a supported method:

tailscale up

Once registered, device connectivity can be seen by using the “status” command:

tailscale status

Additional configuration may be necessary to communicate with other machines in your Tailnet depending on your default forwarding rules. The following instructions can be used to add a new unmanaged interface and firewall zone so that you can classify and apply forwarding rules to Tailscale traffic.

Create a new unmanaged interface via LuCI: NetworkInterfacesAdd new interface

  • Name: tailscale
  • Protocol: Unmanaged
  • Device: tailscale0

For tailscale to assign the IP to the tailscale0 interface, the init.d script need to be adjusted.

  • Edit /etc/init.d/tailscale
  • After the last procd_append_param add: procd_append_param command --tun tailscale0
  • If you do not want to send logs, you can add to that line --no-logs-no-support, too.

Create a new firewall zone via LuCI: NetworkFirewallZonesAdd

  • Name: tailscale
  • Input: ACCEPT (default)
  • Output: ACCEPT (default)
  • Forward: ACCEPT
  • Masquerading: on
  • MSS Clamping: on
  • Covered networks: tailscale
  • Allow forward to destination zones: Select your LAN (and/or other internal zones or WAN if you plan on using this device as an exit node)
  • Allow forward from source zones: Select your LAN (and/or other internal zones or leave it blank if you do not want to route LAN traffic to other tailscale hosts)

Click Save & Apply

OpenWrt 22.03 and later, use nftables (superseding iptables) as a backend to firewall4. Tailscale is unable to configure nftables automatically and this prevents the tailscale daemon from initializing properly and forwarding traffic.


A workaround for this issue has been applied to the master branch. If you're unable or unwilling to run an image built from the master branch, the following steps can be used as a manual workaround on 22.03.x Credit: aricade, csrutil, youngt2:

Though not actually used, the iptables-nft package is required for tailscaled to start properly and not error with: error: creating router: exec: “iptables”: executable file not found in $PATH

Install iptables-nft

opkg install iptables-nft

Restart the daemon

service tailscale restart

When starting Tailscale, you must prevent iptables rules from being created with the --netfilter-mode=off flag. This setting will be preserved in /etc/tailscale/tailscaled.state for future boots.

tailscale up --netfilter-mode=off

Complete the setup as usual

To use the device as a VPN gateway, configure Tailscale to use an exit node:

tailscale up --netfilter-mode=off --exit-node=MY-EXIT-NODE --exit-node-allow-lan-access=true

Force LAN traffic to go through Exit Node

1. Disable packet forwarding by default: NetworkFirewallGeneral Settings

  • Forward: reject

2. Disable LAN-to-WAN forwarding: NetworkFirewallZoneslanEdit

  • Allow forward to destination zones: Ensure that your WAN zone is unselected.

In order to get tailscale to cooperate well with LuCI, you will need to create a new managed interface and firewall zone for tailscale.

1. Create a new unmanaged interface via LuCI: NetworkInterfacesAdd new interface

  • Name: tailscale
  • Protocol: Unmanaged
  • Device: tailscale0

2. Create a new firewall zone via LuCI: NetworkFirewallZonesAdd

  • Name: tailscale
  • Input: ACCEPT (default)
  • Output: ACCEPT (default)
  • Forward: ACCEPT
  • Masquerading: on
  • MSS Clamping: on
  • Covered networks: tailscale
  • Allow forward to destination zones: Ensure that your WAN zone is selected. (Add LAN here as well if you intend to allow hosts in your tailscale network to connect to hosts on your LAN)
  • Allow forward from source zones: Select your LAN and/or other internal zones (Leave this blank if you do not want to route LAN traffic to hosts on your tailscale network, e.g a WAN-only exit node)

3. Click Save & Apply

4. Restart tailscale and add the routes you want to advertise to peers using the --advertise-routes option with a comma separated list of network addresses and CIDRs. The --accept-routes option will manage adding static routes for other subnet routes within your tailnet.

tailscale up --advertise-routes=, --accept-routes

You can also also use --advertise-exit-node node here to offer both subnet routes and a WAN gateway to your tailscale network:

tailscale up --advertise-routes=, --accept-routes --advertise-exit-node

If you're using OpenWrt >=22.03 you will also need to specify --netfilter-mode=off

5. Open the Machines page in the Tailscale admin interface. Once you've found the machine from the ellipsis icon menu, open the Edit route settings.. panel, and approve exported routes and or enable the Use as exit node option.

6. Devices on either subnet should be able to route traffic over the VPN. If you've configured this device to be an exit node, it should now be selectable from your tailscale apps as an Exit Node. You can test connectivity with tools like ping or traceroute.

Tailscale cannot be installed on devices with 16MB or less of flash memory because the package and its dependencies consume too much space. Until the day that there is a separate “tailscale-lite” build, your best bet is to compile (or cross-compile) it yourself from upstream sources and use the multicall binary build target. To reduce the filesize further, you can strip debugging symbols and run the resulting binary through a packer, like upx. As of 1.56.1, this will result in ~98% reduction in size (from ~33MB to ~5.2MB).

Instead of running the optimized binaries directly, it is recommend that you repack the tailscale.ipk, and tailscaled.ipk packages with the smaller optimized binaries. This will let you benefit from OpenWrt conventions like init scripts, opkg installation receipts, etc, keeping your installation sane and consistent while still being able to use the smaller binaries.

If your device has only 16MB of flash or less, you will need to share the multicall binary between both of the tailscale and tailscaled packages. To do this, stub out the large /usr/sbin/tailscale{d} binaries contained within these packages, install them, manually copy the optimized binary to the device, and then replace the stubs with symlinks. More detailed instructions on how to do this are below.

The official Tailscale small binary build guide is here:


  • upx 3.96 produces broken mips binaries, use the latest version. Upx can handle all executable formats, so you don't need to run it under the target architecture.
  • You can shave off an additional MB or so with strip --strip-all. This strips even more than when using go build ldflags. Look for the binutils package of your target architecture. For my MIPS target, on Linux that was binutils-mips-linux-gnu, on macOS the same MacPorts package is called mips-elf-binutils.
  • You should reset your git checkout of Tailscale to a tagged stable release to ensure compatibility with the OpenWrt package you're repacking. This also makes troubleshooting easier on yourself in the future and is best practice.
  • Be very careful when repacking your .ipk not to include leading paths. An absolute path in the root of the package will produce an unusable .ipk.
  • Don't forget to symlink /usr/sbin/talescale.combined to /usr/sbin/tailscale and /usr/sbin/tailscaled.
  • If installing on >= 22.03, don't forget to apply the work arounds listed earlier on this page.
  • On slow devices, upx packed executables may appear to hang at first when you run them but this is normal; higher startup time for lower storage costs. If having trouble try compressing without --best
  • It's a good idea to check that your tailscale.combined actually runs on your target architecture with a simple ./tailscaled --version on the target device before going to the trouble of repacking.

Other useful links:

Shell history on macOS where I built tailscale from source for a big endian mips target:

sudo port install go mips-elf-binutils upx
git clone https://github.com/tailscale/tailscale.git
cd tailscale
git checkout tags/v1.56.1 -b v1.56.1
env GOOS=linux GOARCH=mips GOMIPS=softfloat go build -o tailscale.combined -tags ts_include_cli,ts_omit_aws,ts_omit_bird,ts_omit_tap,ts_omit_kube -trimpath -ldflags="-s -w" ./cmd/tailscaled
/opt/local/bin/mips-elf-strip --strip-all tailscale.combined
upx --lzma --best tailscale.combined # (v3.96 has deadlock bug)

The steps below were performed on Debian Linux. I repacked the OpenWrt .ipk for the tailscale and tailscaled packages and replaced the large binaries with small stub scripts that always return true. I did this so that the pre/post scripts will run successfully and the opkg database at /usr/lib/opkg will be consistent. The packages were installed manually and stub files deleted post installation. The multicall binary was then uploaded and symlinks created.

# convenience variables
export package=tailscaled_1.56.1-1_mips_24kc.ipk
export release=23.05.2
export arch=mips_24kc

# download .ipk
wget https://downloads.openwrt.org/releases/${release}/packages/${arch}/packages/${package}
mkdir ${package%%.ipk}
pushd ${package%%.ipk}
tar -xvf ../${package}

# data
mkdir data
pushd data
tar -xvf ../data.tar.gz
echo -e '#!/bin/sh\ntrue\n' > usr/sbin/${package%%_*}
tar --numeric-owner --group=0 --owner=0 -czf ../data.tar.gz *
size=$(du -sb data | awk '{ print $1 }')
rm -rf data

# control
mkdir control
pushd control
tar -xvf ../control.tar.gz
sed -i "s/^Installed-Size.*/Installed-Size: ${size}/g" control
tar --numeric-owner --group=0 --owner=0 -czf ../control.tar.gz *
rm -rf control

# repack .ipk
tar --numeric-owner --group=0 --owner=0 -cvzf ../${package} debian-binary data.tar.gz control.tar.gz

You should now have a repacked package named tailscaled_1.56.1-1_mips_24kc.ipk. You will need to repeat this process for the tailscale package.

Set a new package variable:

export package=tailscale_1.56.1-1_mips_24kc.ipk

And repeat the repack process above to create the repacked tailscale package.

You should now have two repacked packages similar to tailscale_1.56.1-1_mips_24kc.ipk and tailscaled_1.56.1-1_mips_24kc.ipk. Copy these files to /tmp on your device. Since sftp-server is not included with dropbear/OpenWrt, if you're scp from a relatively recent version of OpenSSH you'll need to either use scp -O to use the legacy scp fallback mode, or do this from the OpenWrt device.

# convenience variables
export version=1.56.1
export arch=mips_24kc

# copy files
scp remote:/tmp/tailscale.combined /tmp
scp remote:/tmp/tailscaled_${version}-1_${arch}.ipk /tmp
scp remote:/tmp/tailscale_${version}-1_${arch}.ipk /tmp

# install dependencies
opkg install kmod-tun

# install repacked packages
opkg install /tmp/tailscaled_${version}-1_${arch}.ipk
opkg install /tmp/tailscale_${version}-1_${arch}.ipk

# remove stubs and link multicall binary
rm /usr/sbin/tailscaled
rm /usr/sbin/tailscale
cd /usr/sbin
cp /tmp/tailscale.combined .
ln -s tailscale.combined tailscaled
ln -s tailscale.combined tailscale

# verify
tailscale --version
tailscaled --version

You're now ready to continue to iptables-nft_issue.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2024/05/08 14:18
  • by wpyoga