at 25.11-pre 6.6 kB view raw
1let 2 generateNodeConf = 3 { 4 lib, 5 pkgs, 6 config, 7 privk, 8 pubk, 9 systemdCreds, 10 peerId, 11 nodeId, 12 ... 13 }: 14 { 15 imports = [ common/user-account.nix ]; 16 systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; 17 networking.useNetworkd = true; 18 networking.useDHCP = false; 19 networking.firewall.enable = false; 20 virtualisation.vlans = [ 1 ]; 21 environment.systemPackages = with pkgs; [ wireguard-tools ]; 22 environment.etc."credstore/network.wireguard.private" = lib.mkIf systemdCreds { text = privk; }; 23 systemd.network = { 24 enable = true; 25 config = { 26 routeTables.custom = 23; 27 }; 28 netdevs = { 29 "90-wg0" = { 30 netdevConfig = { 31 Kind = "wireguard"; 32 Name = "wg0"; 33 }; 34 wireguardConfig = { 35 # Test storing wireguard private key using systemd credentials. 36 PrivateKey = lib.mkIf systemdCreds "@network.wireguard.private"; 37 38 # NOTE: we're storing the wireguard private key in the 39 # store for this test. Do not do this in the real 40 # world. Keep in mind the nix store is 41 # world-readable. 42 PrivateKeyFile = lib.mkIf (!systemdCreds) (pkgs.writeText "wg0-priv" privk); 43 ListenPort = 51820; 44 FirewallMark = 42; 45 }; 46 wireguardPeers = [ 47 { 48 Endpoint = "192.168.1.${peerId}:51820"; 49 PublicKey = pubk; 50 PresharedKeyFile = pkgs.writeText "psk.key" "yTL3sCOL33Wzi6yCnf9uZQl/Z8laSE+zwpqOHC4HhFU="; 51 AllowedIPs = [ "10.0.0.${peerId}/32" ]; 52 PersistentKeepalive = 15; 53 } 54 ]; 55 }; 56 }; 57 networks = { 58 "99-nope" = { 59 matchConfig.Name = "eth*"; 60 linkConfig.Unmanaged = true; 61 }; 62 "90-wg0" = { 63 matchConfig = { 64 Name = "wg0"; 65 }; 66 address = [ "10.0.0.${nodeId}/32" ]; 67 routes = [ 68 { 69 Gateway = "10.0.0.${nodeId}"; 70 Destination = "10.0.0.0/24"; 71 } 72 { 73 Gateway = "10.0.0.${nodeId}"; 74 Destination = "10.0.0.0/24"; 75 Table = "custom"; 76 } 77 ]; 78 }; 79 "30-eth1" = { 80 matchConfig = { 81 Name = "eth1"; 82 }; 83 address = [ 84 "192.168.1.${nodeId}/24" 85 "fe80::${nodeId}/64" 86 ]; 87 routingPolicyRules = [ 88 { 89 Table = 10; 90 IncomingInterface = "eth1"; 91 Family = "both"; 92 } 93 { 94 Table = 20; 95 OutgoingInterface = "eth1"; 96 } 97 { 98 Table = 30; 99 From = "192.168.1.1"; 100 To = "192.168.1.2"; 101 SourcePort = 666; 102 DestinationPort = 667; 103 } 104 { 105 Table = 40; 106 IPProtocol = "tcp"; 107 InvertRule = true; 108 } 109 { 110 Table = 50; 111 IncomingInterface = "eth1"; 112 Family = "ipv4"; 113 } 114 { 115 Table = 60; 116 FirewallMark = 4; 117 } 118 { 119 Table = 70; 120 FirewallMark = "16/0x1f"; 121 } 122 ]; 123 }; 124 }; 125 }; 126 }; 127in 128import ./make-test-python.nix ( 129 { pkgs, ... }: 130 { 131 name = "networkd"; 132 meta = with pkgs.lib.maintainers; { 133 maintainers = [ picnoir ]; 134 }; 135 nodes = { 136 node1 = 137 { pkgs, ... }@attrs: 138 let 139 localConf = { 140 privk = "GDiXWlMQKb379XthwX0haAbK6hTdjblllpjGX0heP00="; 141 pubk = "iRxpqj42nnY0Qz8MAQbSm7bXxXP5hkPqWYIULmvW+EE="; 142 systemdCreds = false; 143 nodeId = "1"; 144 peerId = "2"; 145 }; 146 in 147 generateNodeConf (attrs // localConf); 148 149 node2 = 150 { pkgs, ... }@attrs: 151 let 152 localConf = { 153 privk = "eHxSI2jwX/P4AOI0r8YppPw0+4NZnjOxfbS5mt06K2k="; 154 pubk = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g="; 155 systemdCreds = true; 156 nodeId = "2"; 157 peerId = "1"; 158 }; 159 in 160 generateNodeConf (attrs // localConf); 161 }; 162 testScript = '' 163 start_all() 164 node1.systemctl("start systemd-networkd-wait-online@eth1.service") 165 node1.systemctl("start systemd-networkd-wait-online.service") 166 node1.wait_for_unit("systemd-networkd-wait-online@eth1.service") 167 node1.wait_for_unit("systemd-networkd-wait-online.service") 168 node2.systemctl("start systemd-networkd-wait-online@eth1.service") 169 node2.systemctl("start systemd-networkd-wait-online.service") 170 node2.wait_for_unit("systemd-networkd-wait-online@eth1.service") 171 node2.wait_for_unit("systemd-networkd-wait-online.service") 172 173 # ================================ 174 # Networkd Config 175 # ================================ 176 node1.succeed("grep RouteTable=custom:23 /etc/systemd/networkd.conf") 177 node1.succeed("sudo ip route show table custom | grep '10.0.0.0/24 via 10.0.0.1 dev wg0 proto static'") 178 179 # ================================ 180 # Wireguard 181 # ================================ 182 node1.succeed("ping -c 5 10.0.0.2") 183 node2.succeed("ping -c 5 10.0.0.1") 184 # Is the fwmark set? 185 node2.succeed("wg | grep -q 42") 186 187 # ================================ 188 # Routing Policies 189 # ================================ 190 # Testing all the routingPolicyRuleConfig members: 191 # Table + IncomingInterface 192 node1.succeed("sudo ip rule | grep 'from all iif eth1 lookup 10'") 193 # OutgoingInterface 194 node1.succeed("sudo ip rule | grep 'from all oif eth1 lookup 20'") 195 # From + To + SourcePort + DestinationPort 196 node1.succeed( 197 "sudo ip rule | grep 'from 192.168.1.1 to 192.168.1.2 sport 666 dport 667 lookup 30'" 198 ) 199 # IPProtocol + InvertRule 200 node1.succeed("sudo ip rule | grep 'not from all ipproto tcp lookup 40'") 201 # FirewallMark without a mask 202 node1.succeed("sudo ip rule | grep 'from all fwmark 0x4 lookup 60'") 203 # FirewallMark with a mask 204 node1.succeed("sudo ip rule | grep 'from all fwmark 0x10/0x1f lookup 70'") 205 ''; 206 } 207)