From aa24bdf88fd39da965f7783058951b1a92780539 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Tue, 20 Jan 2026 17:04:41 +0100 Subject: [PATCH] nixos/tor: do not put Unix sockets in BindPaths= - The socket may not be accessible at all times resulting in the Tor unit failing to start. - If the socket is re-created it will become inaccessible. - Tor can't be started if any of the UNIX sockets are not available, which may result in a single service having issues affecting all services. (It may be best to start Tor to serve N-1 sockets even if 1 socket isn't available). Reverts: https://github.com/NixOS/nixpkgs/pull/440889 Fixes: https://github.com/NixOS/nixpkgs/issues/481673 Reported-by: https://github.com/kevincox --- .../manual/release-notes/rl-2605.section.md | 5 +++ nixos/modules/services/security/tor.nix | 38 ++++++++++++------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2605.section.md b/nixos/doc/manual/release-notes/rl-2605.section.md index d29cb9aa49dc..8c85dbc110f9 100644 --- a/nixos/doc/manual/release-notes/rl-2605.section.md +++ b/nixos/doc/manual/release-notes/rl-2605.section.md @@ -77,6 +77,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..0c86f9572e09 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,18 +1440,6 @@ 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"