diff --git a/hosts/sausebiene/default.nix b/hosts/sausebiene/default.nix index 706cea6..a983702 100644 --- a/hosts/sausebiene/default.nix +++ b/hosts/sausebiene/default.nix @@ -25,6 +25,7 @@ ./influxdb.nix ./mosquitto.nix ./wyoming.nix + ./zigbee2mqtt.nix ]; topology.self.hardware.info = "Intel N100, 16GB RAM"; diff --git a/hosts/sausebiene/mosquitto.nix b/hosts/sausebiene/mosquitto.nix index 7368466..d308131 100644 --- a/hosts/sausebiene/mosquitto.nix +++ b/hosts/sausebiene/mosquitto.nix @@ -1,5 +1,12 @@ { config, ... }: { + age.secrets.mosquitto-pw-zigbee2mqtt = { + mode = "440"; + owner = "zigbee2mqtt"; + group = "mosquitto"; + generator.script = "alnum"; + }; + age.secrets.mosquitto-pw-home-assistant = { mode = "440"; owner = "hass"; @@ -14,10 +21,10 @@ { acl = [ "pattern readwrite #" ]; users = { - # zigbee2mqtt = { - # passwordFile = config.age.secrets.mosquitto-pw-zigbee2mqtt.path; - # acl = [ "readwrite #" ]; - # }; + zigbee2mqtt = { + passwordFile = config.age.secrets.mosquitto-pw-zigbee2mqtt.path; + acl = [ "readwrite #" ]; + }; home_assistant = { passwordFile = config.age.secrets.mosquitto-pw-home-assistant.path; acl = [ "readwrite #" ]; diff --git a/hosts/sausebiene/zigbee2mqtt.nix b/hosts/sausebiene/zigbee2mqtt.nix new file mode 100644 index 0000000..ec74468 --- /dev/null +++ b/hosts/sausebiene/zigbee2mqtt.nix @@ -0,0 +1,87 @@ +{ + config, + globals, + lib, + pkgs, + ... +}: +let + zigbee2mqttDomain = "zigbee.${globals.domains.personal}"; +in +{ + wireguard.proxy-home.firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [ + config.services.zigbee2mqtt.settings.frontend.port + ]; + + globals.services.zigbee2mqtt.domain = zigbee2mqttDomain; + # globals.monitoring.http.homeassistant = { + # url = "https://${homeasisstantDomain}"; + # expectedBodyRegex = "homeassistant"; + # network = "internet"; + # }; + + services.zigbee2mqtt = { + enable = true; + package = pkgs.zigbee2mqtt_2; + settings = { + advanced = { + log_level = "info"; + channel = 25; + }; + homeassistant = true; + permit_join = false; + serial = { + port = "/dev/serial/by-path/pci-0000:00:14.0-usb-0:5.4:1.0-port0"; + adapter = "zstack"; + }; + mqtt = { + server = "mqtt://localhost:1883"; + user = "zigbee2mqtt"; + password = "!/run/zigbee2mqtt/secrets.yaml mosquitto-pw"; + }; + frontend.port = 8072; + }; + }; + + systemd.services.zigbee2mqtt = { + serviceConfig = { + RuntimeDirectory = "zigbee2mqtt"; + LoadCredential = [ + "mosquitto-pw-zigbee2mqtt:${config.age.secrets.mosquitto-pw-zigbee2mqtt.path}" + ]; + }; + preStart = lib.mkBefore '' + # Update mosquitto password + # We don't use -i because it would require chown with is a @privileged syscall + MOSQUITTO_PW="$(cat "$CREDENTIALS_DIRECTORY/mosquitto-pw-zigbee2mqtt")" \ + ${lib.getExe pkgs.yq-go} '.mosquitto-pw = strenv(MOSQUITTO_PW)' \ + /dev/null > /run/zigbee2mqtt/secrets.yaml + ''; + }; + + nodes.ward-web-proxy = { + services.nginx = { + upstreams."zigbee2mqtt" = { + servers."${config.wireguard.proxy-home.ipv4}:${toString config.services.zigbee2mqtt.settings.frontend.port}" = + { }; + extraConfig = '' + zone zigbee2mqtt 64k; + keepalive 2; + ''; + }; + virtualHosts.${zigbee2mqttDomain} = { + forceSSL = true; + useACMEWildcardHost = true; + locations."/" = { + proxyPass = "http://zigbee2mqtt"; + proxyWebsockets = true; + }; + extraConfig = '' + allow ${globals.net.home-lan.vlans.home.cidrv4}; + allow ${globals.net.home-lan.vlans.home.cidrv6}; + deny all; + ''; + }; + }; + }; +} diff --git a/hosts/sentinel/firezone.nix b/hosts/sentinel/firezone.nix index f55cdf7..e83e378 100644 --- a/hosts/sentinel/firezone.nix +++ b/hosts/sentinel/firezone.nix @@ -19,6 +19,7 @@ let globals.services.paperless.domain globals.services.esphome.domain globals.services.home-assistant.domain + globals.services.zigbee2mqtt.domain "fritzbox.${globals.domains.personal}" ]; diff --git a/hosts/ward/default.nix b/hosts/ward/default.nix index a56b215..0084a07 100644 --- a/hosts/ward/default.nix +++ b/hosts/ward/default.nix @@ -20,6 +20,7 @@ let globals.services.paperless.domain globals.services.esphome.domain globals.services.home-assistant.domain + globals.services.zigbee2mqtt.domain "fritzbox.${globals.domains.personal}" ]; in diff --git a/hosts/ward/guests/adguardhome.nix b/hosts/ward/guests/adguardhome.nix index 8952bbf..4de9b06 100644 --- a/hosts/ward/guests/adguardhome.nix +++ b/hosts/ward/guests/adguardhome.nix @@ -119,6 +119,7 @@ in globals.services.paperless.domain globals.services.esphome.domain globals.services.home-assistant.domain + globals.services.zigbee2mqtt.domain "fritzbox.${globals.domains.personal}" ]; filters = [ diff --git a/secrets/generated/sausebiene/mosquitto-pw-zigbee2mqtt.age b/secrets/generated/sausebiene/mosquitto-pw-zigbee2mqtt.age new file mode 100644 index 0000000..3bb5747 --- /dev/null +++ b/secrets/generated/sausebiene/mosquitto-pw-zigbee2mqtt.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> X25519 U/Thn4wTLTDEF+mcWV5ZC8NZ5qBIwKQxxnoZOugHiDg +gF+2ZwYjT1cGIS7Q6T/c+bZdrIKpGiEQMi27qG0bYsA +-> piv-p256 xqSe8Q ArPNbPO60gHXtHNndhWIibqoJ/3W5JFr/GWc3iZ0Gvp+ +7iYbOcHduUzt2f8PAW433RLqLNpH1EDzlBDy+8ez0+M +-> iF51-grease |M2 voKb|f $({}coDX R2eT +9Us2yS3sDz89PGI3Sy3jvSv6+0Unpy76BeuhfyYEJcwHRGeqZHuiSDEkZyOT +--- Z2X0Rk9vCYMgzTsnYqPpgc28AQH60qbYHm2PTAHx9So +ЎƖzw(":v:sÞBo bA.I N5OT%|Z¾([ \ No newline at end of file diff --git a/secrets/rekeyed/sausebiene/bf9d6a3cda28060387b1c7dcb58bbdfc-mosquitto-pw-zigbee2mqtt.age b/secrets/rekeyed/sausebiene/bf9d6a3cda28060387b1c7dcb58bbdfc-mosquitto-pw-zigbee2mqtt.age new file mode 100644 index 0000000..f9df97d Binary files /dev/null and b/secrets/rekeyed/sausebiene/bf9d6a3cda28060387b1c7dcb58bbdfc-mosquitto-pw-zigbee2mqtt.age differ