diff --git a/nixos/doc/manual/release-notes/rl-2605.section.md b/nixos/doc/manual/release-notes/rl-2605.section.md index 65290e41b983..6b7673a82df9 100644 --- a/nixos/doc/manual/release-notes/rl-2605.section.md +++ b/nixos/doc/manual/release-notes/rl-2605.section.md @@ -79,6 +79,11 @@ of pulling the upstream container image from Docker Hub. If you want the old beh - Support for `reiserfs` in nixpkgs has been removed, following the removal in Linux 6.13. +- `services.tor` no longer bind mounts Unix sockets of onion services into its chroot +because it was not reliable. Users should do it themselves using either `JoinsNamespaceOf=` and Unix sockets in `/tmp` +or `BindPaths=` from a persistent parent directory of each Unix socket. +See . + - support for `ecryptfs` in nixpkgs has been removed. - The `networking.wireless` module has been security hardened: the `wpa_supplicant` daemon now runs under an unprivileged user with restricted access to the system. diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index 1c2cc65862e6..359745b4060d 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -636,7 +636,31 @@ in }; onionServices = lib.mkOption { - description = (descriptionGeneric "HiddenServiceDir"); + description = descriptionGeneric "HiddenServiceDir" + '' + :::{.warning} + Because `tor.service` runs in its own `RootDirectory=`, + when using a onion service to reverse-proxy to a Unix socket, + you need to make that Unix socket available + within the mount namespace of `tor.service`. + + When you can configure your service to create its socket in `/tmp`, + this can be done with: + ```nix + systemd.services.''${your-service} = { + unitConfig.JoinsNamespaceOf = [ "tor.service" ];` + serviceConfig.PrivateTmp = true; + }; + ``` + Otherwise, you can use: + ```nix + systemd.services.tor.serviceConfig.BindPaths = [ "/path/to/your-service/socket/directory" ]; + ``` + but you have to be sure that `/path/to/socket/directory` + exists before `tor.service` is started + and is not deleted and recreated between restarts of `your-service`, + or you'll need to restart `tor.service` to refresh the `BindPaths=`. + ::: + ''; default = { }; example = { "example.org/www" = { @@ -1416,22 +1440,10 @@ in RootDirectoryStartOnly = true; #InaccessiblePaths = [ "-+${runDir}/root" ]; UMask = "0066"; - BindPaths = [ - stateDir - ] - ++ lib.filter (x: x != null) ( - lib.catAttrs "unix" ( - lib.filter (x: x != null) ( - lib.catAttrs "target" ( - lib.concatMap (onionService: onionService.map) (lib.attrValues cfg.relay.onionServices) - ) - ) - ) - ); BindReadOnlyPaths = [ - builtins.storeDir "/etc" ] + ++ lib.optional (!config.systemd.services.tor.confinement.enable) builtins.storeDir ++ lib.optionals config.services.resolved.enable [ "/run/systemd/resolve/stub-resolv.conf" "/run/systemd/resolve/resolv.conf" @@ -1485,7 +1497,6 @@ in "~@timer" ]; SystemCallArchitectures = "native"; - SystemCallErrorNumber = "EPERM"; }; };