From b4f4971b6afa671cb584f9e2bddbf459bde8d443 Mon Sep 17 00:00:00 2001 From: Matt Leon Date: Sun, 23 Feb 2025 17:42:04 -0500 Subject: [PATCH] nixos/matter-server: fix permission denied error in initialization with v7.0.1 Signed-off-by: Matt Leon --- .../home-automation/matter-server.nix | 22 ++++++++---- nixos/tests/matter-server.nix | 36 ++++++++++--------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/nixos/modules/services/home-automation/matter-server.nix b/nixos/modules/services/home-automation/matter-server.nix index d01b70e89c14..072d7068a9aa 100644 --- a/nixos/modules/services/home-automation/matter-server.nix +++ b/nixos/modules/services/home-automation/matter-server.nix @@ -58,6 +58,15 @@ in serviceConfig = { ExecStart = ( lib.concatStringsSep " " [ + # `python-matter-server` writes to /data even when a storage-path + # is specified. This symlinks /data at the systemd-managed + # /var/lib/matter-server, so all files get dropped into the state + # directory. + "${pkgs.bash}/bin/sh" + "-c" + "'" + "${pkgs.coreutils}/bin/ln -s %S/matter-server/ %t/matter-server/root/data" + "&&" "${cfg.package}/bin/matter-server" "--port" (toString cfg.port) @@ -68,22 +77,21 @@ in "--log-level" "${cfg.logLevel}" "${lib.escapeShellArgs cfg.extraArgs}" + "'" ] ); # Start with a clean root filesystem, and allowlist what the container # is permitted to access. - TemporaryFileSystem = "/"; + # See https://discourse.nixos.org/t/hardening-systemd-services/17147/14. + RuntimeDirectory = [ "matter-server/root" ]; + RootDirectory = "%t/matter-server/root"; + # Allowlist /nix/store (to allow the binary to find its dependencies) # and dbus. - ReadOnlyPaths = "/nix/store /run/dbus"; + BindReadOnlyPaths = "/nix/store /run/dbus"; # Let systemd manage `/var/lib/matter-server` for us inside the # ephemeral TemporaryFileSystem. StateDirectory = storageDir; - # `python-matter-server` writes to /data even when a storage-path is - # specified. This bind-mount points /data at the systemd-managed - # /var/lib/matter-server, so all files get dropped into the state - # directory. - BindPaths = "${storagePath}:/data"; # Hardening bits AmbientCapabilities = ""; diff --git a/nixos/tests/matter-server.nix b/nixos/tests/matter-server.nix index 3337ea3cf66a..e302a8e91427 100644 --- a/nixos/tests/matter-server.nix +++ b/nixos/tests/matter-server.nix @@ -8,6 +8,7 @@ import ./make-test-python.nix ( { name = "matter-server"; meta.maintainers = with lib.maintainers; [ leonm1 ]; + meta.timeout = 120; # Timeout after two minutes nodes = { machine = @@ -22,29 +23,30 @@ import ./make-test-python.nix ( testScript = # python '' + @polling_condition + def matter_server_running(): + machine.succeed("systemctl status matter-server") + start_all() - machine.wait_for_unit("matter-server.service") - machine.wait_for_open_port(1234) + machine.wait_for_unit("matter-server.service", timeout=20) + machine.wait_for_open_port(1234, timeout=20) - with subtest("Check websocket server initialized"): - output = machine.succeed("echo \"\" | ${pkgs.websocat}/bin/websocat ws://localhost:1234/ws") - machine.log(output) + with matter_server_running: # type: ignore[union-attr] + with subtest("Check websocket server initialized"): + output = machine.succeed("echo \"\" | ${pkgs.websocat}/bin/websocat ws://localhost:1234/ws") + machine.log(output) - assert '"sdk_version": "${chipVersion}"' in output, ( - 'CHIP version \"${chipVersion}\" not present in websocket message' - ) + assert '"fabric_id": 1' in output, ( + "fabric_id not propagated to server" + ) - assert '"fabric_id": 1' in output, ( - "fabric_id not propagated to server" - ) + with subtest("Check storage directory is created"): + machine.succeed("ls /var/lib/matter-server/chip.json") - with subtest("Check storage directory is created"): - machine.succeed("ls /var/lib/matter-server/chip.json") - - with subtest("Check systemd hardening"): - _, output = machine.execute("systemd-analyze security matter-server.service | grep -v '✓'") - machine.log(output) + with subtest("Check systemd hardening"): + _, output = machine.execute("systemd-analyze security matter-server.service | grep -v '✓'") + machine.log(output) ''; } )