1{
2 lib,
3 kernelPackages ? null,
4 useNetworkd ? false,
5 ...
6}:
7let
8 wg-snakeoil-keys = import ./snakeoil-keys.nix;
9in
10{
11 name = "wireguard-dynamic-refresh";
12 meta.maintainers = with lib.maintainers; [ majiir ];
13
14 nodes = {
15 server =
16 { lib, pkgs, ... }:
17 {
18 virtualisation.vlans = [
19 1
20 2
21 ];
22 boot.kernelPackages = lib.mkIf (kernelPackages != null) (kernelPackages pkgs);
23 networking.firewall.allowedUDPPorts = [ 23542 ];
24 networking.useDHCP = false;
25 networking.wireguard.useNetworkd = useNetworkd;
26 networking.wireguard.interfaces.wg0 = {
27 ips = [ "10.23.42.1/32" ];
28 listenPort = 23542;
29
30 # !!! Don't do this with real keys. The /nix store is world-readable!
31 privateKeyFile = toString (pkgs.writeText "privateKey" wg-snakeoil-keys.peer0.privateKey);
32
33 peers = lib.singleton {
34 allowedIPs = [ "10.23.42.2/32" ];
35
36 inherit (wg-snakeoil-keys.peer1) publicKey;
37 };
38 };
39 };
40
41 client =
42 {
43 nodes,
44 lib,
45 pkgs,
46 ...
47 }:
48 {
49 virtualisation.vlans = [
50 1
51 2
52 ];
53 boot.kernelPackages = lib.mkIf (kernelPackages != null) (kernelPackages pkgs);
54 networking.useDHCP = false;
55 networking.wireguard.useNetworkd = useNetworkd;
56 networking.wireguard.interfaces.wg0 = {
57 ips = [ "10.23.42.2/32" ];
58
59 # !!! Don't do this with real keys. The /nix store is world-readable!
60 privateKeyFile = toString (pkgs.writeText "privateKey" wg-snakeoil-keys.peer1.privateKey);
61
62 dynamicEndpointRefreshSeconds = 2;
63
64 peers = lib.singleton {
65 allowedIPs = [
66 "0.0.0.0/0"
67 "::/0"
68 ];
69 endpoint = "server:23542";
70
71 inherit (wg-snakeoil-keys.peer0) publicKey;
72 };
73 };
74
75 specialisation.update-hosts.configuration = {
76 networking.extraHosts =
77 let
78 testCfg = nodes.server.virtualisation.test;
79 in
80 lib.mkForce "192.168.2.${toString testCfg.nodeNumber} ${testCfg.nodeName}";
81 };
82 };
83 };
84
85 testScript =
86 { nodes, ... }:
87 ''
88 start_all()
89
90 server.systemctl("start network-online.target")
91 server.wait_for_unit("network-online.target")
92
93 client.systemctl("start network-online.target")
94 client.wait_for_unit("network-online.target")
95
96 client.succeed("ping -n -w 1 -c 1 10.23.42.1")
97
98 client.succeed("ip link set down eth1")
99
100 client.fail("ping -n -w 1 -c 1 10.23.42.1")
101
102 with client.nested("update hosts file"):
103 client.succeed("${nodes.client.system.build.toplevel}/specialisation/update-hosts/bin/switch-to-configuration test")
104
105 client.succeed("sleep 5 && ping -n -w 1 -c 1 10.23.42.1")
106 '';
107}