about summary refs log tree commit diff
path: root/nixos/modules
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
parent0d930cd6bbfeda4bef5be62eca5d7f83380c55a6 (diff)
parentb2fccae80913400dc6b63aa37c27a5c96243fcad (diff)
downloadnixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar.gz
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar.bz2
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar.lz
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar.xz
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.tar.zst
nixlib-a3708ce91cb36b05a57bb900f567ea6d567949bf.zip
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')
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/home-automation/zwave-js.nix152
2 files changed, 153 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 44acc011ba19..6679e5bb7c65 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -564,6 +564,7 @@
   ./services/home-automation/home-assistant.nix
   ./services/home-automation/homeassistant-satellite.nix
   ./services/home-automation/zigbee2mqtt.nix
+  ./services/home-automation/zwave-js.nix
   ./services/logging/SystemdJournal2Gelf.nix
   ./services/logging/awstats.nix
   ./services/logging/filebeat.nix
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 ];
+}