diff options
author | Michele Guerini Rocco <rnhmjoj@users.noreply.github.com> | 2023-09-04 20:00:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-04 20:00:30 +0200 |
commit | fcf38c9baca5f009ceb601353dcb1857c29d3e06 (patch) | |
tree | c555fc94697934a644f56921b3a9c7d3760bfca4 | |
parent | a9fea43703c233740cd6200f1acd6af06e160bd0 (diff) | |
parent | b058de4ac8539d60534e76eb2b92441384f02e1f (diff) | |
download | nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar.gz nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar.bz2 nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar.lz nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar.xz nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.tar.zst nixpkgs-fcf38c9baca5f009ceb601353dcb1857c29d3e06.zip |
Merge pull request #252597 from rnhmjoj/pr-jool
Fixup of PR #240982
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2311.section.md | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/jool.nix | 313 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 2 | ||||
-rw-r--r-- | nixos/tests/jool.nix | 106 |
4 files changed, 226 insertions, 197 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index aa619703924..8b6f9a23ff5 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -38,7 +38,7 @@ - [stalwart-mail](https://stalw.art), an all-in-one email server (SMTP, IMAP, JMAP). Available as [services.stalwart-mail](#opt-services.stalwart-mail.enable). -- [Jool](https://nicmx.github.io/Jool/en/index.html), an Open Source implementation of IPv4/IPv6 translation on Linux. Available as [networking.jool.enable](#opt-networking.jool.enable). +- [Jool](https://nicmx.github.io/Jool/en/index.html), a kernelspace NAT64 and SIIT implementation, providing translation between IPv4 and IPv6. Available as [networking.jool.enable](#opt-networking.jool.enable). - [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services. diff --git a/nixos/modules/services/networking/jool.nix b/nixos/modules/services/networking/jool.nix index 3aafbe40967..d2d2b0956e8 100644 --- a/nixos/modules/services/networking/jool.nix +++ b/nixos/modules/services/networking/jool.nix @@ -16,7 +16,7 @@ let TemporaryFileSystem = [ "/" ]; BindReadOnlyPaths = [ builtins.storeDir - "/run/current-system/kernel-modules" + "/run/booted-system/kernel-modules" ]; # Give capabilities to load the module and configure it @@ -31,26 +31,96 @@ let configFormat = pkgs.formats.json {}; - mkDefaultAttrs = lib.mapAttrs (n: v: lib.mkDefault v); + # Generate the config file of instance `name` + nat64Conf = name: + configFormat.generate "jool-nat64-${name}.conf" + (cfg.nat64.${name} // { instance = name; }); + siitConf = name: + configFormat.generate "jool-siit-${name}.conf" + (cfg.siit.${name} // { instance = name; }); + + # NAT64 config type + nat64Options = lib.types.submodule { + # The format is plain JSON + freeformType = configFormat.type; + # Some options with a default value + options.framework = lib.mkOption { + type = lib.types.enum [ "netfilter" "iptables" ]; + default = "netfilter"; + description = lib.mdDoc '' + The framework to use for attaching Jool's translation to the exist + kernel packet processing rules. See the + [documentation](https://nicmx.github.io/Jool/en/intro-jool.html#design) + for the differences between the two options. + ''; + }; + options.global.pool6 = lib.mkOption { + type = lib.types.strMatching "[[:xdigit:]:]+/[[:digit:]]+" + // { description = "Network prefix in CIDR notation"; }; + default = "64:ff9b::/96"; + description = lib.mdDoc '' + The prefix used for embedding IPv4 into IPv6 addresses. + Defaults to the well-known NAT64 prefix, defined by + [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). + ''; + }; + }; - defaultNat64 = { - instance = "default"; - framework = "netfilter"; - global.pool6 = "64:ff9b::/96"; + # SIIT config type + siitOptions = lib.types.submodule { + # The format is, again, plain JSON + freeformType = configFormat.type; + # Some options with a default value + options = { inherit (nat64Options.getSubOptions []) framework; }; + }; + + makeNat64Unit = name: opts: { + "jool-nat64-${name}" = { + description = "Jool, NAT64 setup of instance ${name}"; + documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStartPre = "${pkgs.kmod}/bin/modprobe jool"; + ExecStart = "${jool-cli}/bin/jool file handle ${nat64Conf name}"; + ExecStop = "${jool-cli}/bin/jool -f ${nat64Conf name} instance remove"; + } // hardening; + }; }; - defaultSiit = { - instance = "default"; - framework = "netfilter"; + + makeSiitUnit = name: opts: { + "jool-siit-${name}" = { + description = "Jool, SIIT setup of instance ${name}"; + documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStartPre = "${pkgs.kmod}/bin/modprobe jool_siit"; + ExecStart = "${jool-cli}/bin/jool_siit file handle ${siitConf name}"; + ExecStop = "${jool-cli}/bin/jool_siit -f ${siitConf name} instance remove"; + } // hardening; + }; }; - nat64Conf = configFormat.generate "jool-nat64.conf" cfg.nat64.config; - siitConf = configFormat.generate "jool-siit.conf" cfg.siit.config; + checkNat64 = name: _: '' + printf 'Validating Jool configuration for NAT64 instance "${name}"... ' + jool file check ${nat64Conf name} + printf 'Ok.\n'; touch "$out" + ''; + + checkSiit = name: _: '' + printf 'Validating Jool configuration for SIIT instance "${name}"... ' + jool_siit file check ${siitConf name} + printf 'Ok.\n'; touch "$out" + ''; in { - ###### interface - options = { networking.jool.enable = lib.mkOption { type = lib.types.bool; @@ -64,157 +134,146 @@ in NAT64, analogous to the IPv4 NAPT. Refer to the upstream [documentation](https://nicmx.github.io/Jool/en/intro-xlat.html) for the supported modes of translation and how to configure them. + + Enabling this option will install the Jool kernel module and the + command line tools for controlling it. ''; }; - networking.jool.nat64.enable = lib.mkEnableOption (lib.mdDoc "a NAT64 instance of Jool."); - networking.jool.nat64.config = lib.mkOption { - type = configFormat.type; - default = defaultNat64; + networking.jool.nat64 = lib.mkOption { + type = lib.types.attrsOf nat64Options; + default = { }; example = lib.literalExpression '' { - # custom NAT64 prefix - global.pool6 = "2001:db8:64::/96"; - - # Port forwarding - bib = [ - { # SSH 192.0.2.16 → 2001:db8:a::1 - "protocol" = "TCP"; - "ipv4 address" = "192.0.2.16#22"; - "ipv6 address" = "2001:db8:a::1#22"; - } - { # DNS (TCP) 192.0.2.16 → 2001:db8:a::2 - "protocol" = "TCP"; - "ipv4 address" = "192.0.2.16#53"; - "ipv6 address" = "2001:db8:a::2#53"; - } - { # DNS (UDP) 192.0.2.16 → 2001:db8:a::2 - "protocol" = "UDP"; - "ipv4 address" = "192.0.2.16#53"; - "ipv6 address" = "2001:db8:a::2#53"; - } - ]; - - pool4 = [ - # Ports for dynamic translation - { protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } - { protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } - { protocol = "ICMP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } - - # Ports for static BIB entries - { protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "22"; } - { protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "53"; } - ]; + default = { + # custom NAT64 prefix + global.pool6 = "2001:db8:64::/96"; + + # Port forwarding + bib = [ + { # SSH 192.0.2.16 → 2001:db8:a::1 + "protocol" = "TCP"; + "ipv4 address" = "192.0.2.16#22"; + "ipv6 address" = "2001:db8:a::1#22"; + } + { # DNS (TCP) 192.0.2.16 → 2001:db8:a::2 + "protocol" = "TCP"; + "ipv4 address" = "192.0.2.16#53"; + "ipv6 address" = "2001:db8:a::2#53"; + } + { # DNS (UDP) 192.0.2.16 → 2001:db8:a::2 + "protocol" = "UDP"; + "ipv4 address" = "192.0.2.16#53"; + "ipv6 address" = "2001:db8:a::2#53"; + } + ]; + + pool4 = [ + # Port ranges for dynamic translation + { protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } + { protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } + { protocol = "ICMP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; } + + # Ports for static BIB entries + { protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "22"; } + { protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "53"; } + ]; + }; } ''; description = lib.mdDoc '' - The configuration of a stateful NAT64 instance of Jool managed through - NixOS. See https://nicmx.github.io/Jool/en/config-atomic.html for the - available options. + Definitions of NAT64 instances of Jool. + See the + [documentation](https://nicmx.github.io/Jool/en/config-atomic.html) for + the available options. Also check out the + [tutorial](https://nicmx.github.io/Jool/en/run-nat64.html) for an + introduction to NAT64 and how to troubleshoot the setup. + + The attribute name defines the name of the instance, with the main one + being `default`: this can be accessed from the command line without + specifying the name with `-i`. ::: {.note} - Existing or more instances created manually will not interfere with the - NixOS instance, provided the respective `pool4` addresses and port - ranges are not overlapping. + Instances created imperatively from the command line will not interfere + with the NixOS instances, provided the respective `pool4` addresses and + port ranges are not overlapping. ::: ::: {.warning} - Changes to the NixOS instance performed via `jool instance nixos-nat64` - are applied correctly but will be lost after restarting - `jool-nat64.service`. + Changes to an instance performed via `jool -i <name>` are applied + correctly but will be lost after restarting the respective + `jool-nat64-<name>.service`. ::: ''; }; - networking.jool.siit.enable = lib.mkEnableOption (lib.mdDoc "a SIIT instance of Jool."); - networking.jool.siit.config = lib.mkOption { - type = configFormat.type; - default = defaultSiit; + networking.jool.siit = lib.mkOption { + type = lib.types.attrsOf siitOptions; + default = { }; example = lib.literalExpression '' { - # Maps any IPv4 address x.y.z.t to 2001:db8::x.y.z.t and v.v. - pool6 = "2001:db8::/96"; - - # Explicit address mappings - eamt = [ - # 2001:db8:1:: ←→ 192.0.2.0 - { "ipv6 prefix": "2001:db8:1::/128", "ipv4 prefix": "192.0.2.0" } - # 2001:db8:1::x ←→ 198.51.100.x - { "ipv6 prefix": "2001:db8:2::/120", "ipv4 prefix": "198.51.100.0/24" } - ] + default = { + # Maps any IPv4 address x.y.z.t to 2001:db8::x.y.z.t and v.v. + global.pool6 = "2001:db8::/96"; + + # Explicit address mappings + eamt = [ + # 2001:db8:1:: ←→ 192.0.2.0 + { "ipv6 prefix" = "2001:db8:1::/128"; "ipv4 prefix" = "192.0.2.0"; } + # 2001:db8:1::x ←→ 198.51.100.x + { "ipv6 prefix" = "2001:db8:2::/120"; "ipv4 prefix" = "198.51.100.0/24"; } + ]; + }; } ''; description = lib.mdDoc '' - The configuration of a SIIT instance of Jool managed through - NixOS. See https://nicmx.github.io/Jool/en/config-atomic.html for the - available options. + Definitions of SIIT instances of Jool. + See the + [documentation](https://nicmx.github.io/Jool/en/config-atomic.html) for + the available options. Also check out the + [tutorial](https://nicmx.github.io/Jool/en/run-vanilla.html) for an + introduction to SIIT and how to troubleshoot the setup. + + The attribute name defines the name of the instance, with the main one + being `default`: this can be accessed from the command line without + specifying the name with `-i`. ::: {.note} - Existing or more instances created manually will not interfere with the - NixOS instance, provided the respective `EAMT` address mappings are not - overlapping. + Instances created imperatively from the command line will not interfere + with the NixOS instances, provided the respective EAMT addresses and + port ranges are not overlapping. ::: ::: {.warning} - Changes to the NixOS instance performed via `jool instance nixos-siit` - are applied correctly but will be lost after restarting - `jool-siit.service`. + Changes to an instance performed via `jool -i <name>` are applied + correctly but will be lost after restarting the respective + `jool-siit-<name>.service`. ::: ''; }; }; - ###### implementation - config = lib.mkIf cfg.enable { - environment.systemPackages = [ jool-cli ]; + # Install kernel module and cli tools boot.extraModulePackages = [ jool ]; + environment.systemPackages = [ jool-cli ]; - systemd.services.jool-nat64 = lib.mkIf cfg.nat64.enable { - description = "Jool, NAT64 setup"; - documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ]; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - reloadIfChanged = true; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStartPre = "${pkgs.kmod}/bin/modprobe jool"; - ExecStart = "${jool-cli}/bin/jool file handle ${nat64Conf}"; - ExecStop = "${jool-cli}/bin/jool -f ${nat64Conf} instance remove"; - } // hardening; - }; - - systemd.services.jool-siit = lib.mkIf cfg.siit.enable { - description = "Jool, SIIT setup"; - documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ]; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - reloadIfChanged = true; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStartPre = "${pkgs.kmod}/bin/modprobe jool_siit"; - ExecStart = "${jool-cli}/bin/jool_siit file handle ${siitConf}"; - ExecStop = "${jool-cli}/bin/jool_siit -f ${siitConf} instance remove"; - } // hardening; - }; - - system.checks = lib.singleton (pkgs.runCommand "jool-validated" { - nativeBuildInputs = [ pkgs.buildPackages.jool-cli ]; - preferLocalBuild = true; - } '' - printf 'Validating Jool configuration... ' - ${lib.optionalString cfg.siit.enable "jool_siit file check ${siitConf}"} - ${lib.optionalString cfg.nat64.enable "jool file check ${nat64Conf}"} - printf 'ok\n' - touch "$out" - ''); - - networking.jool.nat64.config = mkDefaultAttrs defaultNat64; - networking.jool.siit.config = mkDefaultAttrs defaultSiit; + # Install services for each instance + systemd.services = lib.mkMerge + (lib.mapAttrsToList makeNat64Unit cfg.nat64 ++ + lib.mapAttrsToList makeSiitUnit cfg.siit); + # Check the configuration of each instance + system.checks = lib.optional (cfg.nat64 != {} || cfg.siit != {}) + (pkgs.runCommand "jool-validated" + { + nativeBuildInputs = with pkgs.buildPackages; [ jool-cli ]; + preferLocalBuild = true; + } + (lib.concatStrings + (lib.mapAttrsToList checkNat64 cfg.nat64 ++ + lib.mapAttrsToList checkSiit cfg.siit))); }; meta.maintainers = with lib.maintainers; [ rnhmjoj ]; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 681f2430c12..e25552b7d63 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -395,7 +395,7 @@ in { jibri = handleTest ./jibri.nix {}; jirafeau = handleTest ./jirafeau.nix {}; jitsi-meet = handleTest ./jitsi-meet.nix {}; - jool = handleTest ./jool.nix {}; + jool = import ./jool.nix { inherit pkgs runTest; }; k3s = handleTest ./k3s {}; kafka = handleTest ./kafka.nix {}; kanidm = handleTest ./kanidm.nix {}; diff --git a/nixos/tests/jool.nix b/nixos/tests/jool.nix index 6d5ded9b18e..93575f07b1c 100644 --- a/nixos/tests/jool.nix +++ b/nixos/tests/jool.nix @@ -1,9 +1,4 @@ -{ system ? builtins.currentSystem, - config ? {}, - pkgs ? import ../.. { inherit system config; } -}: - -with import ../lib/testing-python.nix { inherit system pkgs; }; +{ pkgs, runTest }: let inherit (pkgs) lib; @@ -23,7 +18,6 @@ let description = "Mock webserver"; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; - serviceConfig.Restart = "always"; script = '' while true; do { @@ -40,7 +34,7 @@ let in { - siit = makeTest { + siit = runTest { # This test simulates the setup described in [1] with two IPv6 and # IPv4-only devices on different subnets communicating through a border # relay running Jool in SIIT mode. @@ -49,8 +43,7 @@ in meta.maintainers = with lib.maintainers; [ rnhmjoj ]; # Border relay - nodes.relay = { ... }: { - imports = [ ../modules/profiles/minimal.nix ]; + nodes.relay = { virtualisation.vlans = [ 1 2 ]; # Enable packet routing @@ -65,20 +58,13 @@ in eth2.ipv4.addresses = [ { address = "192.0.2.1"; prefixLength = 24; } ]; }; - networking.jool = { - enable = true; - siit.enable = true; - siit.config.global.pool6 = "fd::/96"; - }; + networking.jool.enable = true; + networking.jool.siit.default.global.pool6 = "fd::/96"; }; # IPv6 only node - nodes.alice = { ... }: { - imports = [ - ../modules/profiles/minimal.nix - ipv6Only - (webserver 6 "Hello, Bob!") - ]; + nodes.alice = { + imports = [ ipv6Only (webserver 6 "Hello, Bob!") ]; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.ipv6 = { @@ -89,12 +75,8 @@ in }; # IPv4 only node - nodes.bob = { ... }: { - imports = [ - ../modules/profiles/minimal.nix - ipv4Only - (webserver 4 "Hello, Alice!") - ]; + nodes.bob = { + imports = [ ipv4Only (webserver 4 "Hello, Alice!") ]; virtualisation.vlans = [ 2 ]; networking.interfaces.eth1.ipv4 = { @@ -107,17 +89,17 @@ in testScript = '' start_all() - relay.wait_for_unit("jool-siit.service") + relay.wait_for_unit("jool-siit-default.service") alice.wait_for_unit("network-addresses-eth1.service") bob.wait_for_unit("network-addresses-eth1.service") with subtest("Alice and Bob can't ping each other"): - relay.systemctl("stop jool-siit.service") + relay.systemctl("stop jool-siit-default.service") alice.fail("ping -c1 fd::192.0.2.16") bob.fail("ping -c1 198.51.100.8") with subtest("Alice and Bob can ping using the relay"): - relay.systemctl("start jool-siit.service") + relay.systemctl("start jool-siit-default.service") alice.wait_until_succeeds("ping -c1 fd::192.0.2.16") bob.wait_until_succeeds("ping -c1 198.51.100.8") @@ -132,7 +114,7 @@ in ''; }; - nat64 = makeTest { + nat64 = runTest { # This test simulates the setup described in [1] with two IPv6-only nodes # (a client and a homeserver) on the LAN subnet and an IPv4 node on the WAN. # The router runs Jool in stateful NAT64 mode, masquarading the LAN and @@ -142,8 +124,7 @@ in meta.maintainers = with lib.maintainers; [ rnhmjoj ]; # Router - nodes.router = { ... }: { - imports = [ ../modules/profiles/minimal.nix ]; + nodes.router = { virtualisation.vlans = [ 1 2 ]; # Enable packet routing @@ -158,32 +139,29 @@ in eth2.ipv4.addresses = [ { address = "203.0.113.1"; prefixLength = 24; } ]; }; - networking.jool = { - enable = true; - nat64.enable = true; - nat64.config = { - bib = [ - { # forward HTTP 203.0.113.1 (router) → 2001:db8::9 (homeserver) - "protocol" = "TCP"; - "ipv4 address" = "203.0.113.1#80"; - "ipv6 address" = "2001:db8::9#80"; - } - ]; - pool4 = [ - # Ports for dynamic translation - { protocol = "TCP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } - { protocol = "UDP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } - { protocol = "ICMP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } - # Ports for static BIB entries - { protocol = "TCP"; prefix = "203.0.113.1/32"; "port range" = "80"; } - ]; - }; + networking.jool.enable = true; + networking.jool.nat64.default = { + bib = [ + { # forward HTTP 203.0.113.1 (router) → 2001:db8::9 (homeserver) + "protocol" = "TCP"; + "ipv4 address" = "203.0.113.1#80"; + "ipv6 address" = "2001:db8::9#80"; + } + ]; + pool4 = [ + # Ports for dynamic translation + { protocol = "TCP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } + { protocol = "UDP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } + { protocol = "ICMP"; prefix = "203.0.113.1/32"; "port range" = "40001-65535"; } + # Ports for static BIB entries + { protocol = "TCP"; prefix = "203.0.113.1/32"; "port range" = "80"; } + ]; }; }; # LAN client (IPv6 only) - nodes.client = { ... }: { - imports = [ ../modules/profiles/minimal.nix ipv6Only ]; + nodes.client = { + imports = [ ipv6Only ]; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.ipv6 = { @@ -194,12 +172,8 @@ in }; # LAN server (IPv6 only) - nodes.homeserver = { ... }: { - imports = [ - ../modules/profiles/minimal.nix - ipv6Only - (webserver 6 "Hello from IPv6!") - ]; + nodes.homeserver = { + imports = [ ipv6Only (webserver 6 "Hello from IPv6!") ]; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.ipv6 = { @@ -210,12 +184,8 @@ in }; # WAN server (IPv4 only) - nodes.server = { ... }: { - imports = [ - ../modules/profiles/minimal.nix - ipv4Only - (webserver 4 "Hello from IPv4!") - ]; + nodes.server = { + imports = [ ipv4Only (webserver 4 "Hello from IPv4!") ]; virtualisation.vlans = [ 2 ]; networking.interfaces.eth1.ipv4.addresses = @@ -229,7 +199,7 @@ in node.wait_for_unit("network-addresses-eth1.service") with subtest("Client can ping the WAN server"): - router.wait_for_unit("jool-nat64.service") + router.wait_for_unit("jool-nat64-default.service") client.succeed("ping -c1 64:ff9b::203.0.113.16") with subtest("Client can connect to the WAN webserver"): |