1# This is a simple distributed test involving a topology with two 2# separate virtual networks - the "inside" and the "outside" - with a 3# client on the inside network, a server on the outside network, and a 4# router connected to both that performs Network Address Translation 5# for the client. 6import ./make-test.nix ({ pkgs, withFirewall, ... }: 7 let 8 unit = if withFirewall then "firewall" else "nat"; 9 in 10 { 11 name = "nat${if withFirewall then "WithFirewall" else "Standalone"}"; 12 meta = with pkgs.stdenv.lib.maintainers; { 13 maintainers = [ eelco chaoflow rob wkennington ]; 14 }; 15 16 nodes = 17 { client = 18 { config, pkgs, nodes, ... }: 19 { virtualisation.vlans = [ 1 ]; 20 networking.firewall.allowPing = true; 21 networking.defaultGateway = 22 (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address; 23 }; 24 25 router = 26 { config, pkgs, ... }: 27 { virtualisation.vlans = [ 2 1 ]; 28 networking.firewall.enable = withFirewall; 29 networking.firewall.allowPing = true; 30 networking.nat.enable = true; 31 networking.nat.internalIPs = [ "192.168.1.0/24" ]; 32 networking.nat.externalInterface = "eth1"; 33 }; 34 35 server = 36 { config, pkgs, ... }: 37 { virtualisation.vlans = [ 2 ]; 38 networking.firewall.enable = false; 39 services.httpd.enable = true; 40 services.httpd.adminAddr = "foo@example.org"; 41 services.vsftpd.enable = true; 42 services.vsftpd.anonymousUser = true; 43 }; 44 }; 45 46 testScript = 47 { nodes, ... }: 48 '' 49 startAll; 50 51 # The router should have access to the server. 52 $server->waitForUnit("network.target"); 53 $server->waitForUnit("httpd"); 54 $router->waitForUnit("network.target"); 55 $router->succeed("curl --fail http://server/ >&2"); 56 57 # The client should be also able to connect via the NAT router. 58 $router->waitForUnit("${unit}"); 59 $client->waitForUnit("network.target"); 60 $client->succeed("curl --fail http://server/ >&2"); 61 $client->succeed("ping -c 1 server >&2"); 62 63 # Test whether passive FTP works. 64 $server->waitForUnit("vsftpd"); 65 $server->succeed("echo Hello World > /home/ftp/foo.txt"); 66 $client->succeed("curl -v ftp://server/foo.txt >&2"); 67 68 # Test whether active FTP works. 69 $client->succeed("curl -v -P - ftp://server/foo.txt >&2"); 70 71 # Test ICMP. 72 $client->succeed("ping -c 1 router >&2"); 73 $router->succeed("ping -c 1 client >&2"); 74 75 # If we turn off NAT, the client shouldn't be able to reach the server. 76 $router->succeed("iptables -t nat -D PREROUTING -j nixos-nat-pre"); 77 $router->succeed("iptables -t nat -D POSTROUTING -j nixos-nat-post"); 78 $client->fail("curl --fail --connect-timeout 5 http://server/ >&2"); 79 $client->fail("ping -c 1 server >&2"); 80 81 # And make sure that reloading the NAT job works. 82 $router->succeed("systemctl restart ${unit}"); 83 $client->succeed("curl --fail http://server/ >&2"); 84 $client->succeed("ping -c 1 server >&2"); 85 ''; 86 })