nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 276 lines 7.9 kB view raw
1# This test verifies that we can ping an IPv4-only server from an IPv6-only 2# client via a NAT64 router. The hosts and networks are configured as follows: 3# 4# +------ 5# Client | eth1 Address: 2001:db8::2/64 6# | | Route: 64:ff9b::/96 via 2001:db8::1 7# +--|--- 8# | VLAN 3 9# +--|--- 10# | eth2 Address: 2001:db8::1/64 11# Router | 12# | nat64 Address: 64:ff9b::1/128 13# | Route: 64:ff9b::/96 14# | Address: 192.0.2.0/32 15# | Route: 192.0.2.0/24 16# | 17# | eth1 Address: 100.64.0.1/24 18# +--|--- 19# | VLAN 2 20# +--|--- 21# Server | eth1 Address: 100.64.0.2/24 22# | Route: 192.0.2.0/24 via 100.64.0.1 23# +------ 24 25{ pkgs, lib, ... }: 26 27{ 28 name = "tayga"; 29 meta = with pkgs.lib.maintainers; { 30 maintainers = [ hax404 ]; 31 }; 32 33 nodes = { 34 # The server is configured with static IPv4 addresses. RFC 6052 Section 3.1 35 # disallows the mapping of non-global IPv4 addresses like RFC 1918 into the 36 # Well-Known Prefix 64:ff9b::/96. TAYGA also does not allow the mapping of 37 # documentation space (RFC 5737). To circumvent this, 100.64.0.2/24 from 38 # RFC 6589 (Carrier Grade NAT) is used here. 39 # To reach the IPv4 address pool of the NAT64 gateway, there is a static 40 # route configured. In normal cases, where the router would also source NAT 41 # the pool addresses to one IPv4 addresses, this would not be needed. 42 server = { 43 virtualisation.vlans = [ 44 2 # towards router 45 ]; 46 networking = { 47 useDHCP = false; 48 interfaces.eth1 = lib.mkForce { }; 49 }; 50 systemd.network = { 51 enable = true; 52 networks."vlan1" = { 53 matchConfig.Name = "eth1"; 54 address = [ 55 "100.64.0.2/24" 56 ]; 57 routes = [ 58 { 59 Destination = "192.0.2.0/24"; 60 Gateway = "100.64.0.1"; 61 } 62 ]; 63 }; 64 }; 65 programs.mtr.enable = true; 66 }; 67 68 # The router is configured with static IPv4 addresses towards the server 69 # and IPv6 addresses towards the client. For NAT64, the Well-Known prefix 70 # 64:ff9b::/96 is used. NAT64 is done with TAYGA which provides the 71 # tun-interface nat64 and does the translation over it. The IPv6 packets 72 # are sent to this interfaces and received as IPv4 packets and vice versa. 73 # As TAYGA only translates IPv6 addresses to dedicated IPv4 addresses, it 74 # needs a pool of IPv4 addresses which must be at least as big as the 75 # expected amount of clients. In this test, the packets from the pool are 76 # directly routed towards the client. In normal cases, there would be a 77 # second source NAT44 to map all clients behind one IPv4 address. 78 router_systemd = { 79 boot.kernel.sysctl = { 80 "net.ipv4.ip_forward" = 1; 81 "net.ipv6.conf.all.forwarding" = 1; 82 }; 83 84 virtualisation.vlans = [ 85 2 # towards server 86 3 # towards client 87 ]; 88 89 networking = { 90 useDHCP = false; 91 useNetworkd = true; 92 firewall.enable = false; 93 interfaces.eth1 = lib.mkForce { 94 ipv4 = { 95 addresses = [ 96 { 97 address = "100.64.0.1"; 98 prefixLength = 24; 99 } 100 ]; 101 }; 102 }; 103 interfaces.eth2 = lib.mkForce { 104 ipv6 = { 105 addresses = [ 106 { 107 address = "2001:db8::1"; 108 prefixLength = 64; 109 } 110 ]; 111 }; 112 }; 113 }; 114 115 services.tayga = { 116 enable = true; 117 ipv4 = { 118 address = "192.0.2.0"; 119 router = { 120 address = "192.0.2.1"; 121 }; 122 pool = { 123 address = "192.0.2.0"; 124 prefixLength = 24; 125 }; 126 }; 127 ipv6 = { 128 address = "2001:db8::1"; 129 router = { 130 address = "64:ff9b::1"; 131 }; 132 pool = { 133 address = "64:ff9b::"; 134 prefixLength = 96; 135 }; 136 }; 137 mappings = { 138 "192.0.2.42" = "2001:db8::2"; 139 }; 140 }; 141 }; 142 143 router_nixos = { 144 boot.kernel.sysctl = { 145 "net.ipv4.ip_forward" = 1; 146 "net.ipv6.conf.all.forwarding" = 1; 147 }; 148 149 virtualisation.vlans = [ 150 2 # towards server 151 3 # towards client 152 ]; 153 154 networking = { 155 useDHCP = false; 156 firewall.enable = false; 157 interfaces.eth1 = lib.mkForce { 158 ipv4 = { 159 addresses = [ 160 { 161 address = "100.64.0.1"; 162 prefixLength = 24; 163 } 164 ]; 165 }; 166 }; 167 interfaces.eth2 = lib.mkForce { 168 ipv6 = { 169 addresses = [ 170 { 171 address = "2001:db8::1"; 172 prefixLength = 64; 173 } 174 ]; 175 }; 176 }; 177 }; 178 179 services.tayga = { 180 enable = true; 181 ipv4 = { 182 address = "192.0.2.0"; 183 router = { 184 address = "192.0.2.1"; 185 }; 186 pool = { 187 address = "192.0.2.0"; 188 prefixLength = 24; 189 }; 190 }; 191 ipv6 = { 192 address = "2001:db8::1"; 193 router = { 194 address = "64:ff9b::1"; 195 }; 196 pool = { 197 address = "64:ff9b::"; 198 prefixLength = 96; 199 }; 200 }; 201 mappings = { 202 "192.0.2.42" = "2001:db8::2"; 203 }; 204 }; 205 }; 206 207 # The client is configured with static IPv6 addresses. It has also a static 208 # route for the NAT64 IP space where the IPv4 addresses are mapped in. In 209 # normal cases, there would be only a default route. 210 client = { 211 virtualisation.vlans = [ 212 3 # towards router 213 ]; 214 215 networking = { 216 useDHCP = false; 217 interfaces.eth1 = lib.mkForce { }; 218 }; 219 220 systemd.network = { 221 enable = true; 222 networks."vlan1" = { 223 matchConfig.Name = "eth1"; 224 address = [ 225 "2001:db8::2/64" 226 ]; 227 routes = [ 228 { 229 Destination = "64:ff9b::/96"; 230 Gateway = "2001:db8::1"; 231 } 232 ]; 233 }; 234 }; 235 programs.mtr.enable = true; 236 }; 237 }; 238 239 testScript = '' 240 # start client and server 241 for machine in client, server: 242 machine.systemctl("start network-online.target") 243 machine.wait_for_unit("network-online.target") 244 machine.log(machine.execute("ip addr")[1]) 245 machine.log(machine.execute("ip route")[1]) 246 machine.log(machine.execute("ip -6 route")[1]) 247 248 # test systemd-networkd and nixos-scripts based router 249 for router in router_systemd, router_nixos: 250 router.start() 251 router.systemctl("start network-online.target") 252 router.wait_for_unit("network-online.target") 253 router.wait_for_unit("tayga.service") 254 router.log(machine.execute("ip addr")[1]) 255 router.log(machine.execute("ip route")[1]) 256 router.log(machine.execute("ip -6 route")[1]) 257 258 with subtest("Wait for tayga"): 259 router.wait_for_unit("tayga.service") 260 261 with subtest("Test ICMP server -> client"): 262 server.wait_until_succeeds("ping -c 3 192.0.2.42 >&2") 263 264 with subtest("Test ICMP and show a traceroute server -> client"): 265 server.wait_until_succeeds("mtr --show-ips --report-wide 192.0.2.42 >&2") 266 267 with subtest("Test ICMP client -> server"): 268 client.wait_until_succeeds("ping -c 3 64:ff9b::100.64.0.2 >&2") 269 270 with subtest("Test ICMP and show a traceroute client -> server"): 271 client.wait_until_succeeds("mtr --show-ips --report-wide 64:ff9b::100.64.0.2 >&2") 272 273 router.log(router.execute("systemd-analyze security tayga.service")[1]) 274 router.shutdown() 275 ''; 276}