The socket is wanted by sockets.target and nothing orders the wireguard unit before it, so the mesh address can be missing at bind time (EADDRNOTAVAIL) and the receiver never listens. FreeBind lets the bind succeed regardless, and also covers the interface coming back after a flap. Also assert the mesh address is not a wildcard, which the comment above the socket already claimed, and cover the rendered socket in a module-eval case.
85 lines
2.5 KiB
Nix
85 lines
2.5 KiB
Nix
# `checks.module-eval-snapshot-store` — see ./lib.nix for the shared
|
|
# rationale (why this suite exists, naming convention, "evaluates not
|
|
# executes").
|
|
#
|
|
# The snapshot store's receiver socket: where it listens, that it can bind
|
|
# before the mesh interface is up, and that it refuses a wildcard.
|
|
{
|
|
pkgs,
|
|
lib,
|
|
self,
|
|
nixosSystem,
|
|
}:
|
|
let
|
|
inherit
|
|
(import ./lib.nix {
|
|
inherit
|
|
pkgs
|
|
lib
|
|
self
|
|
nixosSystem
|
|
;
|
|
})
|
|
hive
|
|
runGroup
|
|
;
|
|
|
|
# Bare hive: the store and the mesh it needs, nothing else.
|
|
store = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "10.100.0.1/24";
|
|
snapshotStore.enable = true;
|
|
snapshotStore.port = 51822;
|
|
};
|
|
|
|
# The same with a wildcard where the mesh address goes.
|
|
storeOnWildcard = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "0.0.0.0/24";
|
|
snapshotStore.enable = true;
|
|
};
|
|
|
|
# The IPv6 wildcard.
|
|
storeOnWildcardV6 = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "::/64";
|
|
snapshotStore.enable = true;
|
|
};
|
|
|
|
socket = store.systemd.sockets.swarm-snapshot-store.socketConfig;
|
|
|
|
refusedAsWildcard =
|
|
m:
|
|
lib.any (
|
|
a: !a.assertion && lib.hasInfix "refuses a wildcard listen address" a.message
|
|
) m.assertions;
|
|
|
|
cases = [
|
|
{
|
|
# The wg-hive address does not exist when sockets.target binds, so
|
|
# without FreeBind the bind fails with EADDRNOTAVAIL and the receiver
|
|
# never listens. The unit still renders and evaluates either way, which
|
|
# is why only a rendered-config check can see it.
|
|
name = "the receiver socket may bind before the mesh interface has its address";
|
|
ok = socket.FreeBind or false == true;
|
|
}
|
|
{
|
|
# The bare IP and the configured port: the prefix length on
|
|
# `deploy.wireguard.address` must not leak into the listen address.
|
|
name = "the receiver socket listens on the mesh address and the configured port";
|
|
ok = socket.ListenStream == "10.100.0.1:51822";
|
|
}
|
|
{
|
|
# The control for the case below: it is the wildcard that trips the
|
|
# assertion, not the store being on.
|
|
name = "a mesh address on the store raises no wildcard refusal";
|
|
ok = !(refusedAsWildcard store);
|
|
}
|
|
{
|
|
# A wildcard bind is an unauthenticated remote write into agent state.
|
|
name = "a wildcard mesh address, IPv4 or IPv6, is refused";
|
|
ok = refusedAsWildcard storeOnWildcard && refusedAsWildcard storeOnWildcardV6;
|
|
}
|
|
];
|
|
in
|
|
runGroup "snapshot-store" cases
|