mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-21 22:43:01 +00:00
matter-server: add nixos service module
New module to run the python-matter-server executable as a sandboxed system service.
This commit is contained in:
parent
6d69355499
commit
c0846f900a
@ -62,6 +62,10 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [hebbot](https://github.com/haecker-felix/hebbot), a Matrix bot to generate "This Week in X" like blog posts. Available as [services.hebbot](#opt-services.hebbot.enable).
|
||||
|
||||
- [Python Matter Server](https://github.com/home-assistant-libs/python-matter-server), a
|
||||
Matter Controller Server exposing websocket connections for use with other services, notably Home Assistant.
|
||||
Available as [services.matter-server](#opt-services.matter-server.enable)
|
||||
|
||||
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
|
||||
The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
|
||||
|
||||
|
@ -580,6 +580,7 @@
|
||||
./services/home-automation/govee2mqtt.nix
|
||||
./services/home-automation/home-assistant.nix
|
||||
./services/home-automation/homeassistant-satellite.nix
|
||||
./services/home-automation/matter-server.nix
|
||||
./services/home-automation/zigbee2mqtt.nix
|
||||
./services/home-automation/zwave-js.nix
|
||||
./services/logging/SystemdJournal2Gelf.nix
|
||||
|
125
nixos/modules/services/home-automation/matter-server.nix
Normal file
125
nixos/modules/services/home-automation/matter-server.nix
Normal file
@ -0,0 +1,125 @@
|
||||
{ lib
|
||||
, pkgs
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.matter-server;
|
||||
storageDir = "matter-server";
|
||||
storagePath = "/var/lib/${storageDir}";
|
||||
vendorId = "4939"; # home-assistant vendor ID
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ leonm1 ];
|
||||
|
||||
options.services.matter-server = with types; {
|
||||
enable = mkEnableOption (lib.mdDoc "Matter-server");
|
||||
|
||||
package = mkPackageOptionMD pkgs "python-matter-server" { };
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5580;
|
||||
description = "Port to expose the matter-server service on.";
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "critical" "error" "warning" "info" "debug" ];
|
||||
default = "info";
|
||||
description = "Verbosity of logs from the matter-server";
|
||||
};
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
Extra arguments to pass to the matter-server executable.
|
||||
See https://github.com/home-assistant-libs/python-matter-server?tab=readme-ov-file#running-the-development-server for options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.matter-server = {
|
||||
after = [ "network-online.target" ];
|
||||
before = [ "home-assistant.service" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Matter Server";
|
||||
environment.HOME = storagePath;
|
||||
serviceConfig = {
|
||||
ExecStart = (concatStringsSep " " [
|
||||
"${cfg.package}/bin/matter-server"
|
||||
"--port" (toString cfg.port)
|
||||
"--vendorid" vendorId
|
||||
"--storage-path" storagePath
|
||||
"--log-level" "${cfg.logLevel}"
|
||||
"${escapeShellArgs cfg.extraArgs}"
|
||||
]);
|
||||
# Start with a clean root filesystem, and allowlist what the container
|
||||
# is permitted to access.
|
||||
TemporaryFileSystem = "/";
|
||||
# Allowlist /nix/store (to allow the binary to find its dependencies)
|
||||
# and dbus.
|
||||
ReadOnlyPaths = "/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 = "";
|
||||
CapabilityBoundingSet = "";
|
||||
DevicePolicy = "closed";
|
||||
DynamicUser = true;
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallFilter = concatStringsSep " " [
|
||||
"~" # Blocklist
|
||||
"@clock"
|
||||
"@cpu-emulation"
|
||||
"@debug"
|
||||
"@module"
|
||||
"@mount"
|
||||
"@obsolete"
|
||||
"@privileged"
|
||||
"@raw-io"
|
||||
"@reboot"
|
||||
"@resources"
|
||||
"@swap"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -510,6 +510,7 @@ in {
|
||||
mastodon = discoverTests (import ./web-apps/mastodon { inherit handleTestOn; });
|
||||
pixelfed = discoverTests (import ./web-apps/pixelfed { inherit handleTestOn; });
|
||||
mate = handleTest ./mate.nix {};
|
||||
matter-server = handleTest ./matter-server.nix {};
|
||||
matomo = handleTest ./matomo.nix {};
|
||||
matrix-appservice-irc = handleTest ./matrix/appservice-irc.nix {};
|
||||
matrix-conduit = handleTest ./matrix/conduit.nix {};
|
||||
|
45
nixos/tests/matter-server.nix
Normal file
45
nixos/tests/matter-server.nix
Normal file
@ -0,0 +1,45 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ...} :
|
||||
|
||||
let
|
||||
chipVersion = pkgs.python311Packages.home-assistant-chip-core.version;
|
||||
in
|
||||
|
||||
{
|
||||
name = "matter-server";
|
||||
meta.maintainers = with lib.maintainers; [ leonm1 ];
|
||||
|
||||
nodes = {
|
||||
machine = { config, ... }: {
|
||||
services.matter-server = {
|
||||
enable = true;
|
||||
port = 1234;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = /* python */ ''
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("matter-server.service")
|
||||
machine.wait_for_open_port(1234)
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
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)
|
||||
'';
|
||||
})
|
Loading…
Reference in New Issue
Block a user