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