How to enforce a truly persistent route over Zerotier?

So I have built a zerotier network back to my house via a Glinet Beryl AX (my travel router), and a Flint 2 sitting at home. I have configured the network so all my traffic moves through my public IP at home. I enabled WAN access on the Flint 2, setup a route in Zerotier, then setup a static route in LuCI on my Beryl AX. While this is generally working, I have one MAJOR problem. It is easy to accidentally leak my local IP for various reasons. I am essentially looking for a way to functionally accomplish “Block Non-VPN Traffic”, but for my Zerotier network. So if the zerotier connection dies, or the wan/wwan connection dies, traffic will just stop, instead accidentally failing over to the local wan route. Cron jobs to re-apply the static route on an interval is not tight enough for my needs. I tried using Google Bard to see if I could figure this out on my own, but after spending hours, I have hit a wall. It seems like route persistence doesn’t work the way I would expect (apply the local static route on bootup, regardless if the interface is present), but I’m not a network guy at all, so if anyone knows a strategy to solve for this, it would be super appreciated.

@admon : < ping >                      

I read this thread yesterday already and hoped that somebody else will answer it :face_with_peeking_eye: because I don’t know the answer.

In my opinion, ZeroTier cannot be uses like a privacy VPN (like Mullvad.net) because it was not designed for this specific purpose. ZeroTier is more like bridging and switching existing networks together - instead of trying to stay private.

I wasn’t able to find any information about how to stop traffic flow when the ZeroTier connection drops. Since ZeroTier itself needs internet access, I would even doubt that it’s possible without really wonky adjustments - there is no kill switch integrated.

In that case, you might need to script your own unique watchdog daemon. Nothing I can assist you with, unfortunately.

I was able to build a startup route monitoring script after spending a full day playing around with Bard which monitors the static routes, and drops my lan interface if the needed route isn’t in place. It polls every second, which is better than nothing, but I will need to play with some packages to get the monitoring truly active. Bard couldn’t get the native monitoring solution built into Beryl/OpenWRT to work properly. Some more fiddling, and I think I should be able to get pretty darn close. Might need to load a 3rd party monitor in order to figure it out.

But yes, I acknowledge Zerotier really isn’t designed for this. However, I specifically need to route my connection through my home IP, and Wireguard is not an option (since my ISP is behind CGNAT). Honestly, the network performance has been more than sufficient for my current needs. Just need to handle some video calls basically. Ping times aren’t perfect, but sufficient.

What’s amazing (at least to me), is I would NEVER have been able to figure this out on my own. The fact that I can “brute force” the needed scripting with multiple iterations within AI. I couldn’t code or script my way out of a paper bag. It took several hours, and someone who is much more knowledge could have accomplished what I built I’m sure in a fraction of the time (and a better job). But the fact that entry level development and scripting are now accessible to the masses is pretty darn nifty if I do say so myself :wink:

If you want to get something back to the community, feel free to share your script here.
Maybe some people are even able to modify it for your needs.

Here is my current pile of trash ;). Outside of this script, I have a cron job which perpetually re-applies the “catch all” static route which pushes all my traffic through zerotier. I do this so the route gets re-applied if the WAN blips/drops. I couldn’t figure out how to turn off traffic with iptables successfully, thus the interface shutdown.

Additionally, I am not savvy with the firewall. I had to put my zerotier interfece in my WAN zone for things to work correctly. I tried isolating Zerotier into its own zone so I could manage the Luci firewall more cleanly, but just couldn’t make it work. Anywho, see below for my “rough and dirty” script.

#!/bin/ash


TARGET_NETWORK="10.147.20.16"  # Replace with the actual network address
ZEROTIER_INTERFACE="ztrfyi6tzz"  # Replace with the actual ZeroTier interface name
LAN_INTERFACE="eth1"  # Replace with the actual LAN interface name


# Initial state: Disable the LAN interface
ifconfig $LAN_INTERFACE down
echo "LAN interface disabled."


while true; do
 current_status=$(ip route show | grep "$TARGET_NETWORK" | grep "$ZEROTIER_INTERFACE")


 echo "$current_status"  # Debugging output


 if [ -n "$current_status" ] && [ "$current_status" != "$previous_status" ]; then
   echo "Route status changed: $current_status"  # Additional debugging


   if [ -n "$current_status" ]; then
     # Specific ZeroTier route is present, enable the LAN interface
     ifconfig $LAN_INTERFACE up
     echo "Specific ZeroTier route is up, LAN interface enabled."
     break  # Exit the loop since the route is up
   else
     # Specific ZeroTier route is down, keep the LAN interface disabled
     echo "Specific ZeroTier route is down, LAN interface remains disabled."
   fi


   previous_status="$current_status"
 fi


 sleep 1  # Check again in 1 seconds
done

I was able to successfully use Bard to convert this over to IP monitor, so thats an improvement…

#!/bin/ash

TARGET_NETWORK="10.147.20.118"  # Replace with the actual network address
ZEROTIER_INTERFACE="ztrfyi6tzz"  # Replace with the actual ZeroTier interface name
LAN_INTERFACE="eth1"  # Replace with the actual LAN interface name

# Initial state: Disable the LAN interface
ifconfig $LAN_INTERFACE down
echo "LAN interface disabled."

ip monitor all > /dev/null &  # Start monitoring route changes in the background
monitor_pid=$!

while true; do
    # Check if the specific ZeroTier route is present
    current_status=$(ip route show | grep "$TARGET_NETWORK" | grep "$ZEROTIER_INTERFACE")

    if [ -n "$current_status" ]; then
        # Specific ZeroTier route is present, enable the LAN interface
        ifconfig $LAN_INTERFACE up
        echo "Specific ZeroTier route is up, LAN interface enabled."
        break  # Exit the loop since the route is up
    else
        # Specific ZeroTier route is down, keep the LAN interface disabled
        echo "Specific ZeroTier route is down, LAN interface remains disabled."
    fi

    sleep 1  # Check again in 1 second (adjust as needed)
done

# Cleanup: Stop the route monitoring process
kill $monitor_pid



1 Like

Well, in worst case it will make your router unreachable for you - when WAN is down.

@alzhao

I’ll say it again: I’m really looking forward to seeing the Docs feature on this forum. I think it could be another important product/market-related differentiator given OWRT’s default forum offering.

The docs seems good. Will do some research.

2 Likes

Not that anyone cares, and even though I more or less got where I wanted to get to scripting-wise, the better answer was to set up a Wireguard server and setup a vpn connection between my two routers, and then leverage the native traffic protection of wireguard. So essentially doing a wireguard connection after the zerotier connection bootstraps. Works perfectly (after specifying internal Wireguard server IP, and not public IP), and I have gone that route

1 Like

Heh; congratulations on the workaround. You’ve set up what’s known as a ‘tunnel in tunnel.’ Nice.

If you are from the Glinet dev team, you might want to look into Cudy's (other brand of travel routers) implementation, they have a kill switch option for Zerotier (and an easy way of allowing a Zerotier exit node, i.e. having an local IP route to the exit node and setting Zerotier's alloeDefault option).

I just got a Beryl AX (upgraded from the Cudy equivalent of a Glinet Mango, where VPN speeds were slow given the basic specs), and found the lack of kill switch for Zerotier appalling.

I guess the only option is to setup Wireguard on top (over the ZT IP addresses, to circumvent CGNAT?), which seems a bit overkill.

I am not, but thanks for the hint.