summary refs log tree commit diff
path: root/nixos/modules/services/security/tor.nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:20 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:20 +0200
commit5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010 (patch)
treea6c0f605be6de3f372ae69905b331f9f75452da7 /nixos/modules/services/security/tor.nix
parent6070bc016bd2fd945b04347e25cfd3738622d2ac (diff)
downloadnixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.gz
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.bz2
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.lz
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.xz
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.zst
nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.zip
Move all of NixOS to nixos/ in preparation of the repository merge
Diffstat (limited to 'nixos/modules/services/security/tor.nix')
-rw-r--r--nixos/modules/services/security/tor.nix321
1 files changed, 321 insertions, 0 deletions
diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix
new file mode 100644
index 00000000000..2dafb4595c6
--- /dev/null
+++ b/nixos/modules/services/security/tor.nix
@@ -0,0 +1,321 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  inherit (pkgs) tor privoxy;
+
+  stateDir = "/var/lib/tor";
+  privoxyDir = stateDir+"/privoxy";
+
+  cfg = config.services.tor;
+
+  torUser = "tor";
+
+  opt = name: value: if value != "" then "${name} ${value}" else "";
+  optint = name: value: if value != 0 then "${name} ${toString value}" else "";
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.tor = {
+
+      config = mkOption {
+        default = "";
+        description = ''
+          Extra configuration. Contents will be added verbatim to the
+          configuration file.
+        '';
+      };
+
+      client = {
+
+        enable = mkOption {
+          default = false;
+          description = ''
+            Whether to enable Tor daemon to route application connections.
+            You might want to disable this if you plan running a dedicated Tor relay.
+          '';
+        };
+
+        socksListenAddress = mkOption {
+          default = "127.0.0.1:9050";
+          example = "192.168.0.1:9100";
+          description = ''
+            Bind to this address to listen for connections from Socks-speaking
+            applications.
+          '';
+        };
+
+	socksListenAddressFaster = mkOption {
+          default = "127.0.0.1:9063";
+	  description = ''
+            Same as socksListenAddress but uses weaker circuit isolation to provide
+            performance suitable for a web browser.
+          '';
+        };
+
+        socksPolicy = mkOption {
+          default = "";
+          example = "accept 192.168.0.0/16, reject *";
+          description = ''
+            Entry policies to allow/deny SOCKS requests based on IP address.
+            First entry that matches wins. If no SocksPolicy is set, we accept
+            all (and only) requests from SocksListenAddress.
+          '';
+        };
+
+        privoxy = {
+
+          enable = mkOption {
+            default = true;
+            description = ''
+              Whether to enable a special instance of privoxy dedicated to Tor.
+              To have anonymity, protocols need to be scrubbed of identifying
+              information.
+              Most people using Tor want to anonymize their web traffic, so by
+              default we enable an special instance of privoxy specifically for
+              Tor.
+              However, if you are only going to use Tor only for other kinds of
+              traffic then you can disable this option.
+            '';
+          };
+
+          listenAddress = mkOption {
+            default = "127.0.0.1:8118";
+            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.
+            '';
+          };
+
+          config = 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.
+            '';
+          };
+
+        };
+
+      };
+
+      relay = {
+
+        enable = mkOption {
+          default = false;
+          description = ''
+            Whether to enable relaying TOR traffic for others.
+
+            See https://www.torproject.org/docs/tor-doc-relay for details.
+          '';
+        };
+
+        isBridge = mkOption {
+          default = false;
+          description = ''
+            Bridge relays (or "bridges" ) are Tor relays that aren't listed in the
+            main directory. Since there is no complete public list of them, even if an
+            ISP is filtering connections to all the known Tor relays, they probably
+            won't be able to block all the bridges.
+
+            A bridge relay can't be an exit relay.
+
+            You need to set relay.enable to true for this option to take effect.
+
+            The bridge is set up with an obfuscated transport proxy.
+
+            See https://www.torproject.org/bridges.html.en for more info.
+          '';
+        };
+
+        isExit = mkOption {
+          default = false;
+          description = ''
+            An exit relay allows Tor users to access regular Internet services.
+
+            Unlike running a non-exit relay, running an exit relay may expose
+            you to abuse complaints. See https://www.torproject.org/faq.html.en#ExitPolicies for more info.
+
+            You can specify which services Tor users may access via your exit relay using exitPolicy option.
+          '';
+        };
+
+        nickname = mkOption {
+          default = "anonymous";
+          description = ''
+            A unique handle for your TOR relay.
+          '';
+        };
+
+        bandwidthRate = mkOption {
+          default = 0;
+          example = 100;
+          description = ''
+            Specify this to limit the bandwidth usage of relayed (server)
+            traffic. Your own traffic is still unthrottled. Units: bytes/second.
+          '';
+        };
+
+        bandwidthBurst = mkOption {
+          default = cfg.relay.bandwidthRate;
+          example = 200;
+          description = ''
+            Specify this to allow bursts of the bandwidth usage of relayed (server)
+            traffic. The average usage will still be as specified in relayBandwidthRate.
+            Your own traffic is still unthrottled. Units: bytes/second.
+          '';
+        };
+
+        port = mkOption {
+          default = 9001;
+          description = ''
+            What port to advertise for Tor connections.
+          '';
+        };
+
+        listenAddress = mkOption {
+          default = "";
+          example = "0.0.0.0:9090";
+          description = ''
+            Set this if you need to listen on a port other than the one advertised
+            in relayPort (e.g. to advertise 443 but bind to 9090). You'll need to do
+            ipchains or other port forwsarding yourself to make this work.
+          '';
+        };
+
+        exitPolicy = mkOption {
+          default = "";
+          example = "accept *:6660-6667,reject *:*";
+          description = ''
+            A comma-separated list of exit policies. They're considered first
+            to last, and the first match wins. If you want to _replace_
+            the default exit policy, end this with either a reject *:* or an
+            accept *:*. Otherwise, you're _augmenting_ (prepending to) the
+            default exit policy. Leave commented to just use the default, which is
+            available in the man page or at https://www.torproject.org/documentation.html
+
+            Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
+            for issues you might encounter if you use the default exit policy.
+
+            If certain IPs and ports are blocked externally, e.g. by your firewall,
+            you should update your exit policy to reflect this -- otherwise Tor
+            users will be told that those destinations are down.
+          '';
+        };
+
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf (cfg.client.enable || cfg.relay.enable) (
+  mkAssert (cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit)) "
+    Can't be both an exit and a bridge relay at the same time
+  " {
+
+    users.extraUsers = singleton
+      { name = torUser;
+        uid = config.ids.uids.tor;
+        description = "Tor daemon user";
+        home = stateDir;
+      };
+
+    jobs = {
+      tor = { name = "tor";
+
+              startOn = "started network-interfaces";
+              stopOn = "stopping network-interfaces";
+
+              preStart = ''
+                mkdir -m 0755 -p ${stateDir}
+                chown ${torUser} ${stateDir}
+              '';
+              exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" cfg.config}";
+    }; }
+    // optionalAttrs (cfg.client.privoxy.enable && cfg.client.enable) {
+      torPrivoxy = { name = "tor-privoxy";
+
+                     startOn = "started network-interfaces";
+                     stopOn = "stopping network-interfaces";
+
+                     preStart = ''
+                       mkdir -m 0755 -p ${privoxyDir}
+                       chown ${torUser} ${privoxyDir}
+                     '';
+                     exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" cfg.client.privoxy.config}";
+    }; };
+
+      services.tor.config = ''
+        DataDirectory ${stateDir}
+        User ${torUser}
+      ''
+      + optionalString cfg.client.enable  ''
+        SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
+	SOCKSPort ${cfg.client.socksListenAddressFaster}
+        ${opt "SocksPolicy" cfg.client.socksPolicy}
+      ''
+      + optionalString cfg.relay.enable ''
+        ORPort ${toString cfg.relay.port}
+        ${opt "ORListenAddress" cfg.relay.listenAddress }
+        ${opt "Nickname" cfg.relay.nickname}
+        ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
+        ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
+        ${if cfg.relay.isExit then opt "ExitPolicy" cfg.relay.exitPolicy else "ExitPolicy reject *:*"}
+        ${if cfg.relay.isBridge then ''
+          BridgeRelay 1
+          ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
+        '' else ""}
+      '';
+
+      services.tor.client.privoxy.config = ''
+        # Generally, this file goes in /etc/privoxy/config
+        #
+        # Tor listens as a SOCKS4a proxy here:
+        forward-socks4a / ${cfg.client.socksListenAddressFaster} .
+        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  ${cfg.client.privoxy.listenAddress}
+        toggle  1
+        enable-remote-toggle 0
+        enable-edit-actions 0
+        enable-remote-http-toggle 0
+        buffer-limit 4096
+
+        # Extra config goes here
+      '';
+
+  });
+
+}