1 # This tests whether UPnP port mappings can be created using Miniupnpd
3 # It runs a Miniupnpd service on one machine, and verifies
4 # a client can indeed create a port mapping using Miniupnpc. If
5 # this succeeds an external client will try to connect to the port
8 import ./make-test-python.nix ({ pkgs, useNftables, ... }:
11 internalRouterAddress = "192.168.3.1";
12 internalClient1Address = "192.168.3.2";
13 externalRouterAddress = "80.100.100.1";
14 externalClient2Address = "80.100.100.2";
18 meta = with pkgs.lib.maintainers; {
19 maintainers = [ bobvanderlinden ];
26 { virtualisation.vlans = [ 1 2 ];
27 networking.nat.enable = true;
28 networking.nat.internalInterfaces = [ "eth2" ];
29 networking.nat.externalInterface = "eth1";
30 networking.nftables.enable = useNftables;
31 networking.firewall.enable = true;
32 networking.firewall.trustedInterfaces = [ "eth2" ];
33 networking.interfaces.eth1.ipv4.addresses = [
34 { address = externalRouterAddress; prefixLength = 24; }
36 networking.interfaces.eth2.ipv4.addresses = [
37 { address = internalRouterAddress; prefixLength = 24; }
39 services.miniupnpd = {
41 externalInterface = "eth1";
42 internalIPs = [ "eth2" ];
44 ext_ip=${externalRouterAddress}
51 { environment.systemPackages = [ pkgs.miniupnpc pkgs.netcat ];
52 virtualisation.vlans = [ 2 ];
53 networking.defaultGateway = internalRouterAddress;
54 networking.interfaces.eth1.ipv4.addresses = [
55 { address = internalClient1Address; prefixLength = 24; }
57 networking.firewall.enable = false;
59 services.httpd.enable = true;
60 services.httpd.virtualHosts.localhost = {
61 listen = [{ ip = "*"; port = 9000; }];
62 adminAddr = "foo@example.org";
63 documentRoot = "/tmp";
69 { environment.systemPackages = [ pkgs.miniupnpc ];
70 virtualisation.vlans = [ 1 ];
71 networking.interfaces.eth1.ipv4.addresses = [
72 { address = externalClient2Address; prefixLength = 24; }
74 networking.firewall.enable = false;
83 # Wait for network and miniupnpd.
84 router.systemctl("start network-online.target")
85 router.wait_for_unit("network-online.target")
86 # $router.wait_for_unit("nat")
87 router.wait_for_unit("${if useNftables then "nftables" else "firewall"}.service")
88 router.wait_for_unit("miniupnpd")
90 client1.systemctl("start network-online.target")
91 client1.wait_for_unit("network-online.target")
93 client1.succeed("upnpc -a ${internalClient1Address} 9000 9000 TCP")
95 client1.wait_for_unit("httpd")
96 client2.wait_until_succeeds("curl -f http://${externalRouterAddress}:9000/")