Sensible way to define static routes

Hi,
I’m wondering if there is a sensible way to define static routes per network?

I can connect my laptop to different subnets and I’d like the static routes defined that appropriate for that subnet. I realise this might be a bit of an ask but also nixos can do a lot so I thought it worth asking the question

https://nixos.org/manual/nixos/unstable/#sec-networking

I do not see a section here on static routes. It would be useful to define them per wifi connection vit I see no indication that this is possible

Oh, sorry. Static routes… what about systemd.network.networks.<name>.routes?

After reading up on systemd-networkd this appears to be the direction to go. The Match section for a network appears to be able to use SSID so I would be able to at least match if I connect by Wifi. I don’t see any way to uniquely identify a wired network but I can’t even think how one would be able to do that without first connecting to the network and then examining mac addresses or something. This may be as good as it gets currently so I’ll look to switch to systemd networking rather than network manager, which I think is default.

I may be able to make all of this redundant with tailscale but I think this exercise is worth working through

Maybe Vula?

https://ngi-nix.github.io/ngipkgs/

While this does look like an interesting project it still uses the original IPs as far as I can tell so I would still need static routes. The advantage of tailscale in this context would be the overlay network being in the same subnet and also that the entry point to the vpn could be moved to an exit node. I’ve not experimented with this yet though and moving to tailscale will take a bit more thought so I wanted a solution that worked immediately and only affected a single host

Vula is zero configuration. You won’t need to add static routes. And the NixOS module “just works”.

Mullvad VPN needs static routes so it knows what to define as the local network.

To come back to your original question, using the scripted network module (ie. not networkd), you can add some static routes to your interface using the networking.interfaces.$ifname.ipv4.routes options.

This doesn’t help me as the same interface would apply to multiple subnets

Right. I’m not sure I’m fully get what you’re trying to do here.

You say:

I can connect my laptop to different subnets and I’d like the static routes defined that appropriate for that subnet

How do you connect to these networks?

Assuming it’s a laptop, chances you’re doing that using network-manager. In that case, your best bet is likely to use the network manager dispatcher scripts, and packing the various ip route add calls in a dispatcher script. More infos about those here: NetworkManager: NetworkManager Reference Manual

It’s integrated to NixOS via these options: NixOS Search

The different subnets have different DHCP. And while the laptop itself gets the right IP address and the router knows the correct routes, the VPN software does not know the routes so when it is activated and LAN access is allowed it will not pass traffic to the other subnets.

I’m actually now wondering if I use a slightly broader subnet mask then the VPN software will actually be fine as it will know what to exclude.

I’ve solved this in the meantime with Tailscale but as an exercise I’d like to solve it in Nixos.

I’ll check out these dispatcher scripts you mentioned and see if they can help