1 { config, lib, pkgs, ... }:
6 cfg = config.services.tor;
7 torDirectory = "/var/lib/tor";
8 torRunDirectory = "/run/tor";
10 opt = name: value: optionalString (value != null) "${name} ${value}";
11 optint = name: value: optionalString (value != null && value != 0) "${name} ${toString value}";
14 type = types.listOf (types.enum [
17 "IsolateClientProtocol"
25 "IsolateClientProtocol"
29 description = "Tor isolation options";
34 DataDirectory ${torDirectory}
35 ${optionalString cfg.enableGeoIP ''
36 GeoIPFile ${cfg.package.geoip}/share/tor/geoip
37 GeoIPv6File ${cfg.package.geoip}/share/tor/geoip6
40 ${optint "ControlPort" cfg.controlPort}
41 ${optionalString cfg.controlSocket.enable "ControlPort unix:${torRunDirectory}/control GroupWritable RelaxDirModeCheck"}
43 # Client connection config
44 + optionalString cfg.client.enable ''
45 SOCKSPort ${cfg.client.socksListenAddress} ${toString cfg.client.socksIsolationOptions}
46 SOCKSPort ${cfg.client.socksListenAddressFaster}
47 ${opt "SocksPolicy" cfg.client.socksPolicy}
49 ${optionalString cfg.client.transparentProxy.enable ''
50 TransPort ${cfg.client.transparentProxy.listenAddress} ${toString cfg.client.transparentProxy.isolationOptions}
53 ${optionalString cfg.client.dns.enable ''
54 DNSPort ${cfg.client.dns.listenAddress} ${toString cfg.client.dns.isolationOptions}
55 AutomapHostsOnResolve 1
56 AutomapHostsSuffixes ${concatStringsSep "," cfg.client.dns.automapHostsSuffixes}
59 # Explicitly disable the SOCKS server if the client is disabled. In
60 # particular, this makes non-anonymous hidden services possible.
61 + optionalString (! cfg.client.enable) ''
65 + optionalString cfg.relay.enable ''
66 ORPort ${toString cfg.relay.port}
67 ${opt "Address" cfg.relay.address}
68 ${opt "Nickname" cfg.relay.nickname}
69 ${opt "ContactInfo" cfg.relay.contactInfo}
71 ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
72 ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
73 ${opt "AccountingMax" cfg.relay.accountingMax}
74 ${opt "AccountingStart" cfg.relay.accountingStart}
76 ${if (cfg.relay.role == "exit") then
77 opt "ExitPolicy" cfg.relay.exitPolicy
79 "ExitPolicy reject *:*"}
81 ${optionalString (elem cfg.relay.role ["bridge" "private-bridge"]) ''
83 ServerTransportPlugin ${concatStringsSep "," cfg.relay.bridgeTransports} exec ${pkgs.obfs4}/bin/obfs4proxy managed
85 ${optionalString (cfg.relay.role == "private-bridge") ''
87 PublishServerDescriptor 0
92 + concatStrings (flip mapAttrsToList cfg.hiddenServices (n: v: ''
93 HiddenServiceDir ${torDirectory}/onion/${v.name}
94 ${optionalString (v.version != null) "HiddenServiceVersion ${toString v.version}"}
95 ${flip concatMapStrings v.map (p: ''
96 HiddenServicePort ${toString p.port} ${p.destination}
98 ${optionalString (v.authorizeClient != null) ''
99 HiddenServiceAuthorizeClient ${v.authorizeClient.authType} ${concatStringsSep "," v.authorizeClient.clientNames}
104 torRcFile = pkgs.writeText "torrc" torRc;
109 (mkRenamedOptionModule [ "services" "tor" "relay" "portSpec" ] [ "services" "tor" "relay" "port" ])
110 (mkRemovedOptionModule [ "services" "tor" "relay" "isBridge" ] "Use services.tor.relay.role instead.")
111 (mkRemovedOptionModule [ "services" "tor" "relay" "isExit" ] "Use services.tor.relay.role instead.")
116 enable = mkEnableOption ''Tor daemon.
117 By default, the daemon is run without
118 relay, exit, bridge or client connectivity.
122 type = types.package;
124 defaultText = "pkgs.tor";
125 example = literalExample "pkgs.tor";
131 enableGeoIP = mkOption {
135 Whenever to configure Tor daemon to use GeoIP databases.
137 Disabling this will disable by-country statistics for
138 bridges and relays and some client and third-party software
143 extraConfig = mkOption {
147 Extra configuration. Contents will be added verbatim to the
148 configuration file at the end.
152 controlPort = mkOption {
153 type = types.nullOr (types.either types.int types.str);
157 If set, Tor will accept connections on the specified port
158 and allow them to control the tor process.
167 Whether to enable Tor control socket. Control socket is created
168 in <literal>${torRunDirectory}/control</literal>
178 Whether to enable Tor daemon to route application
179 connections. You might want to disable this if you plan
180 running a dedicated Tor relay.
184 socksListenAddress = mkOption {
186 default = "127.0.0.1:9050";
187 example = "192.168.0.1:9100";
189 Bind to this address to listen for connections from
190 Socks-speaking applications. Provides strong circuit
191 isolation, separate circuit per IP address.
195 socksListenAddressFaster = mkOption {
197 default = "127.0.0.1:9063";
198 example = "192.168.0.1:9101";
200 Bind to this address to listen for connections from
201 Socks-speaking applications. Same as
202 <option>socksListenAddress</option> but uses weaker
203 circuit isolation to provide performance suitable for a
208 socksPolicy = mkOption {
209 type = types.nullOr types.str;
211 example = "accept 192.168.0.0/16, reject *";
213 Entry policies to allow/deny SOCKS requests based on IP
214 address. First entry that matches wins. If no SocksPolicy
215 is set, we accept all (and only) requests from
216 <option>socksListenAddress</option>.
220 socksIsolationOptions = mkOption (isolationOptions // {
221 default = ["IsolateDestAddr"];
228 description = "Whether to enable tor transparent proxy";
231 listenAddress = mkOption {
233 default = "127.0.0.1:9040";
234 example = "192.168.0.1:9040";
236 Bind transparent proxy to this address.
240 isolationOptions = mkOption isolationOptions;
247 description = "Whether to enable tor dns resolver";
250 listenAddress = mkOption {
252 default = "127.0.0.1:9053";
253 example = "192.168.0.1:9053";
255 Bind tor dns to this address.
259 isolationOptions = mkOption isolationOptions;
261 automapHostsSuffixes = mkOption {
262 type = types.listOf types.str;
263 default = [".onion" ".exit"];
264 example = [".onion"];
265 description = "List of suffixes to use with automapHostsOnResolve";
269 privoxy.enable = lib.mkEnableOption ''Privoxy system,
270 to use Tor's faster port, suitable for HTTP.
272 To have anonymity, protocols need to be scrubbed of identifying
273 information, and this can be accomplished for HTTP by Privoxy.
275 Privoxy can also be useful for KDE torification. A good setup would be:
276 setting SOCKS proxy to the default Tor port, providing maximum
277 circuit isolation where possible; and setting HTTP proxy to Privoxy
278 to route HTTP traffic over faster, but less isolated port.
287 Whether to enable relaying TOR traffic for others.
289 See <link xlink:href="https://www.torproject.org/docs/tor-doc-relay" />
292 Setting this to true requires setting
293 <option>services.tor.relay.role</option>
295 <option>services.tor.relay.port</option>
301 type = types.enum [ "exit" "relay" "bridge" "private-bridge" ];
303 Your role in Tor network. There're several options:
307 <term><literal>exit</literal></term>
310 An exit relay. This allows Tor users to access regular
311 Internet services through your public IP.
315 Running an exit relay may expose you to abuse
317 <link xlink:href="https://www.torproject.org/faq.html.en#ExitPolicies" />
322 You can specify which services Tor users may access via
323 your exit relay using <option>exitPolicy</option> option.
329 <term><literal>relay</literal></term>
332 Regular relay. This allows Tor users to relay onion
333 traffic to other Tor nodes, but not to public
338 Note that some misconfigured and/or disrespectful
339 towards privacy sites will block you even if your
340 relay is not an exit relay. That is, just being listed
341 in a public relay directory can have unwanted
344 Which means you might not want to use
345 this role if you browse public Internet from the same
346 network as your relay, unless you want to write
347 e-mails to those sites (you should!).
352 <link xlink:href="https://www.torproject.org/docs/tor-doc-relay.html.en" />
359 <term><literal>bridge</literal></term>
362 Regular bridge. Works like a regular relay, but
363 doesn't list you in the public relay directory and
364 hides your Tor node behind obfs4proxy.
368 Using this option will make Tor advertise your bridge
369 to users through various mechanisms like
370 <link xlink:href="https://bridges.torproject.org/" />, though.
375 WARNING: THE FOLLOWING PARAGRAPH IS NOT LEGAL ADVICE.
376 Consult with your lawer when in doubt.
380 This role should be safe to use in most situations
381 (unless the act of forwarding traffic for others is
382 a punishable offence under your local laws, which
383 would be pretty insane as it would make ISP
389 See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
396 <term><literal>private-bridge</literal></term>
399 Private bridge. Works like regular bridge, but does
400 not advertise your node in any way.
404 Using this role means that you won't contribute to Tor
405 network in any way unless you advertise your node
406 yourself in some way.
410 Use this if you want to run a private bridge, for
411 example because you'll give out your bridge address
412 manually to your friends.
416 Switching to this role after measurable time in
417 "bridge" role is pretty useless as some Tor users
418 would have learned about your node already. In the
419 latter case you can still change
420 <option>port</option> option.
424 See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
433 bridgeTransports = mkOption {
434 type = types.listOf types.str;
436 example = ["obfs2" "obfs3" "obfs4" "scramblesuit"];
437 description = "List of pluggable transports";
440 nickname = mkOption {
442 default = "anonymous";
444 A unique handle for your TOR relay.
448 contactInfo = mkOption {
449 type = types.nullOr types.str;
451 example = "admin@relay.com";
453 Contact information for the relay owner (e.g. a mail
454 address and GPG key ID).
458 accountingMax = mkOption {
459 type = types.nullOr types.str;
461 example = "450 GBytes";
463 Specify maximum bandwidth allowed during an accounting period. This
464 allows you to limit overall tor bandwidth over some time period.
465 See the <literal>AccountingMax</literal> option by looking at the
466 tor manual <citerefentry><refentrytitle>tor</refentrytitle>
467 <manvolnum>1</manvolnum></citerefentry> for more.
469 Note this limit applies individually to upload and
470 download; if you specify <literal>"500 GBytes"</literal>
471 here, then you may transfer up to 1 TBytes of overall
472 bandwidth (500 GB upload, 500 GB download).
476 accountingStart = mkOption {
477 type = types.nullOr types.str;
479 example = "month 1 1:00";
481 Specify length of an accounting period. This allows you to limit
482 overall tor bandwidth over some time period. See the
483 <literal>AccountingStart</literal> option by looking at the tor
484 manual <citerefentry><refentrytitle>tor</refentrytitle>
485 <manvolnum>1</manvolnum></citerefentry> for more.
489 bandwidthRate = mkOption {
490 type = types.nullOr types.int;
494 Specify this to limit the bandwidth usage of relayed (server)
495 traffic. Your own traffic is still unthrottled. Units: bytes/second.
499 bandwidthBurst = mkOption {
500 type = types.nullOr types.int;
501 default = cfg.relay.bandwidthRate;
504 Specify this to allow bursts of the bandwidth usage of relayed (server)
505 traffic. The average usage will still be as specified in relayBandwidthRate.
506 Your own traffic is still unthrottled. Units: bytes/second.
511 type = types.nullOr types.str;
513 example = "noname.example.com";
515 The IP address or full DNS name for advertised address of your relay.
516 Leave unset and Tor will guess.
521 type = types.either types.int types.str;
524 What port to advertise for Tor connections. This corresponds to the
525 <literal>ORPort</literal> section in the Tor manual; see
526 <citerefentry><refentrytitle>tor</refentrytitle>
527 <manvolnum>1</manvolnum></citerefentry> for more details.
529 At a minimum, you should just specify the port for the
530 relay to listen on; a common one like 143, 22, 80, or 443
531 to help Tor users who may have very restrictive port-based
536 exitPolicy = mkOption {
537 type = types.nullOr types.str;
539 example = "accept *:6660-6667,reject *:*";
541 A comma-separated list of exit policies. They're
542 considered first to last, and the first match wins. If you
543 want to _replace_ the default exit policy, end this with
544 either a reject *:* or an accept *:*. Otherwise, you're
545 _augmenting_ (prepending to) the default exit policy.
546 Leave commented to just use the default, which is
547 available in the man page or at
548 <link xlink:href="https://www.torproject.org/documentation.html" />.
551 <link xlink:href="https://www.torproject.org/faq-abuse.html#TypicalAbuses" />
552 for issues you might encounter if you use the default
555 If certain IPs and ports are blocked externally, e.g. by
556 your firewall, you should update your exit policy to
557 reflect this -- otherwise Tor users will be told that
558 those destinations are down.
563 hiddenServices = mkOption {
565 A set of static hidden services that terminate their Tor
566 circuits at this node.
568 Every element in this set declares a virtual onion host.
570 You can specify your onion address by putting corresponding
571 private key to an appropriate place in ${torDirectory}.
573 For services without private keys in ${torDirectory} Tor
574 daemon will generate random key pairs (which implies random
575 onion addresses) on restart. The latter could take a while,
579 Hidden services can be useful even if you don't intend to
580 actually <emphasis>hide</emphasis> them, since they can
581 also be seen as a kind of NAT traversal mechanism.
583 E.g. the example will make your sshd, whatever runs on
584 "8080" and your mail server available from anywhere where
585 the Tor network is available (which, with the help from
586 bridges, is pretty much everywhere), even if both client
587 and server machines are behind NAT you have no control
592 example = literalExample ''
593 { "my-hidden-service-example".map = [
594 { port = 22; } # map ssh port to this machine's ssh
595 { port = 80; toPort = 8080; } # map http port to whatever runs on 8080
596 { port = "sip"; toHost = "mail.example.com"; toPort = "imap"; } # because we can
600 type = types.loaOf (types.submodule ({name, ...}: {
606 Name of this tor hidden service.
608 This is purely descriptive.
610 After restarting Tor daemon you should be able to
611 find your .onion address in
612 <literal>${torDirectory}/onion/$name/hostname</literal>.
618 description = "Port mapping for this hidden service.";
619 type = types.listOf (types.submodule ({config, ...}: {
623 type = types.either types.int types.str;
626 Hidden service port to "bind to".
630 destination = mkOption {
633 description = "Forward these connections where?";
638 default = "127.0.0.1";
639 description = "Mapping destination host.";
643 type = types.either types.int types.str;
645 description = "Mapping destination port.";
651 toPort = mkDefault config.port;
652 destination = mkDefault "${config.toHost}:${toString config.toPort}";
657 authorizeClient = mkOption {
659 description = "If configured, the hidden service is accessible for authorized clients only.";
660 type = types.nullOr (types.submodule ({...}: {
664 authType = mkOption {
665 type = types.enum [ "basic" "stealth" ];
667 Either <literal>"basic"</literal> for a general-purpose authorization protocol
668 or <literal>"stealth"</literal> for a less scalable protocol
669 that also hides service activity from unauthorized clients.
673 clientNames = mkOption {
674 type = types.nonEmptyListOf (types.strMatching "[A-Za-z0-9+-_]+");
676 Only clients that are listed here are authorized to access the hidden service.
677 Generated authorization data can be found in <filename>${torDirectory}/onion/$name/hostname</filename>.
678 Clients need to put this authorization data in their configuration file using <literal>HidServAuth</literal>.
687 description = "Rendezvous service descriptor version to publish for the hidden service. Currently, versions 2 and 3 are supported. (Default: 2)";
688 type = types.nullOr (types.enum [ 2 3 ]);
693 name = mkDefault name;
700 config = mkIf cfg.enable {
701 # Not sure if `cfg.relay.role == "private-bridge"` helps as tor
702 # sends a lot of stats
703 warnings = optional (cfg.relay.enable && cfg.hiddenServices != {})
705 Running Tor hidden services on a public relay makes the
706 presence of hidden services visible through simple statistical
707 analysis of publicly available data.
709 You can safely ignore this warning if you don't intend to
710 actually hide your hidden services. In either case, you can
711 always create a container/VM with a separate Tor daemon instance.
714 users.groups.tor.gid = config.ids.gids.tor;
716 { description = "Tor Daemon User";
720 uid = config.ids.uids.tor;
723 systemd.services.tor =
724 { description = "Tor Daemon";
727 wantedBy = [ "multi-user.target" ];
728 after = [ "network.target" ];
729 restartTriggers = [ torRcFile ];
736 # Translated from the upstream contrib/dist/tor.service.in
737 ExecStartPre = "${cfg.package}/bin/tor -f ${torRcFile} --verify-config";
738 ExecStart = "${cfg.package}/bin/tor -f ${torRcFile}";
739 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
740 KillSignal = "SIGINT";
742 Restart = "on-failure";
746 # this seems to unshare /run despite what systemd.exec(5) says
748 StateDirectoryMode = "0700";
749 StateDirectory = ["tor" "tor/onion"];
750 RuntimeDirectory = ["tor"];
751 RuntimeDirectoryMode = "0750";
753 AmbientCapabilities = [""] ++ lib.optional (cfg.relay.port < 1024) "CAP_NET_BIND_SERVICE";
754 CapabilityBoundingSet = [""] ++ lib.optional (cfg.relay.port < 1024) "CAP_NET_BIND_SERVICE";
756 # ProtectClock= adds DeviceAllow=char-rtc r
758 LockPersonality = true;
759 MemoryDenyWriteExecute = true;
760 NoNewPrivileges = true;
761 PrivateDevices = true;
762 PrivateMounts = true;
763 PrivateNetwork = mkDefault false;
767 ProtectControlGroups = true;
768 # ProtectHome=true would not allow BindPaths= to work accross /home,
769 # and ProtectHome=tmpfs would break statfs(),
770 # preventing transmission-daemon to report the available free space.
771 # However, RootDirectory= is used, so this is not a security concern
772 # since there would be nothing in /home but any BindPaths= wanted by the user.
773 ProtectHome = "read-only";
774 ProtectHostname = true;
775 ProtectKernelLogs = true;
776 ProtectKernelModules = true;
777 ProtectKernelTunables = true;
778 ProtectSystem = "strict";
780 # AF_UNIX may become usable one day:
781 # https://github.com/transmission/transmission/issues/441
782 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
783 RestrictNamespaces = true;
784 RestrictRealtime = true;
785 RestrictSUIDSGID = true;
788 # Groups in @system-service which do not contain a syscall
789 # listed by perf stat -e 'syscalls:sys_enter_*' transmission-daemon -f
790 # in tests, and seem likely not necessary for transmission-daemon.
791 "~@aio" "~@chown" "~@keyring" "~@memlock" "~@resources" "~@setuid" "~@timer"
792 # In the @privileged group, but reached when querying infos through RPC (eg. with stig).
795 SystemCallArchitectures = "native";
796 SystemCallErrorNumber = "EPERM";
801 environment.systemPackages = [ cfg.package ];
803 services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
806 forward-socks4a / ${cfg.client.socksListenAddressFaster} .
808 enable-remote-toggle 0
809 enable-edit-actions 0
810 enable-remote-http-toggle 0