42060da3

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

Check a RouterOS configuration before it can lock you out of the router

Applying is how you would otherwise find out whether RouterOS takes a
file, and finding out that way costs the router. Three things now stand
between a configuration and the box.

routeros-check reads the file against what the router said about itself.
A verbose export is the strongest of those: the router printed those
commands, which is proof it accepts them, whatever version it runs, and
a vm booting some other version can promise nothing of the kind. The
chassis says which interfaces and serial ports exist. A hosts list says
what is supposed to be on the network, so a lease can contradict it. On
top of that, the things a file can say that no single line is wrong
about: a command that can fail before there is a way back in, a bridge
used above the line that creates it, two leases for one address, a
forward to a machine that never asked for one, and an address from a
pool with no host part, which is the subnet-router anycast address and
takes the network down while leaving the router up. Every problem is
reported at once and pointed at the line it is on, because the file
being checked resets a router.

The vm test imports the file into a real RouterOS under qemu, since
RouterOS is the only thing that parses RouterOS. One derivation per
example, so they run at once and an unchanged example is not booted
again.

Deploying is two halves. /import compiles a whole file before running
any of it, so one it cannot compile leaves a reset router with nothing.
The reset is paired with the half that gets you back in, static leases
included, because a dhcp server without them hands out pool addresses
and whatever asks in that window keeps the wrong one for as long as a
lease lasts. The rest goes onto the router that came up, where being
refused costs a message. It refuses to start against a router that is
not the one the checks read, waits for ssh rather than for a port to
answer, waits for the export to stop complaining, and writes the router
back into the record afterwards.

nix run .#deploy-<name> is one exec of one binary, and it does not exist
for a file that failed either check.

Total

9s

Created Started Finished

Time to Start Worker time Duration Time to finish Idle
Config 0s 0s 0s 0s 0s
Eval 0s 8s 8s 9s 0s
Build 8s 0s 0s 8s 0s
Suite 0s 9s 9s 9s 0s

Timeline

Config Eval Build
0s