diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index 806252f49b8d..4f4f11907a77 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -695,19 +695,38 @@ in uid = config.ids.uids.tor; }; + # We have to do this instead of using RuntimeDirectory option in + # the service below because systemd has no way to set owners of + # RuntimeDirectory and putting this into the service below + # requires that service to relax it's sandbox since this needs + # writable /run + systemd.services.tor-init = + { description = "Tor Daemon Init"; + wantedBy = [ "tor.service" ]; + after = [ "local-fs.target" ]; + script = '' + install -m 0700 -o tor -g tor -d ${torDirectory} ${torDirectory}/onion + install -m 0750 -o tor -g tor -d ${torRunDirectory} + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + systemd.services.tor = { description = "Tor Daemon"; path = [ pkgs.tor ]; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; + after = [ "tor-init.service" "network.target" ]; restartTriggers = [ torRcFile ]; serviceConfig = { Type = "simple"; # Translated from the upstream contrib/dist/tor.service.in ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config"; - ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile} --RunAsDaemon 0"; + ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; KillSignal = "SIGINT"; TimeoutSec = 30; @@ -715,20 +734,18 @@ in LimitNOFILE = 32768; # Hardening - # Note: DevicePolicy is set to 'closed', although the - # minimal permissions are really: - # DeviceAllow /dev/null rw - # DeviceAllow /dev/urandom r - # .. but we can't specify DeviceAllow multiple times. 'closed' - # is close enough. - RuntimeDirectory = "tor"; - StateDirectory = [ "tor" "tor/onion" ]; - PrivateTmp = "yes"; - DevicePolicy = "closed"; - InaccessibleDirectories = "/home"; - ReadOnlyDirectories = "/"; - ReadWriteDirectories = [torDirectory torRunDirectory]; + # this seems to unshare /run despite what systemd.exec(5) says + PrivateTmp = mkIf (!cfg.controlSocket.enable) "yes"; + PrivateDevices = "yes"; + ProtectHome = "yes"; + ProtectSystem = "strict"; + InaccessiblePaths = "/home"; + ReadOnlyPaths = "/"; + ReadWritePaths = [ torDirectory torRunDirectory ]; NoNewPrivileges = "yes"; + + # tor.service.in has this in, but this line it fails to spawn a namespace when using hidden services + #CapabilityBoundingSet = "CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE"; }; };