| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | let | 
					
						
							|  |  |  |   aliceIp6 = "200:3b91:b2d8:e708:fbf3:f06:fdd5:90d0"; | 
					
						
							|  |  |  |   aliceKeys = { | 
					
						
							|  |  |  |     EncryptionPublicKey = "13e23986fe76bc3966b42453f479bc563348b7ff76633b7efcb76e185ec7652f"; | 
					
						
							|  |  |  |     EncryptionPrivateKey = "9f86947b15e86f9badac095517a1982e39a2db37ca726357f95987b898d82208"; | 
					
						
							|  |  |  |     SigningPublicKey = "e2c43349083bc1e998e4ec4535b4c6a8f44ca9a5a8e07336561267253b2be5f4"; | 
					
						
							|  |  |  |     SigningPrivateKey = "fe3add8da35316c05f6d90d3ca79bd2801e6ccab6d37e5339fef4152589398abe2c43349083bc1e998e4ec4535b4c6a8f44ca9a5a8e07336561267253b2be5f4"; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   bobIp6 = "201:ebbd:bde9:f138:c302:4afa:1fb6:a19a"; | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  |   bobPrefix = "301:ebbd:bde9:f138"; | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |   bobConfig = { | 
					
						
							|  |  |  |     InterfacePeers = { | 
					
						
							|  |  |  |       eth1 = [ "tcp://192.168.1.200:12345" ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     MulticastInterfaces = [ "eth1" ]; | 
					
						
							|  |  |  |     LinkLocalTCPPort = 54321; | 
					
						
							|  |  |  |     EncryptionPublicKey = "c99d6830111e12d1b004c52fe9e5a2eef0f6aefca167aca14589a370b7373279"; | 
					
						
							|  |  |  |     EncryptionPrivateKey = "2e698a53d3fdce5962d2ff37de0fe77742a5c8b56cd8259f5da6aa792f6e8ba3"; | 
					
						
							|  |  |  |     SigningPublicKey = "de111da0ec781e45bf6c63ecb45a78c24d7d4655abfaeea83b26c36eb5c0fd5b"; | 
					
						
							|  |  |  |     SigningPrivateKey = "2a6c21550f3fca0331df50668ffab66b6dce8237bcd5728e571e8033b363e247de111da0ec781e45bf6c63ecb45a78c24d7d4655abfaeea83b26c36eb5c0fd5b"; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  |   danIp6 = bobPrefix + "::2"; | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  | in import ./make-test-python.nix ({ pkgs, ...} : { | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |   name = "yggdrasil"; | 
					
						
							| 
									
										
										
										
											2021-01-10 20:08:30 +01:00
										 |  |  |   meta = with pkgs.lib.maintainers; { | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |     maintainers = [ gazally ]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nodes = rec { | 
					
						
							|  |  |  |     # Alice is listening for peerings on a specified port, | 
					
						
							|  |  |  |     # but has multicast peering disabled.  Alice has part of her | 
					
						
							|  |  |  |     # yggdrasil config in Nix and part of it in a file. | 
					
						
							|  |  |  |     alice = | 
					
						
							|  |  |  |       { ... }: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           interfaces.eth1.ipv4.addresses = [{ | 
					
						
							|  |  |  |             address = "192.168.1.200"; | 
					
						
							|  |  |  |             prefixLength = 24; | 
					
						
							|  |  |  |           }]; | 
					
						
							|  |  |  |           firewall.allowedTCPPorts = [ 80 12345 ]; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         services.httpd.enable = true; | 
					
						
							|  |  |  |         services.httpd.adminAddr = "foo@example.org"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         services.yggdrasil = { | 
					
						
							|  |  |  |           enable = true; | 
					
						
							|  |  |  |           config = { | 
					
						
							|  |  |  |             Listen = ["tcp://0.0.0.0:12345"]; | 
					
						
							|  |  |  |             MulticastInterfaces = [ ]; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           configFile = toString (pkgs.writeTextFile { | 
					
						
							|  |  |  |                          name = "yggdrasil-alice-conf"; | 
					
						
							|  |  |  |                          text = builtins.toJSON aliceKeys; | 
					
						
							|  |  |  |                        }); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Bob is set up to peer with Alice, and also to do local multicast | 
					
						
							|  |  |  |     # peering.  Bob's yggdrasil config is in a file. | 
					
						
							|  |  |  |     bob = | 
					
						
							|  |  |  |       { ... }: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         networking.firewall.allowedTCPPorts = [ 54321 ]; | 
					
						
							|  |  |  |         services.yggdrasil = { | 
					
						
							|  |  |  |           enable = true; | 
					
						
							|  |  |  |           openMulticastPort = true; | 
					
						
							|  |  |  |           configFile = toString (pkgs.writeTextFile { | 
					
						
							|  |  |  |                          name = "yggdrasil-bob-conf"; | 
					
						
							|  |  |  |                          text = builtins.toJSON bobConfig; | 
					
						
							|  |  |  |                        }); | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |         boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           bridges.br0.interfaces = [ ]; | 
					
						
							|  |  |  |           interfaces.br0 = { | 
					
						
							|  |  |  |             ipv6.addresses = [{ | 
					
						
							|  |  |  |               address = bobPrefix + "::1"; | 
					
						
							|  |  |  |               prefixLength = 64; | 
					
						
							|  |  |  |             }]; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # dan is a node inside a container running on bob's host. | 
					
						
							|  |  |  |         containers.dan = { | 
					
						
							|  |  |  |           autoStart = true; | 
					
						
							|  |  |  |           privateNetwork = true; | 
					
						
							|  |  |  |           hostBridge = "br0"; | 
					
						
							|  |  |  |           config = { config, pkgs, ... }: { | 
					
						
							|  |  |  |             networking.interfaces.eth0.ipv6 = { | 
					
						
							|  |  |  |               addresses = [{ | 
					
						
							|  |  |  |                 address = bobPrefix + "::2"; | 
					
						
							|  |  |  |                 prefixLength = 64; | 
					
						
							|  |  |  |               }]; | 
					
						
							|  |  |  |               routes = [{ | 
					
						
							|  |  |  |                 address = "200::"; | 
					
						
							|  |  |  |                 prefixLength = 7; | 
					
						
							|  |  |  |                 via = bobPrefix + "::1"; | 
					
						
							|  |  |  |               }]; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |             services.httpd.enable = true; | 
					
						
							|  |  |  |             services.httpd.adminAddr = "foo@example.org"; | 
					
						
							|  |  |  |             networking.firewall.allowedTCPPorts = [ 80 ]; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Carol only does local peering.  Carol's yggdrasil config is all Nix. | 
					
						
							|  |  |  |     carol = | 
					
						
							|  |  |  |       { ... }: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         networking.firewall.allowedTCPPorts = [ 43210 ]; | 
					
						
							|  |  |  |         services.yggdrasil = { | 
					
						
							|  |  |  |           enable = true; | 
					
						
							|  |  |  |           denyDhcpcdInterfaces = [ "ygg0" ]; | 
					
						
							|  |  |  |           config = { | 
					
						
							|  |  |  |             IfTAPMode = true; | 
					
						
							| 
									
										
										
										
											2019-11-16 12:57:56 +01:00
										 |  |  |             IfName = "ygg0"; | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |             MulticastInterfaces = [ "eth1" ]; | 
					
						
							|  |  |  |             LinkLocalTCPPort = 43210; | 
					
						
							|  |  |  |           }; | 
					
						
							| 
									
										
										
										
											2020-05-03 16:00:31 +05:30
										 |  |  |           persistentKeys = true; | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   testScript = | 
					
						
							|  |  |  |     ''
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       import re | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |       # Give Alice a head start so she is ready when Bob calls. | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       alice.start() | 
					
						
							|  |  |  |       alice.wait_for_unit("yggdrasil.service") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       bob.start() | 
					
						
							|  |  |  |       carol.start() | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  |       bob.wait_for_unit("default.target") | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       carol.wait_for_unit("yggdrasil.service") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       ip_addr_show = "ip -o -6 addr show dev ygg0 scope global" | 
					
						
							|  |  |  |       carol.wait_until_succeeds(f"[ `{ip_addr_show} | grep -v tentative | wc -l` -ge 1 ]") | 
					
						
							|  |  |  |       carol_ip6 = re.split(" +|/", carol.succeed(ip_addr_show))[3] | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # If Alice can talk to Carol, then Bob's outbound peering and Carol's | 
					
						
							|  |  |  |       # local peering have succeeded and everybody is connected. | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       alice.wait_until_succeeds(f"ping -c 1 {carol_ip6}") | 
					
						
							|  |  |  |       alice.succeed(f"ping -c 1 ${bobIp6}") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       bob.succeed("ping -c 1 ${aliceIp6}") | 
					
						
							|  |  |  |       bob.succeed(f"ping -c 1 {carol_ip6}") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       carol.succeed("ping -c 1 ${aliceIp6}") | 
					
						
							|  |  |  |       carol.succeed("ping -c 1 ${bobIp6}") | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  |       carol.succeed("ping -c 1 ${bobPrefix}::1") | 
					
						
							|  |  |  |       carol.succeed("ping -c 8 ${danIp6}") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       carol.fail("journalctl -u dhcpcd | grep ygg0") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 09:18:50 -08:00
										 |  |  |       alice.wait_for_unit("httpd.service") | 
					
						
							|  |  |  |       carol.succeed("curl --fail -g http://[${aliceIp6}]") | 
					
						
							| 
									
										
										
										
											2020-06-09 22:05:23 +05:30
										 |  |  |       carol.succeed("curl --fail -g http://[${danIp6}]") | 
					
						
							| 
									
										
										
										
											2019-06-27 08:56:10 -07:00
										 |  |  |     '';
 | 
					
						
							|  |  |  | }) |