nixos/preload: init
[NixPkgs.git] / nixos / modules / services / home-automation / zigbee2mqtt.nix
blob6b5bd8a0d9bbc1688ae6cfa4714134fc368550b7
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.zigbee2mqtt;
8   format = pkgs.formats.yaml { };
9   configFile = format.generate "zigbee2mqtt.yaml" cfg.settings;
13   meta.maintainers = with maintainers; [ sweber hexa ];
15   imports = [
16     # Remove warning before the 21.11 release
17     (mkRenamedOptionModule [ "services" "zigbee2mqtt" "config" ] [ "services" "zigbee2mqtt" "settings" ])
18   ];
20   options.services.zigbee2mqtt = {
21     enable = mkEnableOption (lib.mdDoc "zigbee2mqtt service");
23     package = mkOption {
24       description = lib.mdDoc "Zigbee2mqtt package to use";
25       default = pkgs.zigbee2mqtt;
26       defaultText = literalExpression ''
27         pkgs.zigbee2mqtt
28       '';
29       type = types.package;
30     };
32     dataDir = mkOption {
33       description = lib.mdDoc "Zigbee2mqtt data directory";
34       default = "/var/lib/zigbee2mqtt";
35       type = types.path;
36     };
38     settings = mkOption {
39       type = format.type;
40       default = { };
41       example = literalExpression ''
42         {
43           homeassistant = config.services.home-assistant.enable;
44           permit_join = true;
45           serial = {
46             port = "/dev/ttyACM1";
47           };
48         }
49       '';
50       description = lib.mdDoc ''
51         Your {file}`configuration.yaml` as a Nix attribute set.
52         Check the [documentation](https://www.zigbee2mqtt.io/information/configuration.html)
53         for possible options.
54       '';
55     };
56   };
58   config = mkIf (cfg.enable) {
60     # preset config values
61     services.zigbee2mqtt.settings = {
62       homeassistant = mkDefault config.services.home-assistant.enable;
63       permit_join = mkDefault false;
64       mqtt = {
65         base_topic = mkDefault "zigbee2mqtt";
66         server = mkDefault "mqtt://localhost:1883";
67       };
68       serial.port = mkDefault "/dev/ttyACM0";
69       # reference device/group configuration, that is kept in a separate file
70       # to prevent it being overwritten in the units ExecStartPre script
71       devices = mkDefault "devices.yaml";
72       groups = mkDefault "groups.yaml";
73     };
75     systemd.services.zigbee2mqtt = {
76       description = "Zigbee2mqtt Service";
77       wantedBy = [ "multi-user.target" ];
78       after = [ "network.target" ];
79       environment.ZIGBEE2MQTT_DATA = cfg.dataDir;
80       serviceConfig = {
81         ExecStart = "${cfg.package}/bin/zigbee2mqtt";
82         User = "zigbee2mqtt";
83         Group = "zigbee2mqtt";
84         WorkingDirectory = cfg.dataDir;
85         Restart = "on-failure";
87         # Hardening
88         CapabilityBoundingSet = "";
89         DeviceAllow = [
90           config.services.zigbee2mqtt.settings.serial.port
91         ];
92         DevicePolicy = "closed";
93         LockPersonality = true;
94         MemoryDenyWriteExecute = false;
95         NoNewPrivileges = true;
96         PrivateDevices = false; # prevents access to /dev/serial, because it is set 0700 root:root
97         PrivateUsers = true;
98         PrivateTmp = true;
99         ProtectClock = true;
100         ProtectControlGroups = true;
101         ProtectHome = true;
102         ProtectHostname = true;
103         ProtectKernelLogs = true;
104         ProtectKernelModules = true;
105         ProtectKernelTunables = true;
106         ProtectProc = "invisible";
107         ProcSubset = "pid";
108         ProtectSystem = "strict";
109         ReadWritePaths = cfg.dataDir;
110         RemoveIPC = true;
111         RestrictAddressFamilies = [
112           "AF_INET"
113           "AF_INET6"
114         ];
115         RestrictNamespaces = true;
116         RestrictRealtime = true;
117         RestrictSUIDSGID = true;
118         SupplementaryGroups = [
119           "dialout"
120         ];
121         SystemCallArchitectures = "native";
122         SystemCallFilter = [
123           "@system-service @pkey"
124           "~@privileged @resources"
125         ];
126         UMask = "0077";
127       };
128       preStart = ''
129         cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml"
130       '';
131     };
133     users.users.zigbee2mqtt = {
134       home = cfg.dataDir;
135       createHome = true;
136       group = "zigbee2mqtt";
137       uid = config.ids.uids.zigbee2mqtt;
138     };
140     users.groups.zigbee2mqtt.gid = config.ids.gids.zigbee2mqtt;
141   };