diff options
Diffstat (limited to 'nixos/tests')
-rw-r--r-- | nixos/tests/unbound.nix | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/nixos/tests/unbound.nix b/nixos/tests/unbound.nix index 9a7a652b4052f..dc8e5a9d3ed8c 100644 --- a/nixos/tests/unbound.nix +++ b/nixos/tests/unbound.nix @@ -8,8 +8,13 @@ * running a recursive DNS resolver on a machine in the network awaiting input from clients over TCP/53 & UDP/53 * running a recursive DNS resolver on a machine in the network awaiting input from clients over TCP/853 (DoT) - In the below test setup we are trying to implement all of those use cases - without creating a bazillion machines. + In the below test setup we are trying to implement all of those use cases. + + Another aspect that we cover is access to the local control UNIX socket. It + can optionally be enabled and users can optionally be in a group to gain + access. Users that are not in the group (except for root) should not have + access to that socket. Also, when there is no socket configured, users + shouldn't be able to access the control socket at all. Not even root. */ import ./make-test-python.nix ({ pkgs, lib, ... }: let @@ -96,7 +101,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: }; # machine that runs a local unbound that will be reconfigured during test execution - local_resolver = { lib, nodes, ... }: { + local_resolver = { lib, nodes, config, ... }: { imports = [ common ]; networking.interfaces.eth1.ipv4.addresses = lib.mkForce [ { address = "192.168.0.3"; prefixLength = 24; } @@ -113,11 +118,22 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: enable = true; allowedAccess = [ "::1" "127.0.0.0/8" ]; interfaces = [ "::1" "127.0.0.1" ]; + localControlSocketPath = "/run/unbound/unbound.ctl"; extraConfig = '' include: "/etc/unbound/extra*.conf" ''; }; + users.users = { + # user that is permitted to access the unix socket + someuser.extraGroups = [ + config.users.users.unbound.group + ]; + + # user that is not permitted to access the unix socket + unauthorizeduser = {}; + }; + environment.etc = { "unbound-extra1.conf".text = '' forward-zone: @@ -132,12 +148,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: something.local. IN A 3.4.5.6 ''} ''; - "unbound-extra3.conf".text = '' - remote-control: - control-enable: yes - control-interface: /run/unbound/unbound.ctl - ''; - }; }; @@ -218,6 +228,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: resolver.wait_for_unit("unbound.service") + with subtest("root is unable to use unbounc-control when the socket is not configured"): + resolver.succeed("which unbound-control") # the binary must exist + resolver.fail("unbound-control list_forwards") # the invocation must fail + # verify that the resolver is able to resolve on all the local protocols with subtest("test that the resolver resolves on all protocols and transports"): test(resolver, ["::1", "127.0.0.1"], doh=True) @@ -241,18 +255,24 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: print(local_resolver.succeed("journalctl -u unbound -n 1000")) test(local_resolver, ["::1", "127.0.0.1"], args=["+timeout=60"]) + with subtest("test that we can use the unbound control socket"): + out = local_resolver.succeed( + "sudo -u someuser -- unbound-control list_forwards" + ).strip() + + # Thank you black! Can't really break this line into a readable version. + expected = "example.local. IN forward ${(lib.head nodes.resolver.config.networking.interfaces.eth1.ipv6.addresses).address} ${(lib.head nodes.resolver.config.networking.interfaces.eth1.ipv4.addresses).address}" + assert out == expected, f"Expected `{expected}` but got `{out}` instead." + local_resolver.fail("sudo -u unauthorizeduser -- unbound-control list_forwards") + + # link a new config file to /etc/unbound/extra.conf local_resolver.succeed("ln -sf /etc/unbound-extra2.conf /etc/unbound/extra2.conf") # reload the server & ensure the new local zone works with subtest("test that we can query the new local zone"): - local_resolver.succeed("systemctl reload unbound") + local_resolver.succeed("unbound-control reload") r = [("A", "3.4.5.6")] test(local_resolver, ["::1", "127.0.0.1"], zone="something.local.", records=r) - - with subtest("test that we can enable unbound control sockets on the fly"): - local_resolver.succeed("ln -sf /etc/unbound-extra3.conf /etc/unbound/extra3.conf") - local_resolver.succeed("systemctl reload unbound") - local_resolver.succeed("unbound-control list_forwards") ''; }) |