Any working examples of a NixOs with Internet failover

I’m trying once again to get dual wan failover working, as I host services, and have two internets, either of which can fail. I’m looking for a way to get nixos to route from either of two wans to internal servers, and send the response back out to the requester.

I’ve done all the normal research, trying to understand iptables, nftables, route, ip route, conntrack, marking, etc, etc. I know that extraCommands will execute whatever magic incantation I assemble, and do it all perfectly. But I cannot find the incantation to turn lead into gold. I’m happy to browse through a public github repository of someone who’s done it. That would be amazing. I’m happy to follow recipies, even though the shorewall multi-wan recipe didn’t work. I’m happy to take any advice given.

Things I’ve used:

  1. PfSense – both preinstalled on an old rackmount pc, and purchased from netgate directly. The pfsense hardware failed repeatedly. The ebay machines I’ve bought to do this were either great or a piece of junk. Nothing in the middle.
  2. A raw linux machine, Ubuntu 16.xx. This had the ability to receive and maintain connections from two WAN’s, but one of them was always the default gateway.
  3. Nixos with a single wan. Simply glorious, but only able to use one wan! Because I don’t know how. It’s what I have now.

Places I’ve looked:

  1. NixOs as a router – seems possible, but with only one wan
  2. Me trying to ask a related question
  3. Shorewall. Unfortunately, unmaintained, also without any working examples. Never could get it working, either.
  4. Ferm – looked awesome, but again no examples.
  5. [Routing for multiple uplinks/providers](The theory discussion – routing for multiple uplinks/providers). Nothing explaining it granularly enough to help me mark packets with the firewall, and get them back out.

Would a bond interface do the trick for you? You can set one up with systemd-networkd (or magic ip incantations).

I use it to get failover for ethernet/wireless: https://github.com/TLATER/dotfiles/blob/d9024b2d7bcadd36246422c97b9e260bcc727ee8/nixos-config/yui/default.nix#L82

But you can set it up in lots of different ways, details are in the kernel docs, but you have these options: systemd.netdev

Edit: Hrm, guess not, I suppose routing ends up being the problem in the end, the netdev will just ultimately only be able to connect to one gateway. Fair enough.

Would it be nice enough to connect to a different net dev each time? I think I might try it. Can you listen on the bonded device, and forward that to some other machine?

I think you could get away with using route metrics in networkd like this
https://wiki.archlinux.org/title/systemd-networkd#Wired_and_wireless_adapters_on_the_same_machine

You would just have to use two wired networks instead.

Or maybe you can make a bridge?
https://wiki.archlinux.org/title/Network_bridge

Once you figured out what you need you can just write the config in nix.

I think so, it acts just like a normal device. Worst case you can always use iptables to force that. The kernel just sends packets through both interfaces - I’m just not sure what happens if an address is only reachable from one of the bonded devices, and not both, as would probably happen when you’re trying to send stuff via two different gateways.

I’m afraid after looking into bonded interfaces further, I chickened out and bought a unifi UXG-pro-us. I actually probably need all the IDS and ad-blocking to improve sanity, so there’s that. I keep hoping someone will create a nixos config for a router appliance (even if it needs burly full-scale server machines), but I think that’s probably unlikely to happen.

Not exactly NixOS, but there’s some ongoing work on a nix-based router distro using an openwrt kernel: https://www.liminix.org/