From e0f1e1f7bf7e27f92c1a0215a7cc19eeed0499dd Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 30 Apr 2021 01:41:58 +0200 Subject: [PATCH 1/5] nixos/zigbee2mqtt: convert to rfc42 style settings --- nixos/doc/manual/release-notes/rl-2105.xml | 6 +++ nixos/modules/services/misc/zigbee2mqtt.nix | 49 +++++++++++---------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2105.xml b/nixos/doc/manual/release-notes/rl-2105.xml index 6e4a9e7114b..b45c19fa9af 100644 --- a/nixos/doc/manual/release-notes/rl-2105.xml +++ b/nixos/doc/manual/release-notes/rl-2105.xml @@ -692,6 +692,12 @@ environment.systemPackages = [ skip-kernel-setup true and takes care of setting forwarding and rp_filter sysctls by itself as well as for each interface in services.babeld.interfaces. + + + + The option has been renamed to and + now follows RFC 0042. + diff --git a/nixos/modules/services/misc/zigbee2mqtt.nix b/nixos/modules/services/misc/zigbee2mqtt.nix index cd987eb76c7..63951348172 100644 --- a/nixos/modules/services/misc/zigbee2mqtt.nix +++ b/nixos/modules/services/misc/zigbee2mqtt.nix @@ -5,26 +5,8 @@ with lib; let cfg = config.services.zigbee2mqtt; - configJSON = pkgs.writeText "configuration.json" - (builtins.toJSON (recursiveUpdate defaultConfig cfg.config)); - configFile = pkgs.runCommand "configuration.yaml" { preferLocalBuild = true; } '' - ${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out - ''; - - # the default config contains all required settings, - # so the service starts up without crashing. - defaultConfig = { - homeassistant = false; - permit_join = false; - mqtt = { - base_topic = "zigbee2mqtt"; - server = "mqtt://localhost:1883"; - }; - serial.port = "/dev/ttyACM0"; - # put device configuration into separate file because configuration.yaml - # is copied from the store on startup - devices = "devices.yaml"; - }; + format = pkgs.formats.yaml { }; + configFile = format.generate "zigbee2mqtt.yaml" cfg.settings; in { meta.maintainers = with maintainers; [ sweber ]; @@ -37,7 +19,11 @@ in default = pkgs.zigbee2mqtt.override { dataDir = cfg.dataDir; }; - defaultText = "pkgs.zigbee2mqtt"; + defaultText = literalExample '' + pkgs.zigbee2mqtt { + dataDir = services.zigbee2mqtt.dataDir + } + ''; type = types.package; }; @@ -47,9 +33,9 @@ in type = types.path; }; - config = mkOption { + settings = mkOption { + type = format.type; default = {}; - type = with types; nullOr attrs; example = literalExample '' { homeassistant = config.services.home-assistant.enable; @@ -61,11 +47,28 @@ in ''; description = '' Your configuration.yaml as a Nix attribute set. + Check the documentation + for possible options. ''; }; }; config = mkIf (cfg.enable) { + + # preset config values + services.zigbee2mqtt.settings = { + homeassistant = mkDefault config.services.home-assistant.enable; + permit_join = mkDefault false; + mqtt = { + base_topic = mkDefault "zigbee2mqtt"; + server = mkDefault "mqtt://localhost:1883"; + }; + serial.port = mkDefault "/dev/ttyACM0"; + # reference device configuration, that is kept in a separate file + # to prevent it being overwritten in the units ExecStartPre script + devices = mkDefault "devices.yaml"; + }; + systemd.services.zigbee2mqtt = { description = "Zigbee2mqtt Service"; wantedBy = [ "multi-user.target" ]; From a691549f7e2e466aa3833992de55c72bcee36885 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Sat, 24 Apr 2021 15:40:12 +0200 Subject: [PATCH 2/5] nixos/zigbee2mqtt: harden systemd unit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is what is still exposed, and it allows me to control my lamps from within home-assistant. ✗ PrivateNetwork= Service has access to the host's network 0.5 ✗ RestrictAddressFamilies=~AF_(INET|INET6) Service may allocate Internet sockets 0.3 ✗ DeviceAllow= Service has a device ACL with some special devices 0.1 ✗ IPAddressDeny= Service does not define an IP address allow list 0.2 ✗ PrivateDevices= Service potentially has access to hardware devices 0.2 ✗ RootDirectory=/RootImage= Service runs within the host's root directory 0.1 ✗ SupplementaryGroups= Service runs with supplementary groups 0.1 ✗ MemoryDenyWriteExecute= Service may create writable executable memory mappings 0.1 → Overall exposure level for zigbee2mqtt.service: 1.3 OK 🙂 --- nixos/modules/services/misc/zigbee2mqtt.nix | 41 ++++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/misc/zigbee2mqtt.nix b/nixos/modules/services/misc/zigbee2mqtt.nix index 63951348172..1f721910c4c 100644 --- a/nixos/modules/services/misc/zigbee2mqtt.nix +++ b/nixos/modules/services/misc/zigbee2mqtt.nix @@ -79,10 +79,48 @@ in User = "zigbee2mqtt"; WorkingDirectory = cfg.dataDir; Restart = "on-failure"; + + # Hardening + CapabilityBoundingSet = ""; + DeviceAllow = [ + config.services.zigbee2mqtt.settings.serial.port + ]; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = false; + NoNewPrivileges = true; + PrivateDevices = false; # prevents access to /dev/serial, because it is set 0700 root:root + PrivateUsers = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; ProtectSystem = "strict"; ReadWritePaths = cfg.dataDir; - PrivateTmp = true; RemoveIPC = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SupplementaryGroups = [ + "dialout" + ]; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@resources" + ]; + UMask = "0077"; }; preStart = '' cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml" @@ -93,7 +131,6 @@ in home = cfg.dataDir; createHome = true; group = "zigbee2mqtt"; - extraGroups = [ "dialout" ]; uid = config.ids.uids.zigbee2mqtt; }; From f1e7183f69595beabacb785b2f6a3f57ff5f99a9 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 30 Apr 2021 01:45:57 +0200 Subject: [PATCH 3/5] nixos/tests/zigbee2mqtt: relax DevicePolicy and log systemd-analye security --- nixos/tests/zigbee2mqtt.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nixos/tests/zigbee2mqtt.nix b/nixos/tests/zigbee2mqtt.nix index b7bb21f9227..98aadbb699b 100644 --- a/nixos/tests/zigbee2mqtt.nix +++ b/nixos/tests/zigbee2mqtt.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, lib, ... }: { machine = { pkgs, ... }: @@ -6,6 +6,8 @@ import ./make-test-python.nix ({ pkgs, ... }: services.zigbee2mqtt = { enable = true; }; + + systemd.services.zigbee2mqtt.serviceConfig.DevicePolicy = lib.mkForce "auto"; }; testScript = '' @@ -14,6 +16,8 @@ import ./make-test-python.nix ({ pkgs, ... }: machine.succeed( "journalctl -eu zigbee2mqtt | grep \"Error: Error while opening serialport 'Error: Error: No such file or directory, cannot open /dev/ttyACM0'\"" ) + + machine.log(machine.succeed("systemd-analyze security zigbee2mqtt.service")) ''; } ) From 2b61d9ea01dd69eeb5f113b906e24d0cb2252367 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 30 Apr 2021 20:05:57 +0200 Subject: [PATCH 4/5] nixos/zigbee2mqtt: create migration path from config to settings --- nixos/modules/services/misc/zigbee2mqtt.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nixos/modules/services/misc/zigbee2mqtt.nix b/nixos/modules/services/misc/zigbee2mqtt.nix index 1f721910c4c..189e620127d 100644 --- a/nixos/modules/services/misc/zigbee2mqtt.nix +++ b/nixos/modules/services/misc/zigbee2mqtt.nix @@ -7,10 +7,16 @@ let format = pkgs.formats.yaml { }; configFile = format.generate "zigbee2mqtt.yaml" cfg.settings; + in { meta.maintainers = with maintainers; [ sweber ]; + imports = [ + # Remove warning before the 21.11 release + (mkRenamedOptionModule [ "services" "zigbee2mqtt" "config" ] [ "services" "zigbee2mqtt" "settings" ]) + ]; + options.services.zigbee2mqtt = { enable = mkEnableOption "enable zigbee2mqtt service"; From 62de527dc32563e65556669037f5ce81943091bf Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 30 Apr 2021 20:40:04 +0200 Subject: [PATCH 5/5] nixos/zigbee2mqtt: start maintaing the module --- nixos/modules/services/misc/zigbee2mqtt.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/misc/zigbee2mqtt.nix b/nixos/modules/services/misc/zigbee2mqtt.nix index 189e620127d..4458da1346b 100644 --- a/nixos/modules/services/misc/zigbee2mqtt.nix +++ b/nixos/modules/services/misc/zigbee2mqtt.nix @@ -10,7 +10,7 @@ let in { - meta.maintainers = with maintainers; [ sweber ]; + meta.maintainers = with maintainers; [ sweber hexa ]; imports = [ # Remove warning before the 21.11 release