diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2ef049beeca4..0c7c85dd9160 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -167,6 +167,7 @@ ./programs/direnv.nix ./programs/dmrconfig.nix ./programs/droidcam.nix + ./programs/dublin-traceroute.nix ./programs/ecryptfs.nix ./programs/environment.nix ./programs/evince.nix diff --git a/nixos/modules/programs/dublin-traceroute.nix b/nixos/modules/programs/dublin-traceroute.nix new file mode 100644 index 000000000000..cfcd6e8308ff --- /dev/null +++ b/nixos/modules/programs/dublin-traceroute.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.dublin-traceroute; + +in { + meta.maintainers = pkgs.dublin-traceroute.meta.maintainers; + + options = { + programs.dublin-traceroute = { + enable = mkEnableOption (mdDoc '' + dublin-traceroute, add it to the global environment and configure a setcap wrapper for it. + ''); + + package = mkPackageOption pkgs "dublin-traceroute" { }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + security.wrappers.dublin-traceroute = { + owner = "root"; + group = "root"; + capabilities = "cap_net_raw+p"; + source = getExe cfg.package; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 1e11cc220805..c0944a391479 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -253,6 +253,7 @@ in { domination = handleTest ./domination.nix {}; dovecot = handleTest ./dovecot.nix {}; drbd = handleTest ./drbd.nix {}; + dublin-traceroute = handleTest ./dublin-traceroute.nix {}; earlyoom = handleTestOn ["x86_64-linux"] ./earlyoom.nix {}; early-mount-options = handleTest ./early-mount-options.nix {}; ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {}; diff --git a/nixos/tests/dublin-traceroute.nix b/nixos/tests/dublin-traceroute.nix new file mode 100644 index 000000000000..b359b7fcdd6f --- /dev/null +++ b/nixos/tests/dublin-traceroute.nix @@ -0,0 +1,63 @@ +# This is a simple distributed test involving a topology with two +# separate virtual networks - the "inside" and the "outside" - with a +# client on the inside network, a server on the outside network, and a +# router connected to both that performs Network Address Translation +# for the client. +import ./make-test-python.nix ({ pkgs, lib, ... }: + let + routerBase = + lib.mkMerge [ + { virtualisation.vlans = [ 2 1 ]; + networking.nftables.enable = true; + networking.nat.internalIPs = [ "192.168.1.0/24" ]; + networking.nat.externalInterface = "eth1"; + } + ]; + in + { + name = "dublin-traceroute"; + meta = with pkgs.lib.maintainers; { + maintainers = [ baloo ]; + }; + + nodes.client = { nodes, ... }: { + imports = [ ./common/user-account.nix ]; + virtualisation.vlans = [ 1 ]; + + networking.defaultGateway = + (builtins.head nodes.router.networking.interfaces.eth2.ipv4.addresses).address; + networking.nftables.enable = true; + + programs.dublin-traceroute.enable = true; + }; + + nodes.router = { ... }: { + virtualisation.vlans = [ 2 1 ]; + networking.nftables.enable = true; + networking.nat.internalIPs = [ "192.168.1.0/24" ]; + networking.nat.externalInterface = "eth1"; + networking.nat.enable = true; + }; + + nodes.server = { ... }: { + virtualisation.vlans = [ 2 ]; + networking.firewall.enable = false; + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.vsftpd.enable = true; + services.vsftpd.anonymousUser = true; + }; + + testScript = '' + client.start() + router.start() + server.start() + + server.wait_for_unit("network.target") + router.wait_for_unit("network.target") + client.wait_for_unit("network.target") + + # Make sure we can trace from an unprivileged user + client.succeed("sudo -u alice dublin-traceroute server") + ''; + })