diff --git a/nixos/tests/vector/default.nix b/nixos/tests/vector/default.nix index c305c04cdba5..990b067e8177 100644 --- a/nixos/tests/vector/default.nix +++ b/nixos/tests/vector/default.nix @@ -6,5 +6,6 @@ { file-sink = import ./file-sink.nix { inherit system pkgs; }; api = import ./api.nix { inherit system pkgs; }; + dnstap = import ./dnstap.nix { inherit system pkgs; }; nginx-clickhouse = import ./nginx-clickhouse.nix { inherit system pkgs; }; } diff --git a/nixos/tests/vector/dnstap.nix b/nixos/tests/vector/dnstap.nix new file mode 100644 index 000000000000..15d643311b60 --- /dev/null +++ b/nixos/tests/vector/dnstap.nix @@ -0,0 +1,118 @@ +import ../make-test-python.nix ({ lib, pkgs, ... }: + +let + dnstapSocket = "/var/run/vector/dnstap.sock"; +in +{ + name = "vector-dnstap"; + meta.maintainers = [ pkgs.lib.maintainers.happysalada ]; + + nodes = { + unbound = { config, pkgs, ... }: { + networking.firewall.allowedUDPPorts = [ 53 ]; + + services.vector = { + enable = true; + + settings = { + sources = { + dnstap = { + type = "dnstap"; + multithreaded = true; + mode = "unix"; + lowercase_hostnames = true; + socket_file_mode = 504; + socket_path = "${dnstapSocket}"; + }; + }; + + sinks = { + file = { + type = "file"; + inputs = [ "dnstap" ]; + path = "/var/lib/vector/logs.log"; + encoding = { codec = "json"; }; + }; + }; + }; + }; + + systemd.services.vector.serviceConfig = { + RuntimeDirectory = "vector"; + RuntimeDirectoryMode = "0770"; + }; + + services.unbound = { + enable = true; + enableRootTrustAnchor = false; + package = pkgs.unbound-full; + settings = { + server = { + interface = [ "0.0.0.0" "::" ]; + access-control = [ "192.168.1.0/24 allow" ]; + + domain-insecure = "local"; + private-domain = "local"; + + local-zone = "local. static"; + local-data = [ + ''"test.local. 10800 IN A 192.168.123.5"'' + ]; + }; + + dnstap = { + dnstap-enable = "yes"; + dnstap-socket-path = "${dnstapSocket}"; + dnstap-send-identity = "yes"; + dnstap-send-version = "yes"; + dnstap-log-client-query-messages = "yes"; + dnstap-log-client-response-messages = "yes"; + }; + }; + }; + + systemd.services.unbound = { + after = [ "vector.service" ]; + wants = [ "vector.service" ]; + serviceConfig = { + # DNSTAP access + ReadWritePaths = [ "/var/run/vector" ]; + SupplementaryGroups = [ "vector" ]; + }; + }; + }; + + dnsclient = { config, pkgs, ... }: { + environment.systemPackages = [ pkgs.dig ]; + }; + }; + + testScript = '' + unbound.wait_for_unit("unbound") + unbound.wait_for_unit("vector") + + unbound.wait_until_succeeds( + "journalctl -o cat -u vector.service | grep 'Socket permissions updated to 0o770'" + ) + unbound.wait_until_succeeds( + "journalctl -o cat -u vector.service | grep 'component_type=dnstap' | grep 'Listening... path=\"${dnstapSocket}\"'" + ) + + unbound.wait_for_file("${dnstapSocket}") + unbound.succeed("test 770 -eq $(stat -c '%a' ${dnstapSocket})") + + dnsclient.wait_for_unit("network-online.target") + dnsclient.succeed( + "dig @unbound test.local" + ) + + unbound.wait_for_file("/var/lib/vector/logs.log") + + unbound.wait_until_succeeds( + "grep ClientQuery /var/lib/vector/logs.log | grep '\"domainName\":\"test.local.\"' | grep '\"rcodeName\":\"NoError\"'" + ) + unbound.wait_until_succeeds( + "grep ClientResponse /var/lib/vector/logs.log | grep '\"domainName\":\"test.local.\"' | grep '\"rData\":\"192.168.123.5\"'" + ) + ''; +})