1 { system ? builtins.currentSystem
3 , pkgs ? import ../.. { inherit system config; }
4 , systemdStage1 ? false
7 import ../make-test-python.nix ({ lib, ...}:
10 name = "initrd-network-openvpn";
15 # Inlining of the shared secret for the
16 # OpenVPN server and client
20 ${lib.readFile ./shared.key}
27 # Minimal test case to check a successful boot, even with invalid config
31 boot.initrd.systemd.enable = systemdStage1;
32 boot.initrd.network = {
36 configuration = builtins.toFile "initrd.ovpn" "";
45 virtualisation.useBootLoader = true;
46 virtualisation.vlans = [ 1 ];
49 systemd.enable = systemdStage1;
50 systemd.extraBin.nc = "${pkgs.busybox}/bin/nc";
51 systemd.services.nc = {
52 requiredBy = ["initrd.target"];
53 after = ["network.target"];
55 ExecStart = "/bin/nc -p 1234 -lke /bin/echo TESTVALUE";
60 # This command does not fork to keep the VM in the state where
61 # only the initramfs is loaded
62 preLVMCommands = lib.mkIf (!systemdStage1)
64 /bin/nc -p 1234 -lke /bin/echo TESTVALUE
70 # Work around udhcpc only getting a lease on eth0
71 postCommands = lib.mkIf (!systemdStage1)
73 /bin/ip addr add 192.168.1.2/24 dev eth1
76 # Example configuration for OpenVPN
77 # This is the main reason for this test
80 configuration = "${./initrd.ovpn}";
86 # VPN server and gateway for ovpnclient between vlan 1 and 2
90 virtualisation.vlans = [ 1 2 ];
92 # Enable NAT and forward port 12345 to port 1234
95 internalInterfaces = [ "tun0" ];
96 externalInterface = "eth2";
97 forwardPorts = [ { destination = "10.8.0.2:1234";
98 sourcePort = 12345; } ];
101 # Trust tun0 and allow the VPN Server to be reached
102 networking.firewall = {
103 trustedInterfaces = [ "tun0" ];
104 allowedUDPPorts = [ 1194 ];
107 # Minimal OpenVPN server configuration
108 services.openvpn.servers.testserver =
112 ifconfig 10.8.0.1 10.8.0.2
119 # Client that resides in the "external" VLAN
123 virtualisation.vlans = [ 2 ];
130 # Minimal test case, checks whether enabling (with invalid config) harms
132 with subtest("Check for successful boot with broken openvpn config"):
134 # If we get to multi-user.target, we booted successfully
135 minimalboot.wait_for_unit("multi-user.target")
136 minimalboot.shutdown()
138 # Elaborated test case where the ovpnclient (where this module is used)
139 # can be reached by testclient only over ovpnserver.
140 # This is an indirect test for success.
141 with subtest("Check for connection from initrd VPN client, config as file"):
146 # Wait until the OpenVPN Server is available
147 ovpnserver.wait_for_unit("openvpn-testserver.service")
148 ovpnserver.succeed("ping -c 1 10.8.0.1")
150 # Wait for the client to connect
151 ovpnserver.wait_until_succeeds("ping -c 1 10.8.0.2")
153 # Wait until the testclient has network
154 testclient.wait_for_unit("network.target")
156 # Check that ovpnclient is reachable over vlan 1
157 ovpnserver.succeed("nc -w 2 192.168.1.2 1234 | grep -q TESTVALUE")
159 # Check that ovpnclient is reachable over tun0
160 ovpnserver.succeed("nc -w 2 10.8.0.2 1234 | grep -q TESTVALUE")
162 # Check that ovpnclient is reachable from testclient over the gateway
163 testclient.succeed("nc -w 2 192.168.2.3 12345 | grep -q TESTVALUE")