From 37e3cadb8b20a1a057c0996885f88be2e2f081e1 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 31 Jul 2020 20:44:59 +0200 Subject: [PATCH] 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 --- nixos/tests/systemd-networkd-vrf.nix | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/nixos/tests/systemd-networkd-vrf.nix b/nixos/tests/systemd-networkd-vrf.nix index af7813a2e60..123e1f26b51 100644 --- a/nixos/tests/systemd-networkd-vrf.nix +++ b/nixos/tests/systemd-networkd-vrf.nix @@ -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.