nixos/esphome: replace DynamicUser with static system user (#508178)
This commit is contained in:
@@ -303,6 +303,8 @@ See <https://github.com/NixOS/nixpkgs/issues/481673>.
|
||||
|
||||
- `opengfw` package and `services.opengfw` module have been removed as the upstream GitHub repository and website have been shut down.
|
||||
|
||||
- `services.esphome` no longer uses `DynamicUser`. The service now runs as a static `esphome` system user. systemd handles the migration from `/var/lib/private/esphome` automatically, but users with [impermanence](https://github.com/nix-community/impermanence) setups should ensure `/var/lib/esphome` is persisted.
|
||||
|
||||
## Other Notable Changes {#sec-release-26.05-notable-changes}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
maintainers
|
||||
mkEnableOption
|
||||
mkIf
|
||||
@@ -17,7 +16,7 @@ let
|
||||
|
||||
cfg = config.services.esphome;
|
||||
|
||||
stateDir = "esphome";
|
||||
stateDir = "/var/lib/esphome";
|
||||
|
||||
esphomeParams =
|
||||
if cfg.enableUnixSocket then
|
||||
@@ -106,6 +105,18 @@ in
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = mkIf (cfg.openFirewall && !cfg.enableUnixSocket) [ cfg.port ];
|
||||
|
||||
# Use a static system user instead of DynamicUser.
|
||||
# DynamicUser creates a /var/lib/esphome -> /var/lib/private/esphome symlink
|
||||
# which breaks PlatformIO's path resolution during firmware compilation.
|
||||
# See: https://github.com/NixOS/nixpkgs/issues/339557
|
||||
users.users.esphome = {
|
||||
isSystemUser = true;
|
||||
home = stateDir;
|
||||
group = "esphome";
|
||||
};
|
||||
|
||||
users.groups.esphome = { };
|
||||
|
||||
systemd.services.esphome = {
|
||||
description = "ESPHome dashboard";
|
||||
after = [ "network.target" ];
|
||||
@@ -113,26 +124,27 @@ in
|
||||
path = [ cfg.package ];
|
||||
|
||||
environment = {
|
||||
# platformio fails to determine the home directory when using DynamicUser
|
||||
PLATFORMIO_CORE_DIR = "%S/${stateDir}/.platformio";
|
||||
# Set PLATFORMIO_CORE_DIR to a real path (not a symlink) so PlatformIO
|
||||
# and its downloaded toolchains can resolve paths correctly.
|
||||
PLATFORMIO_CORE_DIR = "${stateDir}/.platformio";
|
||||
# platformio needs a writable HOME for its configuration
|
||||
HOME = stateDir;
|
||||
}
|
||||
// lib.optionalAttrs cfg.usePing { ESPHOME_DASHBOARD_USE_PING = "true"; }
|
||||
// cfg.environment;
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/esphome dashboard ${esphomeParams} %S/${stateDir}";
|
||||
DynamicUser = true;
|
||||
ExecStart = "${cfg.package}/bin/esphome dashboard ${esphomeParams} ${stateDir}";
|
||||
User = "esphome";
|
||||
Group = "esphome";
|
||||
WorkingDirectory = "%S/${stateDir}";
|
||||
WorkingDirectory = stateDir;
|
||||
StateDirectory = "esphome";
|
||||
StateDirectoryMode = "0750";
|
||||
Restart = "on-failure";
|
||||
RuntimeDirectory = mkIf cfg.enableUnixSocket "esphome";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
ExecPaths = "%S/${stateDir}";
|
||||
ReadWritePaths = "%S/${stateDir}";
|
||||
ReadWritePaths = [ stateDir ];
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
@@ -141,9 +153,8 @@ in
|
||||
DevicePolicy = "closed";
|
||||
DeviceAllow = map (d: "${d} rw") cfg.allowedDevices;
|
||||
SupplementaryGroups = [ "dialout" ];
|
||||
#NoNewPrivileges = true; # Implied by DynamicUser
|
||||
PrivateUsers = true;
|
||||
#PrivateTmp = true; # Implied by DynamicUser
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
@@ -154,7 +165,7 @@ in
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "all"; # Using "pid" breaks bwrap
|
||||
ProtectSystem = "strict";
|
||||
#RemoveIPC = true; # Implied by DynamicUser
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
@@ -163,7 +174,7 @@ in
|
||||
];
|
||||
RestrictNamespaces = false; # Required by platformio for chroot
|
||||
RestrictRealtime = true;
|
||||
#RestrictSUIDSGID = true; # Implied by DynamicUser
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
|
||||
Reference in New Issue
Block a user