Skip to content

nixos/tor: improve type-checking and hardening#97740

Merged
Mic92 merged 1 commit intoNixOS:masterfrom
ju1m:tor
Jan 5, 2021
Merged

nixos/tor: improve type-checking and hardening#97740
Mic92 merged 1 commit intoNixOS:masterfrom
ju1m:tor

Conversation

@ju1m
Copy link
Contributor

@ju1m ju1m commented Sep 11, 2020

This is an attempt to improve services.tor using recent NixOS and systemd features. This is an early release, it needs testing/reviewing. I've done what I could to preserve backward compatibility when mkRemoveOption or mkRenameOption could be used, but not otherwise for options whose structure/names have to change to match torrc's structure or well-known/documented option names. Current users' configs will break, but hopefully only at compile-time and with an helpul warning/error message, and hopefully not with some subtle changes in Tor's behavior. Note also that most of the description= now link to the Tor manual instead of copy/pasting it, because it would be too painful to write/maintain otherwise.

Motivation for this change

Current service for Tor is lacking proper type-checking of options and systemd-level hardening.

Things done
  NAME                                                        DESCRIPTION                                                                    EXPOSURE
✗ PrivateNetwork=                                             Service has access to the host's network                                            0.5
✓ User=/DynamicUser=                                          Service runs under a static non-root user identity                                     
✓ CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP)                Service cannot change UID/GID identities/capabilities                                  
✓ CapabilityBoundingSet=~CAP_SYS_ADMIN                        Service has no administrator privileges                                                
✓ CapabilityBoundingSet=~CAP_SYS_PTRACE                       Service has no ptrace() debugging abilities                                            
✗ RestrictAddressFamilies=~AF_(INET|INET6)                    Service may allocate Internet sockets                                               0.3
✓ RestrictNamespaces=~CLONE_NEWUSER                           Service cannot create user namespaces                                                  
✓ RestrictAddressFamilies=~…                                  Service cannot allocate exotic sockets                                                 
✓ CapabilityBoundingSet=~CAP_(CHOWN|FSETID|SETFCAP)           Service cannot change file ownership/access mode/capabilities                          
✓ CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER)         Service cannot override UNIX file/IPC permission checks                                
✓ CapabilityBoundingSet=~CAP_NET_ADMIN                        Service has no network configuration privileges                                        
✓ CapabilityBoundingSet=~CAP_SYS_MODULE                       Service cannot load kernel modules                                                     
✓ CapabilityBoundingSet=~CAP_SYS_RAWIO                        Service has no raw I/O access                                                          
✓ CapabilityBoundingSet=~CAP_SYS_TIME                         Service processes cannot change the system clock                                       
✗ DeviceAllow=                                                Service has a device ACL with some special devices                                  0.1
✗ IPAddressDeny=                                              Service does not define an IP address allow list                                    0.2
✓ KeyringMode=                                                Service doesn't share key material with other services                                 
✓ NoNewPrivileges=                                            Service processes cannot acquire new privileges                                        
✓ NotifyAccess=                                               Service child processes cannot alter service state                                     
✓ PrivateDevices=                                             Service has no access to hardware devices                                              
✓ PrivateMounts=                                              Service cannot install system mounts                                                   
✓ PrivateTmp=                                                 Service has no access to other software's temporary files                              
✓ PrivateUsers=                                               Service does not have access to other users                                            
✓ ProtectClock=                                               Service cannot write to the hardware clock or system clock                             
✓ ProtectControlGroups=                                       Service cannot modify the control group file system                                    
✓ ProtectHome=                                                Service has no access to home directories                                              
✓ ProtectKernelLogs=                                          Service cannot read from or write to the kernel log ring buffer                        
✓ ProtectKernelModules=                                       Service cannot load or read kernel modules                                             
✓ ProtectKernelTunables=                                      Service cannot alter kernel tunables (/proc/sys, …)                                    
✓ ProtectSystem=                                              Service has strict read-only access to the OS file hierarchy                           
✓ RestrictAddressFamilies=~AF_PACKET                          Service cannot allocate packet sockets                                                 
✓ RestrictSUIDSGID=                                           SUID/SGID file creation by service is restricted                                       
✓ SystemCallArchitectures=                                    Service may execute system calls only with native ABI                                  
✓ SystemCallFilter=~@clock                                    System call allow list defined for service, and @clock is not included                 
✓ SystemCallFilter=~@debug                                    System call allow list defined for service, and @debug is not included                 
✓ SystemCallFilter=~@module                                   System call allow list defined for service, and @module is not included                
✓ SystemCallFilter=~@mount                                    System call allow list defined for service, and @mount is not included                 
✓ SystemCallFilter=~@raw-io                                   System call allow list defined for service, and @raw-io is not included                
✓ SystemCallFilter=~@reboot                                   System call allow list defined for service, and @reboot is not included                
✓ SystemCallFilter=~@swap                                     System call allow list defined for service, and @swap is not included                  
✗ SystemCallFilter=~@privileged                               System call allow list defined for service, and @privileged is included             0.2
✓ SystemCallFilter=~@resources                                System call allow list defined for service, and @resources is not included             
✓ AmbientCapabilities=                                        Service process does not receive ambient capabilities                                  
✓ CapabilityBoundingSet=~CAP_AUDIT_*                          Service has no audit subsystem access                                                  
✓ CapabilityBoundingSet=~CAP_KILL                             Service cannot send UNIX signals to arbitrary processes                                
✓ CapabilityBoundingSet=~CAP_MKNOD                            Service cannot create device nodes                                                     
✓ CapabilityBoundingSet=~CAP_NET_(BIND_SERVICE|BROADCAST|RAW) Service has no elevated networking privileges                                          
✓ CapabilityBoundingSet=~CAP_SYSLOG                           Service has no access to kernel logging                                                
✓ CapabilityBoundingSet=~CAP_SYS_(NICE|RESOURCE)              Service has no privileges to change resource use parameters                            
✓ RestrictNamespaces=~CLONE_NEWCGROUP                         Service cannot create cgroup namespaces                                                
✓ RestrictNamespaces=~CLONE_NEWIPC                            Service cannot create IPC namespaces                                                   
✓ RestrictNamespaces=~CLONE_NEWNET                            Service cannot create network namespaces                                               
✓ RestrictNamespaces=~CLONE_NEWNS                             Service cannot create file system namespaces                                           
✓ RestrictNamespaces=~CLONE_NEWPID                            Service cannot create process namespaces                                               
✓ RestrictRealtime=                                           Service realtime scheduling access is restricted                                       
✓ SystemCallFilter=~@cpu-emulation                            System call allow list defined for service, and @cpu-emulation is not included         
✓ SystemCallFilter=~@obsolete                                 System call allow list defined for service, and @obsolete is not included              
✓ RestrictAddressFamilies=~AF_NETLINK                         Service cannot allocate netlink sockets                                                
✓ RootDirectory=/RootImage=                                   Service has its own root directory/image                                               
✓ SupplementaryGroups=                                        Service has no supplementary groups                                                    
✓ CapabilityBoundingSet=~CAP_MAC_*                            Service cannot adjust SMACK MAC                                                        
✓ CapabilityBoundingSet=~CAP_SYS_BOOT                         Service cannot issue reboot()                                                          
✓ Delegate=                                                   Service does not maintain its own delegated control group subtree                      
✓ LockPersonality=                                            Service cannot change ABI personality                                                  
✓ MemoryDenyWriteExecute=                                     Service cannot create writable executable memory mappings                              
✓ RemoveIPC=                                                  Service user cannot leave SysV IPC objects around                                      
✓ RestrictNamespaces=~CLONE_NEWUTS                            Service cannot create hostname namespaces                                              
✓ UMask=                                                      Files created by service are accessible only by service's own user by default          
✓ CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE                  Service cannot mark files immutable                                                    
✓ CapabilityBoundingSet=~CAP_IPC_LOCK                         Service cannot lock memory into RAM                                                    
✓ CapabilityBoundingSet=~CAP_SYS_CHROOT                       Service cannot issue chroot()                                                          
✓ ProtectHostname=                                            Service cannot change system host/domainname                                           
✓ CapabilityBoundingSet=~CAP_BLOCK_SUSPEND                    Service cannot establish wake locks                                                    
✓ CapabilityBoundingSet=~CAP_LEASE                            Service cannot create file leases                                                      
✓ CapabilityBoundingSet=~CAP_SYS_PACCT                        Service cannot use acct()                                                              
✓ CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG                   Service cannot issue vhangup()                                                         
✓ CapabilityBoundingSet=~CAP_WAKE_ALARM                       Service cannot program timers that wake up the system                                  
✗ RestrictAddressFamilies=~AF_UNIX                            Service may allocate local sockets                                                  0.1

→ Overall exposure level for tor.service: 1.2 OK 🙂
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Sep 11, 2020
@ju1m ju1m changed the title tor: improve type-checking and hardening nixos/tor: improve type-checking and hardening Sep 13, 2020
@ju1m ju1m force-pushed the tor branch 3 times, most recently from 9647a0d to 31954b5 Compare September 14, 2020 17:32
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/377

@SuperSandro2000
Copy link
Member

Can you please fix the eval error?

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/385

@ofborg ofborg bot added 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Nov 26, 2020
@ju1m
Copy link
Contributor Author

ju1m commented Dec 26, 2020

Rebased and adapted after e17d4b0 got merged.

@Mic92
Copy link
Member

Mic92 commented Dec 27, 2020

That's a big one. I will start to have a look.

@Mic92
Copy link
Member

Mic92 commented Dec 27, 2020

@GrahamcOfBorg test tor

@Mic92
Copy link
Member

Mic92 commented Dec 28, 2020

I deployed this on my server and it seems to work for the client setup/hidden services. Can you add a changelog entry to manual/release-notes/rl-2103.xml regarding privoxy and maybe briefly mention services.tor.settings?

@ofborg ofborg bot added 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation labels Jan 4, 2021
@ju1m
Copy link
Contributor Author

ju1m commented Jan 4, 2021

I deployed this on my server and it seems to work for the client setup/hidden services. Can you add a changelog entry to manual/release-notes/rl-2103.xml regarding privoxy and maybe briefly mention services.tor.settings?

@Mic92, thanks for the beta-testing. I've added a release note. A release note about privoxy had been already added by the e17d4b0 commit changing that setup.

@Mic92 Mic92 merged commit a14ea3a into NixOS:master Jan 5, 2021
@sorki
Copy link
Member

sorki commented Jan 5, 2021

I'm getting

trace: Obsolete option `services.tor.client.dns.automapHostsSuffixes' is used. It was renamed to `services.tor.settings.AutomapHostsSuffixes'.
error: infinite recursion encountered, at /etc/nixpkgs/lib/attrsets.nix:344:7

using

  services.tor = {
    enable = true;
    client.enable = true;
    client.dns.enable = true;
  };

@Mic92
Copy link
Member

Mic92 commented Jan 6, 2021

@sorki fixed in #108524

@delroth
Copy link
Contributor

delroth commented Jan 12, 2021

openFirewall seems broken when ORPort contains just an int:

error: value is an integer while a set was expected, at /nix/store/7g5sba5r5nyd9z8c722rvqybl1vpjxmh-nixpkgs/nixos/modules/services/security/tor.nix:912:95
concatMap (o: optional (isInt o && o > 0 || o ? "port" && isInt o.port && o.port > 0) o.port)

This always accesses o.port even if isInt.

@ju1m
Copy link
Contributor Author

ju1m commented Jan 12, 2021

openFirewall seems broken when ORPort contains just an int:

error: value is an integer while a set was expected, at /nix/store/7g5sba5r5nyd9z8c722rvqybl1vpjxmh-nixpkgs/nixos/modules/services/security/tor.nix:912:95
concatMap (o: optional (isInt o && o > 0 || o ? "port" && isInt o.port && o.port > 0) o.port)

This always accesses o.port even if isInt.

@delroth Thanks for the report, this should fix the issue: #109096 (no time to test right now)

@alyssais
Copy link
Member

I had previously been setting

  services.tor.extraConfig = ''
    ORPort [2001:ba8:1f1:f0bc::2]:${toString config.services.tor.relay.port}
  '';

To make my relay reachable over IPv6 (which requires manually specifying the IPv6 address in ORPort). As far as I can tell, there’s no way to do that any more, because there’s no more extraConfig option and services.tor.settings.ORPort does not accept values of this format.

@Mic92
Copy link
Member

Mic92 commented Jan 15, 2021

I had previously been setting

  services.tor.extraConfig = ''
    ORPort [2001:ba8:1f1:f0bc::2]:${toString config.services.tor.relay.port}
  '';

To make my relay reachable over IPv6 (which requires manually specifying the IPv6 address in ORPort). As far as I can tell, there’s no way to do that any more, because there’s no more extraConfig option and services.tor.settings.ORPort does not accept values of this format.

So it should actually accept a string?

@alyssais
Copy link
Member

alyssais commented Jan 15, 2021 via email

@ju1m
Copy link
Contributor Author

ju1m commented Jan 15, 2021

I had previously been setting > > nix > services.tor.extraConfig = '' > ORPort [2001:ba8:1f1:f0bc::2]:${toString config.services.tor.relay.port} > ''; > > > To make my relay reachable over IPv6 (which requires manually > specifying the IPv6 address in ORPort). As far as I can tell, > there’s no way to do that any more, because there’s no more > extraConfig option and services.tor.settings.ORPort does not > accept values of this format. So it should actually accept a string?
I suppose so, unless we wanted to make it something more structured, like strMatching or an attribute set. I haven't looked too closely at the rest of this change yet, so I don't know what would be more consistent.

ORPort can be an attrset, I guess this should work:

services.tor.settings.ORPort.addr = "[2001:ba8:1f1:f0bc::2]";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants