at master 6.5 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 128{ pkgs, ... }: 129{ 130 name = "networkd"; 131 meta = with pkgs.lib.maintainers; { 132 maintainers = [ picnoir ]; 133 }; 134 nodes = { 135 node1 = 136 { pkgs, ... }@attrs: 137 let 138 localConf = { 139 privk = "GDiXWlMQKb379XthwX0haAbK6hTdjblllpjGX0heP00="; 140 pubk = "iRxpqj42nnY0Qz8MAQbSm7bXxXP5hkPqWYIULmvW+EE="; 141 systemdCreds = false; 142 nodeId = "1"; 143 peerId = "2"; 144 }; 145 in 146 generateNodeConf (attrs // localConf); 147 148 node2 = 149 { pkgs, ... }@attrs: 150 let 151 localConf = { 152 privk = "eHxSI2jwX/P4AOI0r8YppPw0+4NZnjOxfbS5mt06K2k="; 153 pubk = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g="; 154 systemdCreds = true; 155 nodeId = "2"; 156 peerId = "1"; 157 }; 158 in 159 generateNodeConf (attrs // localConf); 160 }; 161 testScript = '' 162 start_all() 163 node1.systemctl("start systemd-networkd-wait-online@eth1.service") 164 node1.systemctl("start systemd-networkd-wait-online.service") 165 node1.wait_for_unit("systemd-networkd-wait-online@eth1.service") 166 node1.wait_for_unit("systemd-networkd-wait-online.service") 167 node2.systemctl("start systemd-networkd-wait-online@eth1.service") 168 node2.systemctl("start systemd-networkd-wait-online.service") 169 node2.wait_for_unit("systemd-networkd-wait-online@eth1.service") 170 node2.wait_for_unit("systemd-networkd-wait-online.service") 171 172 # ================================ 173 # Networkd Config 174 # ================================ 175 node1.succeed("grep RouteTable=custom:23 /etc/systemd/networkd.conf") 176 node1.succeed("sudo ip route show table custom | grep '10.0.0.0/24 via 10.0.0.1 dev wg0 proto static'") 177 178 # ================================ 179 # Wireguard 180 # ================================ 181 node1.succeed("ping -c 5 10.0.0.2") 182 node2.succeed("ping -c 5 10.0.0.1") 183 # Is the fwmark set? 184 node2.succeed("wg | grep -q 42") 185 186 # ================================ 187 # Routing Policies 188 # ================================ 189 # Testing all the routingPolicyRuleConfig members: 190 # Table + IncomingInterface 191 node1.succeed("sudo ip rule | grep 'from all iif eth1 lookup 10'") 192 # OutgoingInterface 193 node1.succeed("sudo ip rule | grep 'from all oif eth1 lookup 20'") 194 # From + To + SourcePort + DestinationPort 195 node1.succeed( 196 "sudo ip rule | grep 'from 192.168.1.1 to 192.168.1.2 sport 666 dport 667 lookup 30'" 197 ) 198 # IPProtocol + InvertRule 199 node1.succeed("sudo ip rule | grep 'not from all ipproto tcp lookup 40'") 200 # FirewallMark without a mask 201 node1.succeed("sudo ip rule | grep 'from all fwmark 0x4 lookup 60'") 202 # FirewallMark with a mask 203 node1.succeed("sudo ip rule | grep 'from all fwmark 0x10/0x1f lookup 70'") 204 ''; 205}