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