4.9.0 (GL-BE9300): Adding a server to a WireGuard provider group destroys the existing tunnel configuration, wipes peer credentials and disables policy routing

vpnbug.tar.gz (3.2 KB)

I've found a reproducible issue on my Flint 3 (4.9.0 release) that in the worst case takes down all VPN connections on the router.

Starting point: a NordVPN group in the VPN client profile with three servers, plus Tunnel 1 on the VPN dashboard using kr102.nordvpn.com as its profile, source is a custom interface (krlan), target "all destinations". The tunnel connects and works fine.

Reproduction: disconnect the tunnel, go to the VPN client profile and add one more server to the existing group via the server selection (ca1214 in my case). Back on the dashboard, Tunnel 1 shows "Please select a configuration" — the entire tunnel configuration is gone.

I exported the UCI configs before and after and compared them. Here's what happens:

In /etc/config/wireguard, adding a server doesn't just create the new peer — all peers of the group are deleted and recreated with new IDs (peer_2006–2010 before, peer_2011–2016 after). In the process, existing peers lose all of their credentials. Before:

config peers 'peer_2007'
        option name 'kr102.nordvpn.com'
        option host_id '1003516'
        option private_key '[REDACTED]'
        option address_v4 '10.5.0.2/16'
        option public_key '[REDACTED]'
        option end_point 'seoul.kr.wg.nordhold.net:51820'
        ...

After, the very same server (identical host_id) is reduced to an empty stub without private_key, address or endpoint:

config peers 'peer_2012'
        option name 'kr102.nordvpn.com'
        option host_id '1003516'
        option location 'South Korea,Seoul'

In /etc/config/network, the wgclient1 interface remains but still points to the no-longer-existing peer_2007 and gets set to disabled. On top of that, the related sections rt_wgclient1, wgclient1_blackhole and their IPv6 counterparts disappear from the config entirely.

In /etc/config/route_policy, the tunnel rule loses its via_type, group_id, peer_id and mark options and is set to enabled '0'. The referenced profile file /etc/vpn_profiles.d/profile4260 still exists but has been truncated to 0 bytes. And — this is what I consider the most critical part — in the global section, enabled and instance_on both flip from 1 to 0. So adding a server to a group switches off the entire policy routing engine, which would affect every other tunnel as well.

Since NordVPN WireGuard keys can only be re-fetched through the token API, the damage is not trivially repairable if token validation happens to act up at the same time (which it did in my session: "token not ok" on a token that has no expiry date — possibly a separate issue). I also suspect the same mechanism was responsible for an earlier case on my router where a tunnel was left with an empty PrivateKey after changes to the server group.

Expected behaviour would be: new peers get added to the group without recreating existing ones — or at the very least, credentials, interface binding and tunnel assignment survive the rewrite. I have complete before/after exports of wireguard, network and route_policy and I'm happy to provide them.

1 Like

Update — two more data points:

Retested with the stock Guest network as the tunnel source instead of my custom interface: exact same result. Add a server to the group, tunnel binding gone. So the selected source doesn't matter.

Full transparency though: this router has a custom wifi interface (krlan) that I created via LuCI with a few manual UCI tweaks, documented here: https://forum.gl-inet.com/t/adding-a-custom-wifi-interface-via-luci-requires-manual-uci-tweaks-gl-be9300-4-9-0/68901. Every repro so far has been on this box with that interface present, so I can't fully rule out that its mere existence confuses the config rewrite — even though the peer wipe happens in /etc/config/wireguard during the provider group rewrite, which shouldn't care about wifi interfaces at all. Happy to retest with the custom interface removed if that helps narrow it down.

One more thing: the "earlier case with an empty PrivateKey" I mentioned in the original post — I've since traced it back. On June 16 I had two working tunnels, refreshed the server list to add a third one, and immediately afterwards wgclient1 died with Line unrecognized: 'PrivateKey=' / configuration parsing error. Same signature, so this bug has most likely been biting me for over a month; I just didn't connect the dots back then. It also suggests "update servers" / adding a server through that path triggers the same peer regeneration.

Hi,

Thank you for the detailed follow-up.

We were able to reproduce the behavior where an existing tunnel displays “Please select a configuration” after the NordVPN server list is updated or another server is added to the provider group.

When the provider server list is updated, the related provider profiles are refreshed, and the configuration previously selected for the tunnel is cleared. The corresponding tunnel and routing rule therefore remain inactive until a configuration is selected again.
This is the current expected behavior. The tunnel itself has not been deleted;

The earlier Line unrecognized: 'PrivateKey=' error is a separate issue.
When the request for the NordVPN WireGuard configuration may not have completed successfully during the server update process. The generated configuration did not contain a valid PrivateKey, but the incomplete configuration was still passed to WireGuard for parsing, which caused the configuration parsing error.
We have recorded the issue and submitted it to the relevant team for further evaluation.

Thank you again for your detailed testing and assistance with the investigation.

Thanks for reproducing this and for escalating the PrivateKey issue — much appreciated. Your explanation of the incomplete config being passed to WireGuard matches exactly what I saw on June 16.

On the "expected behavior" part though, I'd like to push back a little, because the before/after diffs show the operation does quite a bit more than clearing the tunnel's profile selection:

The global section of /etc/config/route_policy flips both enabled and instance_on from 1 to 0. That's not one tunnel waiting for a new configuration — that's the policy routing engine for the whole router being switched off, which would also affect other tunnels that weren't touched at all. Is that part expected as well?

On top of that, /etc/config/network loses the rt_wgclient1 rule, the blackhole routes and their IPv6 counterparts entirely, and the wgclient1 interface is left pointing at a peer section (peer_2007) that no longer exists. So "the tunnel has not been deleted" is technically true, but what's left behind is a config that can't work and needs a full re-setup either way.

And one suggestion, because I think the two issues are actually connected: the host_id stays identical across the refresh (kr102 was 1003516 before and after). So the tunnel assignment could simply be re-mapped to the regenerated peer — or better yet, servers that are still in the group could keep their existing credentials instead of being wiped and re-fetched. That would also close the exact window in which the acknowledged PrivateKey bug can strike: if a config request fails mid-update, only newly added servers would be affected instead of previously working tunnels dying. As it stands, adding one server puts every existing tunnel of that provider at risk of the June 16 scenario.

If clearing the assignment really has to stay as-is, a warning in the UI before modifying a group that has tunnels assigned would already help a lot — right now a working tunnel silently disappears after an action that doesn't look related.