[Nix-dev] Patches for a NixOS Tor service

roconnor at theorem.ca roconnor at theorem.ca
Sun May 2 22:57:37 CEST 2010


Here are the patches needed to create a tor service for NixOS.  It's a bit 
preliminary at the moment, but the main funcitonality is there.

Bugs: the torify program doesn't work yet.

-- 
Russell O'Connor                                      <http://r6.ca/>
``All talk about `theft,''' the general counsel of the American Graphophone
Company wrote, ``is the merest claptrap, for there exists no property in
ideas musical, literary or artistic, except as defined by statute.''
-------------- next part --------------
Index: modules/services/security/tor.nix
===================================================================
--- modules/services/security/tor.nix   (revision 0)
+++ modules/services/security/tor.nix   (revision 0)
@@ -0,0 +1,167 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  inherit (pkgs) tor privoxy;
+
+  stateDir = "/var/lib/tor";
+  privoxyDir = stateDir+"/privoxy";
+
+  modprobe = config.system.sbin.modprobe;
+
+  torUser = "tor";
+
+in
+
+{
+
+  ###### interface
+  
+  options = {
+  
+    services.tor = {
+
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to enable the tor socks proxy.
+        '';
+      };
+
+      socksListenAddress = mkOption {
+        default = "127.0.0.1:9050";
+        example = "192.168.0.1";
+        description = ''
+          Bind to this address to listen for connections from Socks-speaking applications. You can also specify a port.
+        '';
+      };
+
+      config = mkOption {
+        default = "";
+        description = ''
+          Extra configuration. Contents will be added verbatim to the configuration file.
+        '';
+      };
+
+      enablePrivoxy = mkOption {
+        default = true;
+        description = ''
+          Whether to enable the tor instance of privoxy.
+          For anonymity protocols need to be scrubbed of identifying information.
+          HTTP is the most common protocol that is used so by default we enable an
+          instance of privoxy specifically for tor so that it won't conflict with the
+          standard NixOS privoxy instance.
+          For example, If you are only going to use tor as a relay, then you can disable this option
+        '';
+      };
+      
+      privoxyListenAddress = mkOption {
+        default = "127.0.0.1:8181";
+        description = ''
+          Address that tor's instance of privoxy is listening to.
+          *This does not configure the standard NixOS instance of privoxy.*  This is for tor connections only! 
+          See services.privoxy.listenAddress to configure the standard NixOS instace of privoxy.
+          Avoid conflicting with the standard NixOS instance of privoxy, both have the same default values. So
+          one needs to change if you are going to run both tor's and NixOS's privoxy services.
+        '';
+      };
+
+      privoxyConfig = mkOption {
+        default = "";
+        description = ''
+          Extra configuration for tor's instance of privoxy. Contents will be added verbatim to the configuration file.
+          *This does not configure the standard NixOS instance of privoxy.*  This is for tor connections only! 
+          See services.privoxy.extraConfig to configure the standard NixOS instace of privoxy.
+        '';
+      };
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.services.tor.enable {
+    environment.systemPackages = [ tor ];  # provides tor-resolve and torify
+  
+    users.extraUsers = singleton
+      { name = torUser;
+        uid = config.ids.uids.tor;
+        description = "tor daemon user";
+        home = stateDir;
+      };
+
+    jobs.tor =
+      { name = "tor";
+
+        startOn = "startup";
+        stopOn = "shutdown"; 
+
+        preStart =
+          ''
+            mkdir -m 0755 -p ${stateDir}
+            chown ${torUser} ${stateDir}
+          '';
+        exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" config.services.tor.config}";
+      };
+
+    jobs.torPrivoxy = mkIf config.services.tor.enablePrivoxy 
+      { name = "tor-privoxy";
+
+        startOn = "starting tor";
+        stopOn = "stopping tor"; 
+
+        preStart =
+          ''
+            mkdir -m 0755 -p ${privoxyDir}
+            chown ${torUser} ${privoxyDir}
+
+            # Needed to run privoxy as an unprivileged user?
+            ${modprobe}/sbin/modprobe capability || true
+          '';
+        exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" config.services.tor.privoxyConfig}";
+      };
+
+      services.tor.config = ''
+        DataDirectory ${stateDir}
+        User ${torUser}
+        SocksListenAddress ${config.services.tor.socksListenAddress}
+    
+        # Extra configurations go here
+      '';
+    
+      services.tor.privoxyConfig = ''
+        # Generally, this file goes in /etc/privoxy/config
+        #
+        # Tor listens as a SOCKS4a proxy here:
+        forward-socks4a / ${config.services.tor.socksListenAddress} .
+        confdir ${privoxy}/etc
+        logdir ${privoxyDir}
+        # actionsfile standard  # Internal purpose, recommended
+        actionsfile default.action   # Main actions file
+        actionsfile user.action      # User customizations
+        filterfile default.filter
+        
+        # Don't log interesting things, only startup messages, warnings and errors
+        logfile logfile
+        #jarfile jarfile
+        #debug   0    # show each GET/POST/CONNECT request
+        debug   4096 # Startup banner and warnings
+        debug   8192 # Errors - *we highly recommended enabling this*
+        
+        user-manual ${privoxy}/doc/privoxy/user-manual
+        listen-address  ${config.services.tor.privoxyListenAddress}
+        toggle  1
+        enable-remote-toggle 0
+        enable-edit-actions 0
+        enable-remote-http-toggle 0
+        buffer-limit 4096
+    
+        # Extra config goes here
+      '';
+     
+  };
+  
+}
Index: modules/misc/ids.nix
===================================================================
--- modules/misc/ids.nix        (revision 21556)
+++ modules/misc/ids.nix        (working copy)
@@ -53,6 +53,7 @@
     davfs2 = 31;
     privoxy = 32;    
     osgi = 34;
+    tor = 35;    
     # When adding a uid, make sure it doesn't match an existing gid.
 
     nixbld = 30000; # start of range of uids
Index: modules/module-list.nix
===================================================================
--- modules/module-list.nix     (revision 21556)
+++ modules/module-list.nix     (working copy)
@@ -103,6 +103,7 @@
   ./services/scheduling/atd.nix
   ./services/scheduling/cron.nix
   ./services/scheduling/fcron.nix
+  ./services/security/tor.nix
   ./services/system/dbus.nix
   ./services/system/nscd.nix
   ./services/system/uptimed.nix
-------------- next part --------------
Index: pkgs/tools/security/tor/default.nix
===================================================================
--- pkgs/tools/security/tor/default.nix (revision 0)
+++ pkgs/tools/security/tor/default.nix (revision 0)
@@ -0,0 +1,12 @@
+{stdenv, fetchurl, libevent, openssl, zlib}:
+
+stdenv.mkDerivation {
+  name = "tor-0.2.1.25";
+
+  src = fetchurl {
+    url = "http://www.torproject.org/dist/tor-0.2.1.25.tar.gz";
+    sha256 = "17hpnvlqimblgprx6qwv8akqy5ric08m0265rl4zm1jnxa4v8n47";
+  };
+
+  buildInputs = [libevent openssl zlib];
+}
Index: pkgs/top-level/all-packages.nix
===================================================================
--- pkgs/top-level/all-packages.nix     (revision 21556)
+++ pkgs/top-level/all-packages.nix     (working copy)
@@ -1685,6 +1685,10 @@
     inherit (xlibs) libX11 libXext;
   };
 
+  tor = import ../tools/security/tor {
+    inherit fetchurl stdenv libevent openssl zlib;
+  };
+
   ttf2pt1 = import ../tools/misc/ttf2pt1 {
     inherit fetchurl stdenv perl freetype;
   };


More information about the nix-dev mailing list