summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services
diff options
context:
space:
mode:
authorMartin Weinelt <mweinelt@users.noreply.github.com>2023-11-06 20:24:56 +0100
committerGitHub <noreply@github.com>2023-11-06 20:24:56 +0100
commita3708ce91cb36b05a57bb900f567ea6d567949bf (patch)
treeeebe86a5020eec0246d9bc8767ddb3b33db90913 /nixos/modules/services
parent0d930cd6bbfeda4bef5be62eca5d7f83380c55a6 (diff)
parentb2fccae80913400dc6b63aa37c27a5c96243fcad (diff)
Merge pull request #230380 from graham33/feature/zwave-js-server_module
zwave-js: module init, zwave-js-server: init at 1.33.0
Diffstat (limited to 'nixos/modules/services')
-rw-r--r--nixos/modules/services/home-automation/zwave-js.nix152
1 files changed, 152 insertions, 0 deletions
diff --git a/nixos/modules/services/home-automation/zwave-js.nix b/nixos/modules/services/home-automation/zwave-js.nix
new file mode 100644
index 000000000000..87c9b8f1ac81
--- /dev/null
+++ b/nixos/modules/services/home-automation/zwave-js.nix
@@ -0,0 +1,152 @@
+{config, pkgs, lib, ...}:
+
+with lib;
+
+let
+ cfg = config.services.zwave-js;
+ mergedConfigFile = "/run/zwave-js/config.json";
+ settingsFormat = pkgs.formats.json {};
+in {
+ options.services.zwave-js = {
+ enable = mkEnableOption (mdDoc "the zwave-js server on boot");
+
+ package = mkPackageOptionMD pkgs "zwave-js-server" { };
+
+ port = mkOption {
+ type = types.port;
+ default = 3000;
+ description = mdDoc ''
+ Port for the server to listen on.
+ '';
+ };
+
+ serialPort = mkOption {
+ type = types.path;
+ description = mdDoc ''
+ Serial port device path for Z-Wave controller.
+ '';
+ example = "/dev/ttyUSB0";
+ };
+
+ secretsConfigFile = mkOption {
+ type = types.path;
+ description = mdDoc ''
+ JSON file containing secret keys. A dummy example:
+
+ ```
+ {
+ "securityKeys": {
+ "S0_Legacy": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "S2_Unauthenticated": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
+ "S2_Authenticated": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
+ "S2_AccessControl": "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+ }
+ }
+ ```
+
+ See
+ <https://zwave-js.github.io/node-zwave-js/#/getting-started/security-s2>
+ for details. This file will be merged with the module-generated config
+ file (taking precedence).
+
+ Z-Wave keys can be generated with:
+
+ {command}`< /dev/urandom tr -dc A-F0-9 | head -c32 ;echo`
+
+
+ ::: {.warning}
+ A file in the nix store should not be used since it will be readable to
+ all users.
+ :::
+ '';
+ example = "/secrets/zwave-js-keys.json";
+ };
+
+ settings = mkOption {
+ type = lib.types.submodule {
+ freeformType = settingsFormat.type;
+
+ options = {
+ storage = {
+ cacheDir = mkOption {
+ type = types.path;
+ default = "/var/cache/zwave-js";
+ readOnly = true;
+ description = lib.mdDoc "Cache directory";
+ };
+ };
+ };
+ };
+ default = {};
+ description = mdDoc ''
+ Configuration settings for the generated config
+ file.
+ '';
+ };
+
+ extraFlags = lib.mkOption {
+ type = with lib.types; listOf str;
+ default = [ ];
+ example = [ "--mock-driver" ];
+ description = lib.mdDoc ''
+ Extra flags to pass to command
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.zwave-js = let
+ configFile = settingsFormat.generate "zwave-js-config.json" cfg.settings;
+ in {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ description = "Z-Wave JS Server";
+ serviceConfig = {
+ ExecStartPre = ''
+ /bin/sh -c "${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configFile} ${cfg.secretsConfigFile} > ${mergedConfigFile}"
+ '';
+ ExecStart = lib.concatStringsSep " " [
+ "${cfg.package}/bin/zwave-server"
+ "--config ${mergedConfigFile}"
+ "--port ${toString cfg.port}"
+ cfg.serialPort
+ (escapeShellArgs cfg.extraFlags)
+ ];
+ Restart = "on-failure";
+ User = "zwave-js";
+ SupplementaryGroups = [ "dialout" ];
+ CacheDirectory = "zwave-js";
+ RuntimeDirectory = "zwave-js";
+
+ # Hardening
+ CapabilityBoundingSet = "";
+ DeviceAllow = [cfg.serialPort];
+ DevicePolicy = "closed";
+ DynamicUser = true;
+ LockPersonality = true;
+ MemoryDenyWriteExecute = false;
+ NoNewPrivileges = true;
+ PrivateUsers = true;
+ PrivateTmp = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ RemoveIPC = true;
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = [
+ "@system-service @pkey"
+ "~@privileged @resources"
+ ];
+ UMask = "0077";
+ };
+ };
+ };
+
+ meta.maintainers = with lib.maintainers; [ graham33 ];
+}