diff options
author | Michele Guerini Rocco <rnhmjoj@users.noreply.github.com> | 2021-05-19 13:36:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-19 13:36:04 +0200 |
commit | 376eabdac3c88b6993484bd344b28f966d35dbd4 (patch) | |
tree | 08d3e9fb11e11599685dfe247695bc5ceed80b91 /nixos/tests | |
parent | 7013a0f2791da4c38c7e6f56d48139aeb344991b (diff) | |
parent | 1e05d6d67f62d28b6c1e8c471491ad640e77b86a (diff) |
Merge pull request #123254 from rnhmjoj/ipsec
libreswan: 3.2 -> 4.4
Diffstat (limited to 'nixos/tests')
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/libreswan.nix | 134 |
2 files changed, 135 insertions, 0 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index f0b050829234f..5ff31ba6834c3 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -217,6 +217,7 @@ in latestKernel.login = handleTest ./login.nix { latestKernel = true; }; leaps = handleTest ./leaps.nix {}; lidarr = handleTest ./lidarr.nix {}; + libreswan = handleTest ./libreswan.nix {}; lightdm = handleTest ./lightdm.nix {}; limesurvey = handleTest ./limesurvey.nix {}; locate = handleTest ./locate.nix {}; diff --git a/nixos/tests/libreswan.nix b/nixos/tests/libreswan.nix new file mode 100644 index 0000000000000..17ae60af8eed4 --- /dev/null +++ b/nixos/tests/libreswan.nix @@ -0,0 +1,134 @@ +# This test sets up a host-to-host IPsec VPN between Alice and Bob, each on its +# own network and with Eve as the only route between each other. We check that +# Eve can eavesdrop the plaintext traffic between Alice and Bob, but once they +# enable the secure tunnel Eve's spying becomes ineffective. + +import ./make-test-python.nix ({ lib, pkgs, ... }: + +let + + # IPsec tunnel between Alice and Bob + tunnelConfig = { + services.libreswan.enable = true; + services.libreswan.connections.tunnel = + '' + leftid=@alice + left=fd::a + rightid=@bob + right=fd::b + authby=secret + auto=add + ''; + environment.etc."ipsec.d/tunnel.secrets" = + { text = ''@alice @bob : PSK "j1JbIi9WY07rxwcNQ6nbyThKCf9DGxWOyokXIQcAQUnafsNTUJxfsxwk9WYK8fHj"''; + mode = "600"; + }; + }; + + # Common network setup + baseNetwork = { + # shared hosts file + extraHosts = lib.mkVMOverride '' + fd::a alice + fd::b bob + fd::e eve + ''; + # remove all automatic addresses + useDHCP = false; + interfaces.eth1.ipv4.addresses = lib.mkVMOverride []; + interfaces.eth2.ipv4.addresses = lib.mkVMOverride []; + # open a port for testing + firewall.allowedUDPPorts = [ 1234 ]; + }; + + # Adds an address and route from a to b via Eve + addRoute = a: b: { + interfaces.eth1.ipv6.addresses = + [ { address = a; prefixLength = 64; } ]; + interfaces.eth1.ipv6.routes = + [ { address = b; prefixLength = 128; via = "fd::e"; } ]; + }; + +in + +{ + name = "libreswan"; + meta = with lib.maintainers; { + maintainers = [ rnhmjoj ]; + }; + + # Our protagonist + nodes.alice = { ... }: { + virtualisation.vlans = [ 1 ]; + networking = baseNetwork // addRoute "fd::a" "fd::b"; + } // tunnelConfig; + + # Her best friend + nodes.bob = { ... }: { + virtualisation.vlans = [ 2 ]; + networking = baseNetwork // addRoute "fd::b" "fd::a"; + } // tunnelConfig; + + # The malicious network operator + nodes.eve = { ... }: { + virtualisation.vlans = [ 1 2 ]; + networking = lib.mkMerge + [ baseNetwork + { interfaces.br0.ipv6.addresses = + [ { address = "fd::e"; prefixLength = 64; } ]; + bridges.br0.interfaces = [ "eth1" "eth2" ]; + } + ]; + environment.systemPackages = [ pkgs.tcpdump ]; + boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; + }; + + testScript = + '' + def alice_to_bob(msg: str): + """ + Sends a message as Alice to Bob + """ + bob.execute("nc -lu ::0 1234 >/tmp/msg &") + alice.sleep(1) + alice.succeed(f"echo '{msg}' | nc -uw 0 bob 1234") + bob.succeed(f"grep '{msg}' /tmp/msg") + + + def eavesdrop(): + """ + Starts eavesdropping on Alice and Bob + """ + match = "src host alice and dst host bob" + eve.execute(f"tcpdump -i br0 -c 1 -Avv {match} >/tmp/log &") + + + start_all() + + with subtest("Network is up"): + alice.wait_until_succeeds("ping -c1 bob") + + with subtest("Eve can eavesdrop cleartext traffic"): + eavesdrop() + alice_to_bob("I secretly love turnip") + eve.sleep(1) + eve.succeed("grep turnip /tmp/log") + + with subtest("Libreswan is ready"): + alice.wait_for_unit("ipsec") + bob.wait_for_unit("ipsec") + alice.succeed("ipsec verify 1>&2") + + with subtest("Alice and Bob can start the tunnel"): + alice.execute("ipsec auto --start tunnel &") + bob.succeed("ipsec auto --start tunnel") + # apparently this is needed to "wake" the tunnel + bob.execute("ping -c1 alice") + + with subtest("Eve no longer can eavesdrop"): + eavesdrop() + alice_to_bob("Just kidding, I actually like rhubarb") + eve.sleep(1) + eve.fail("grep rhubarb /tmp/log") + ''; +}) |