···
torDirectory = "/var/lib/tor";
opt = name: value: optionalString (value != null) "${name} ${value}";
10
-
optint = name: value: optionalString (value != 0) "${name} ${toString value}";
10
+
optint = name: value: optionalString (value != null && value != 0) "${name} ${toString value}";
···
GeoIPv6File ${pkgs.tor.geoip}/share/tor/geoip6
20
-
${optint "ControlPort" cfg.controlPort}
20
+
${optint "ControlPort" (toString cfg.controlPort)}
# Client connection config
+ optionalString cfg.client.enable ''
···
+ optionalString cfg.relay.enable ''
30
-
ORPort ${cfg.relay.portSpec}
30
+
ORPort ${toString cfg.relay.port}
31
+
${opt "Address" cfg.relay.address}
${opt "Nickname" cfg.relay.nickname}
${opt "ContactInfo" cfg.relay.contactInfo}
···
${opt "AccountingMax" cfg.relay.accountingMax}
${opt "AccountingStart" cfg.relay.accountingStart}
39
-
${if cfg.relay.isExit then
40
+
${if (cfg.relay.role == "exit") then
opt "ExitPolicy" cfg.relay.exitPolicy
44
-
${optionalString cfg.relay.isBridge ''
45
+
${optionalString (elem cfg.relay.role ["bridge" "private-bridge"]) ''
ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
49
+
${optionalString (cfg.relay.role == "private-bridge") ''
50
+
ExtraInfoStatistics 0
51
+
PublishServerDescriptor 0
56
+
+ concatStrings (flip mapAttrsToList cfg.hiddenServices (n: v: ''
57
+
HiddenServiceDir ${torDirectory}/onion/${v.name}
58
+
${flip concatMapStrings v.map (p: ''
59
+
HiddenServicePort ${toString p.port} ${p.destination}
52
-
hiddenServices = concatStrings (mapAttrsToList (hiddenServiceDir: hs:
54
-
hsports = concatStringsSep "\n" (map mkHiddenServicePort hs.hiddenServicePorts);
56
-
"HiddenServiceDir ${hiddenServiceDir}\n${hsports}\n${hs.extraConfig}\n"
57
-
) cfg.hiddenServices);
64
+
torRcFile = pkgs.writeText "torrc" torRc;
59
-
mkHiddenServicePort = hsport: let
60
-
trgt = optionalString (hsport.target != null) (" " + hsport.target);
61
-
in "HiddenServicePort ${toString hsport.virtualPort}${trgt}";
63
-
torRcFile = pkgs.writeText "torrc" torRc;
···
101
+
type = types.nullOr (types.either types.int types.str);
If set, Tor will accept connections on the specified port
···
example = "192.168.0.1:9101";
Bind to this address to listen for connections from
136
-
Socks-speaking applications. Same as socksListenAddress
137
-
but uses weaker circuit isolation to provide performance
138
-
suitable for a web browser.
138
+
Socks-speaking applications. Same as
139
+
<option>socksListenAddress</option> but uses weaker
140
+
circuit isolation to provide performance suitable for a
···
example = "accept 192.168.0.0/16, reject *";
Entry policies to allow/deny SOCKS requests based on IP
148
-
address. First entry that matches wins. If no SocksPolicy
151
+
address. First entry that matches wins. If no SocksPolicy
is set, we accept all (and only) requests from
150
-
SocksListenAddress.
153
+
<option>socksListenAddress</option>.
···
Whether to enable relaying TOR traffic for others.
179
-
See https://www.torproject.org/docs/tor-doc-relay for details.
182
+
See <link xlink:href="https://www.torproject.org/docs/tor-doc-relay" />
185
+
Setting this to true requires setting
186
+
<option>services.tor.relay.role</option>
188
+
<option>services.tor.relay.port</option>
183
-
isBridge = mkOption {
194
+
type = types.enum [ "exit" "relay" "bridge" "private-bridge" ];
187
-
Bridge relays (or "bridges") are Tor relays that aren't
188
-
listed in the main directory. Since there is no complete
189
-
public list of them, even if an ISP is filtering
190
-
connections to all the known Tor relays, they probably
191
-
won't be able to block all the bridges.
196
+
Your role in Tor network. There're several options:
200
+
<term><literal>exit</literal></term>
203
+
An exit relay. This allows Tor users to access regular
204
+
Internet services through your public IP.
208
+
Running an exit relay may expose you to abuse
210
+
<link xlink:href="https://www.torproject.org/faq.html.en#ExitPolicies" />
212
+
</para></important>
215
+
You can specify which services Tor users may access via
216
+
your exit relay using <option>exitPolicy</option> option.
222
+
<term><literal>relay</literal></term>
225
+
Regular relay. This allows Tor users to relay onion
226
+
traffic to other Tor nodes, but not to public
231
+
Note that some misconfigured and/or disrespectful
232
+
towards privacy sites will block you even if your
233
+
relay is not an exit relay. That is, just being listed
234
+
in a public relay directory can have unwanted
193
-
A bridge relay can't be an exit relay.
237
+
Which means you might not want to use
238
+
this role if you browse public Internet from the same
239
+
network as your relay, unless you want to write
240
+
e-mails to those sites (you should!).
241
+
</para></important>
195
-
You need to set relay.enable to true for this option to
245
+
<link xlink:href="https://www.torproject.org/docs/tor-doc-relay.html.en" />
198
-
The bridge is set up with an obfuscated transport proxy.
252
+
<term><literal>bridge</literal></term>
255
+
Regular bridge. Works like a regular relay, but
256
+
doesn't list you in the public relay directory and
257
+
hides your Tor node behind obfsproxy.
200
-
See https://www.torproject.org/bridges.html.en for more info.
261
+
Using this option will make Tor advertise your bridge
262
+
to users through various mechanisms like
263
+
<link xlink:href="https://bridges.torproject.org/" />, though.
204
-
isExit = mkOption {
208
-
An exit relay allows Tor users to access regular Internet
268
+
WARNING: THE FOLLOWING PARAGRAPH IS NOT LEGAL ADVISE.
269
+
Consult with your lawer when in doubt.
211
-
Unlike running a non-exit relay, running an exit relay may
212
-
expose you to abuse complaints. See
213
-
https://www.torproject.org/faq.html.en#ExitPolicies for
273
+
This role should be safe to use in most situations
274
+
(unless the act of forwarding traffic for others is
275
+
a punishable offence under your local laws, which
276
+
would be pretty insane as it would make ISP
216
-
You can specify which services Tor users may access via
217
-
your exit relay using exitPolicy option.
282
+
See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
289
+
<term><literal>private-bridge</literal></term>
292
+
Private bridge. Works like regular bridge, but does
293
+
not advertise your node in any way.
297
+
Using this role means that you won't contribute to Tor
298
+
network in any way unless you advertise your node
299
+
yourself in some way.
303
+
Use this if you want to run a private bridge, for
304
+
example because you'll give out your bridge address
305
+
manually to your friends.
309
+
Switching to this role after measurable time in
310
+
"bridge" role is pretty useless as some Tor users
311
+
would have learned about your node already. In the
312
+
latter case you can still change
313
+
<option>port</option> option.
317
+
See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
···
bandwidthRate = mkOption {
376
+
type = types.nullOr types.int;
Specify this to limit the bandwidth usage of relayed (server)
···
bandwidthBurst = mkOption {
386
+
type = types.nullOr types.int;
default = cfg.relay.bandwidthRate;
···
291
-
portSpec = mkOption {
396
+
address = mkOption {
397
+
type = types.nullOr types.str;
399
+
example = "noname.example.com";
401
+
The IP address or full DNS name for advertised address of your relay.
402
+
Leave unset and Tor will guess.
407
+
type = types.either types.int types.str;
What port to advertise for Tor connections. This corresponds to the
<literal>ORPort</literal> section in the Tor manual; see
···
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
316
-
_augmenting_ (prepending to) the default exit
317
-
policy. Leave commented to just use the default, which is
431
+
_augmenting_ (prepending to) the default exit policy.
432
+
Leave commented to just use the default, which is
available in the man page or at
319
-
https://www.torproject.org/documentation.html
434
+
<link xlink:href="https://www.torproject.org/documentation.html" />.
321
-
Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
322
-
for issues you might encounter if you use the default exit policy.
437
+
<link xlink:href="https://www.torproject.org/faq-abuse.html#TypicalAbuses" />
438
+
for issues you might encounter if you use the default
If certain IPs and ports are blocked externally, e.g. by
your firewall, you should update your exit policy to
···
hiddenServices = mkOption {
333
-
type = types.attrsOf (types.submodule ({
451
+
A set of static hidden services that terminate their Tor
452
+
circuits at this node.
454
+
Every element in this set declares a virtual onion host.
456
+
You can specify your onion address by putting corresponding
457
+
private key to an appropriate place in ${torDirectory}.
459
+
For services without private keys in ${torDirectory} Tor
460
+
daemon will generate random key pairs (which implies random
461
+
onion addresses) on restart. The latter could take a while,
465
+
Hidden services can be useful even if you don't intend to
466
+
actually <emphasis>hide</emphasis> them, since they can
467
+
also be seen as a kind of NAT traversal mechanism.
469
+
E.g. the example will make your sshd, whatever runs on
470
+
"8080" and your mail server available from anywhere where
471
+
the Tor network is available (which, with the help from
472
+
bridges, is pretty much everywhere), even if both client
473
+
and server machines are behind NAT you have no control
478
+
example = literalExample ''
479
+
{ "my-hidden-service-example".map = [
480
+
{ port = 22; } # map ssh port to this machine's ssh
481
+
{ port = 80; toPort = 8080; } # map http port to whatever runs on 8080
482
+
{ port = "sip"; toHost = "mail.example.com"; toPort = "imap"; } # because we can
486
+
type = types.loaOf (types.submodule ({name, config, ...}: {
335
-
hiddenServicePorts = mkOption {
336
-
type = types.listOf (types.submodule {
338
-
virtualPort = mkOption {
341
-
description = "Virtual port.";
343
-
target = mkOption {
344
-
type = types.nullOr types.str;
346
-
example = "127.0.0.1:8080";
348
-
Target virtual Port shall be mapped to.
492
+
Name of this tor hidden service.
494
+
This is purely descriptive.
496
+
After restarting Tor daemon you should be able to
497
+
find your .onion address in
498
+
<literal>${torDirectory}/onion/$name/hostname</literal>.
504
+
description = "Port mapping for this hidden service.";
505
+
type = types.listOf (types.submodule ({config, ...}: {
509
+
type = types.either types.int types.str;
512
+
Hidden service port to "bind to".
516
+
destination = mkOption {
519
+
description = "Forward these connections where?";
350
-
You may override the target port, address, or both by
351
-
specifying a target of addr, port, addr:port, or
352
-
unix:path. (You can specify an IPv6 target as
353
-
[addr]:port. Unix paths may be quoted, and may use
354
-
standard C escapes.)
359
-
example = [ { virtualPort = 80; target = "127.0.0.1:8080"; } { virtualPort = 6667; } ];
361
-
If target is <literal>null</literal> the virtual port is mapped
362
-
to the same port on 127.0.0.1 over TCP. You may use
363
-
<literal>target</literal> to overwrite this behaviour (see
364
-
description of target).
522
+
toHost = mkOption {
524
+
default = "127.0.0.1";
525
+
description = "Mapping destination host.";
366
-
This corresponds to the <literal>HiddenServicePort VIRTPORT
367
-
[TARGET]</literal> option by looking at the tor manual
368
-
<citerefentry><refentrytitle>tor</refentrytitle>
369
-
<manvolnum>1</manvolnum></citerefentry> for more information.
372
-
extraConfig = mkOption {
376
-
Extra configuration. Contents will be added in the current
377
-
hidden service context.
384
-
"/var/lib/tor/webserver" = {
385
-
hiddenServicePorts = [ { virtualPort = 80; } ];
528
+
toPort = mkOption {
529
+
type = types.either types.int types.str;
531
+
description = "Mapping destination port.";
537
+
toPort = mkDefault config.port;
538
+
destination = mkDefault "${config.toHost}:${toString config.toPort}";
389
-
Configure hidden services.
391
-
Please consult the tor manual
392
-
<citerefentry><refentrytitle>tor</refentrytitle>
393
-
<manvolnum>1</manvolnum></citerefentry> for a more detailed
394
-
explanation. (search for 'HIDDEN').
546
+
name = mkDefault name;
config = mkIf cfg.enable {
401
-
assertions = singleton
402
-
{ message = "Can't be both an exit and a bridge relay at the same time";
404
-
cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit);
554
+
# Not sure if `cfg.relay.role == "private-bridge"` helps as tor
555
+
# sends a lot of stats
556
+
warnings = optional (cfg.relay.enable && cfg.hiddenServices != {})
558
+
Running Tor hidden services on a public relay makes the
559
+
presence of hidden services visible through simple statistical
560
+
analysis of publicly available data.
562
+
You can safely ignore this warning if you don't intend to
563
+
actually hide your hidden services. In either case, you can
564
+
always create a container/VM with a separate Tor daemon instance.
users.extraGroups.tor.gid = config.ids.gids.tor;
···
restartTriggers = [ torRcFile ];
# Translated from the upstream contrib/dist/tor.service.in
586
+
install -o tor -g tor -d ${torDirectory}/onion
587
+
${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config
427
-
ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile} --RunAsDaemon 0";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";