at 22.05-pre 7.8 kB view raw
1import ./make-test-python.nix ({ pkgs, lib, ... }: let 2 3 # We'll need to be able to trade cert files between nodes via scp. 4 inherit (import ./ssh-keys.nix pkgs) 5 snakeOilPrivateKey snakeOilPublicKey; 6 7 makeNebulaNode = { config, ... }: name: extraConfig: lib.mkMerge [ 8 { 9 # Expose nebula for doing cert signing. 10 environment.systemPackages = [ pkgs.nebula ]; 11 users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; 12 services.openssh.enable = true; 13 14 services.nebula.networks.smoke = { 15 # Note that these paths won't exist when the machine is first booted. 16 ca = "/etc/nebula/ca.crt"; 17 cert = "/etc/nebula/${name}.crt"; 18 key = "/etc/nebula/${name}.key"; 19 listen = { host = "0.0.0.0"; port = 4242; }; 20 }; 21 } 22 extraConfig 23 ]; 24 25in 26{ 27 name = "nebula"; 28 29 nodes = { 30 31 lighthouse = { ... } @ args: 32 makeNebulaNode args "lighthouse" { 33 networking.interfaces.eth1.ipv4.addresses = [{ 34 address = "192.168.1.1"; 35 prefixLength = 24; 36 }]; 37 38 services.nebula.networks.smoke = { 39 isLighthouse = true; 40 firewall = { 41 outbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 42 inbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 43 }; 44 }; 45 }; 46 47 node2 = { ... } @ args: 48 makeNebulaNode args "node2" { 49 networking.interfaces.eth1.ipv4.addresses = [{ 50 address = "192.168.1.2"; 51 prefixLength = 24; 52 }]; 53 54 services.nebula.networks.smoke = { 55 staticHostMap = { "10.0.100.1" = [ "192.168.1.1:4242" ]; }; 56 isLighthouse = false; 57 lighthouses = [ "10.0.100.1" ]; 58 firewall = { 59 outbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 60 inbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 61 }; 62 }; 63 }; 64 65 node3 = { ... } @ args: 66 makeNebulaNode args "node3" { 67 networking.interfaces.eth1.ipv4.addresses = [{ 68 address = "192.168.1.3"; 69 prefixLength = 24; 70 }]; 71 72 services.nebula.networks.smoke = { 73 staticHostMap = { "10.0.100.1" = [ "192.168.1.1:4242" ]; }; 74 isLighthouse = false; 75 lighthouses = [ "10.0.100.1" ]; 76 firewall = { 77 outbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 78 inbound = [ { port = "any"; proto = "any"; host = "lighthouse"; } ]; 79 }; 80 }; 81 }; 82 83 node4 = { ... } @ args: 84 makeNebulaNode args "node4" { 85 networking.interfaces.eth1.ipv4.addresses = [{ 86 address = "192.168.1.4"; 87 prefixLength = 24; 88 }]; 89 90 services.nebula.networks.smoke = { 91 enable = true; 92 staticHostMap = { "10.0.100.1" = [ "192.168.1.1:4242" ]; }; 93 isLighthouse = false; 94 lighthouses = [ "10.0.100.1" ]; 95 firewall = { 96 outbound = [ { port = "any"; proto = "any"; host = "lighthouse"; } ]; 97 inbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 98 }; 99 }; 100 }; 101 102 node5 = { ... } @ args: 103 makeNebulaNode args "node5" { 104 networking.interfaces.eth1.ipv4.addresses = [{ 105 address = "192.168.1.5"; 106 prefixLength = 24; 107 }]; 108 109 services.nebula.networks.smoke = { 110 enable = false; 111 staticHostMap = { "10.0.100.1" = [ "192.168.1.1:4242" ]; }; 112 isLighthouse = false; 113 lighthouses = [ "10.0.100.1" ]; 114 firewall = { 115 outbound = [ { port = "any"; proto = "any"; host = "lighthouse"; } ]; 116 inbound = [ { port = "any"; proto = "any"; host = "any"; } ]; 117 }; 118 }; 119 }; 120 121 }; 122 123 testScript = let 124 125 setUpPrivateKey = name: '' 126 ${name}.succeed( 127 "mkdir -p /root/.ssh", 128 "chown 700 /root/.ssh", 129 "cat '${snakeOilPrivateKey}' > /root/.ssh/id_snakeoil", 130 "chown 600 /root/.ssh/id_snakeoil", 131 ) 132 ''; 133 134 # From what I can tell, StrictHostKeyChecking=no is necessary for ssh to work between machines. 135 sshOpts = "-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oIdentityFile=/root/.ssh/id_snakeoil"; 136 137 restartAndCheckNebula = name: ip: '' 138 ${name}.systemctl("restart nebula@smoke.service") 139 ${name}.succeed("ping -c5 ${ip}") 140 ''; 141 142 # Create a keypair on the client node, then use the public key to sign a cert on the lighthouse. 143 signKeysFor = name: ip: '' 144 lighthouse.wait_for_unit("sshd.service") 145 ${name}.wait_for_unit("sshd.service") 146 ${name}.succeed( 147 "mkdir -p /etc/nebula", 148 "nebula-cert keygen -out-key /etc/nebula/${name}.key -out-pub /etc/nebula/${name}.pub", 149 "scp ${sshOpts} /etc/nebula/${name}.pub 192.168.1.1:/tmp/${name}.pub", 150 ) 151 lighthouse.succeed( 152 'nebula-cert sign -ca-crt /etc/nebula/ca.crt -ca-key /etc/nebula/ca.key -name "${name}" -groups "${name}" -ip "${ip}" -in-pub /tmp/${name}.pub -out-crt /tmp/${name}.crt', 153 ) 154 ${name}.succeed( 155 "scp ${sshOpts} 192.168.1.1:/tmp/${name}.crt /etc/nebula/${name}.crt", 156 "scp ${sshOpts} 192.168.1.1:/etc/nebula/ca.crt /etc/nebula/ca.crt", 157 ) 158 ''; 159 160 in '' 161 start_all() 162 163 # Create the certificate and sign the lighthouse's keys. 164 ${setUpPrivateKey "lighthouse"} 165 lighthouse.succeed( 166 "mkdir -p /etc/nebula", 167 'nebula-cert ca -name "Smoke Test" -out-crt /etc/nebula/ca.crt -out-key /etc/nebula/ca.key', 168 'nebula-cert sign -ca-crt /etc/nebula/ca.crt -ca-key /etc/nebula/ca.key -name "lighthouse" -groups "lighthouse" -ip "10.0.100.1/24" -out-crt /etc/nebula/lighthouse.crt -out-key /etc/nebula/lighthouse.key', 169 ) 170 171 # Reboot the lighthouse and verify that the nebula service comes up on boot. 172 # Since rebooting takes a while, we'll just restart the service on the other nodes. 173 lighthouse.shutdown() 174 lighthouse.start() 175 lighthouse.wait_for_unit("nebula@smoke.service") 176 lighthouse.succeed("ping -c5 10.0.100.1") 177 178 # Create keys for node2's nebula service and test that it comes up. 179 ${setUpPrivateKey "node2"} 180 ${signKeysFor "node2" "10.0.100.2/24"} 181 ${restartAndCheckNebula "node2" "10.0.100.2"} 182 183 # Create keys for node3's nebula service and test that it comes up. 184 ${setUpPrivateKey "node3"} 185 ${signKeysFor "node3" "10.0.100.3/24"} 186 ${restartAndCheckNebula "node3" "10.0.100.3"} 187 188 # Create keys for node4's nebula service and test that it comes up. 189 ${setUpPrivateKey "node4"} 190 ${signKeysFor "node4" "10.0.100.4/24"} 191 ${restartAndCheckNebula "node4" "10.0.100.4"} 192 193 # Create keys for node4's nebula service and test that it does not come up. 194 ${setUpPrivateKey "node5"} 195 ${signKeysFor "node5" "10.0.100.5/24"} 196 node5.fail("systemctl status nebula@smoke.service") 197 node5.fail("ping -c5 10.0.100.5") 198 199 # The lighthouse can ping node2 and node3 but not node5 200 lighthouse.succeed("ping -c3 10.0.100.2") 201 lighthouse.succeed("ping -c3 10.0.100.3") 202 lighthouse.fail("ping -c3 10.0.100.5") 203 204 # node2 can ping the lighthouse, but not node3 because of its inbound firewall 205 node2.succeed("ping -c3 10.0.100.1") 206 node2.fail("ping -c3 10.0.100.3") 207 208 # node3 can ping the lighthouse and node2 209 node3.succeed("ping -c3 10.0.100.1") 210 node3.succeed("ping -c3 10.0.100.2") 211 212 # node4 can ping the lighthouse but not node2 or node3 213 node4.succeed("ping -c3 10.0.100.1") 214 node4.fail("ping -c3 10.0.100.2") 215 node4.fail("ping -c3 10.0.100.3") 216 217 # node2 can ping node3 now that node3 pinged it first 218 node2.succeed("ping -c3 10.0.100.3") 219 # node4 can ping node2 if node2 pings it first 220 node2.succeed("ping -c3 10.0.100.4") 221 node4.succeed("ping -c3 10.0.100.2") 222 ''; 223})