nixos/systemd-networkd-vrf: implement working TCP test on a 5.x kernel

By design, VRFs allow route-leaking for forwarded packages, but not for
local processes using a socket. While it was possible to leak such TCP
traffic through a VRF on a 4.x kernel, this behavior was considered
wrong and got fixed in Linux 5.x[1].

From now on, local unix sockets must run in the VRF itself using
`ip vrf exec`[2] which basically injects a BPF program into the VRF and
drops elevated networking capabilities by default for the specified
command.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3c82a21f4320c8d54cf6456b27c8d49e5ffb722e
[2] https://man7.org/linux/man-pages/man8/ip-vrf.8.html
This commit is contained in:
Maximilian Bosch 2020-07-31 20:44:59 +02:00
parent 8738de2346
commit 37e3cadb8b
No known key found for this signature in database
GPG key ID: 091DBF4D1FC46B8E

View file

@ -194,18 +194,16 @@ in {
client.succeed("ping -c5 192.168.1.2")
client.succeed("ping -c5 192.168.2.3")
# Test whether SSH through a VRF IP is possible.
# (Note: this seems to be an issue on Linux 5.x, so I decided to add this to
# ensure that we catch this when updating the default kernel).
# with subtest("tcp traffic through vrf works"):
# node1.wait_for_open_port(22)
# client.succeed(
# "cat ${snakeOilPrivateKey} > privkey.snakeoil"
# )
# client.succeed("chmod 600 privkey.snakeoil")
# client.succeed(
# "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil root@192.168.1.2 true"
# )
# Test whether TCP through a VRF IP is possible.
with subtest("tcp traffic through vrf works"):
node1.wait_for_open_port(22)
client.succeed(
"cat ${snakeOilPrivateKey} > privkey.snakeoil"
)
client.succeed("chmod 600 privkey.snakeoil")
client.succeed(
"ulimit -l 2048; ip vrf exec vrf1 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil root@192.168.1.2 true"
)
# Only configured routes through the VRF from the main routing table should
# work. Additional IPs are only reachable when binding to the vrf interface.