Keenetic supports ZeroTier out of the box, but Tailscale has to be set up through the console.
First, you need to set up Opkg.
Documentation:
- https://alexeydemidov.com/2026/01/14/tailscale-on-keenetic/
- https://forum.keenetic.ru/topic/11085-tailscale-%E2%80%93-%D1%81%D0%B5%D1%82%D1%8C-vpn-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%B0%D1%8F-%D0%BD%D0%B5-%D0%BD%D1%83%D0%B6%D0%B4%D0%B0%D0%B5%D1%82%D1%81%D1%8F-%D0%B2-%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8/
Notes:
- Keenetic doesn’t like it when other applications change routes or DNS, so we’ll disable that.
- Routes are needed — you can add them through Keenetic itself or use the scripts from the links above.
--netfilter-mode=off --accept-dns=false— the secret to making it work reliably- An exit node (
--advertise-exit-node) is also best avoided, though this doesn’t prevent routing manually in the same way (all machines are on the same network anyway, and the routers are already configured to route outward) - The machine name defaults to the hostname, but it can also be changed separately.
Installation
opkg install tailscale ip-full iptables
/opt/etc/init.d/S06tailscaled start
vi /opt/etc/ndm/netfilter.d/050-tailscale.sh
chmod +x /opt/etc/ndm/netfilter.d/050-tailscale.sh
tailscale up --login-server=https://... --authkey hskey-auth-... --netfilter-mode=off --accept-dns=false
tailscale set --advertise-routes 192.168.1.0/24
# reboot or something to apply netfilter for correct routing
ip route show table all
iptables -L FORWARD -n -v | grep tailscale
iptables -t nat -L POSTROUTING -n -v | grep tailscale
If you want to expose the whole subnet, you need to approve routing to it in the network admin panel:
#!/bin/sh
IPT=/opt/sbin/iptables
[ "$type" = "ip6tables" ] && exit 0
if [ "$table" = "filter" ]; then
$IPT -C FORWARD -i tailscale0 -j ACCEPT 2>/dev/null || \
$IPT -I FORWARD -i tailscale0 -j ACCEPT
$IPT -C FORWARD -o tailscale0 -j ACCEPT 2>/dev/null || \
$IPT -I FORWARD -o tailscale0 -j ACCEPT
fi
# not needed if --advertise-routes 192.168.1.0/24 present
if [ "$table" = "nat" ]; then
$IPT -t nat -C POSTROUTING -o tailscale0 -j MASQUERADE 2>/dev/null || \
$IPT -t nat -A POSTROUTING -o tailscale0 -j MASQUERADE
fi
exit 0
DNS
DNS names change extremely rarely, so because of --accept-dns=false you can specify them explicitly:
ip host mydomain.example.com 100.64.0.123
ip host mydomain2.example.com 100.64.0.123
system configuration save