···5858 serviceConfig = {
5959 ExecStart = (
6060 lib.concatStringsSep " " [
6161+ # `python-matter-server` writes to /data even when a storage-path
6262+ # is specified. This symlinks /data at the systemd-managed
6363+ # /var/lib/matter-server, so all files get dropped into the state
6464+ # directory.
6565+ "${pkgs.bash}/bin/sh"
6666+ "-c"
6767+ "'"
6868+ "${pkgs.coreutils}/bin/ln -s %S/matter-server/ %t/matter-server/root/data"
6969+ "&&"
6170 "${cfg.package}/bin/matter-server"
6271 "--port"
6372 (toString cfg.port)
···6877 "--log-level"
6978 "${cfg.logLevel}"
7079 "${lib.escapeShellArgs cfg.extraArgs}"
8080+ "'"
7181 ]
7282 );
7383 # Start with a clean root filesystem, and allowlist what the container
7484 # is permitted to access.
7575- TemporaryFileSystem = "/";
8585+ # See https://discourse.nixos.org/t/hardening-systemd-services/17147/14.
8686+ RuntimeDirectory = [ "matter-server/root" ];
8787+ RootDirectory = "%t/matter-server/root";
8888+7689 # Allowlist /nix/store (to allow the binary to find its dependencies)
7790 # and dbus.
7878- ReadOnlyPaths = "/nix/store /run/dbus";
9191+ BindReadOnlyPaths = "/nix/store /run/dbus";
7992 # Let systemd manage `/var/lib/matter-server` for us inside the
8093 # ephemeral TemporaryFileSystem.
8194 StateDirectory = storageDir;
8282- # `python-matter-server` writes to /data even when a storage-path is
8383- # specified. This bind-mount points /data at the systemd-managed
8484- # /var/lib/matter-server, so all files get dropped into the state
8585- # directory.
8686- BindPaths = "${storagePath}:/data";
87958896 # Hardening bits
8997 AmbientCapabilities = "";
+19-17
nixos/tests/matter-server.nix
···88 {
99 name = "matter-server";
1010 meta.maintainers = with lib.maintainers; [ leonm1 ];
1111+ meta.timeout = 120; # Timeout after two minutes
11121213 nodes = {
1314 machine =
···22232324 testScript = # python
2425 ''
2626+ @polling_condition
2727+ def matter_server_running():
2828+ machine.succeed("systemctl status matter-server")
2929+2530 start_all()
26312727- machine.wait_for_unit("matter-server.service")
2828- machine.wait_for_open_port(1234)
3232+ machine.wait_for_unit("matter-server.service", timeout=20)
3333+ machine.wait_for_open_port(1234, timeout=20)
29343030- with subtest("Check websocket server initialized"):
3131- output = machine.succeed("echo \"\" | ${pkgs.websocat}/bin/websocat ws://localhost:1234/ws")
3232- machine.log(output)
3333-3434- assert '"sdk_version": "${chipVersion}"' in output, (
3535- 'CHIP version \"${chipVersion}\" not present in websocket message'
3636- )
3535+ with matter_server_running: # type: ignore[union-attr]
3636+ with subtest("Check websocket server initialized"):
3737+ output = machine.succeed("echo \"\" | ${pkgs.websocat}/bin/websocat ws://localhost:1234/ws")
3838+ machine.log(output)
37393838- assert '"fabric_id": 1' in output, (
3939- "fabric_id not propagated to server"
4040- )
4040+ assert '"fabric_id": 1' in output, (
4141+ "fabric_id not propagated to server"
4242+ )
41434242- with subtest("Check storage directory is created"):
4343- machine.succeed("ls /var/lib/matter-server/chip.json")
4444+ with subtest("Check storage directory is created"):
4545+ machine.succeed("ls /var/lib/matter-server/chip.json")
44464545- with subtest("Check systemd hardening"):
4646- _, output = machine.execute("systemd-analyze security matter-server.service | grep -v '✓'")
4747- machine.log(output)
4747+ with subtest("Check systemd hardening"):
4848+ _, output = machine.execute("systemd-analyze security matter-server.service | grep -v '✓'")
4949+ machine.log(output)
4850 '';
4951 }
5052)