services: tor: Add support for pluggable transports.

Pluggable transports are programs that disguise Tor traffic, which
can be useful in case Tor is censored.  Pluggable transports
cannot be configured by #:config-file file exclusively because Tor
process is run via 'least-authority-wrapper' and cannot have access
to transport plugin, which is a separate executable (Bug#70302,
Bug#70332).

* doc/guix.texi (Networking Services): Document 'tor-transport-plugin'
data type and 'transport-plugins' option for 'tor-configuration.
* gnu/services/networking.scm: Export
'tor-configuration-transport-plugins', 'tor-transport-plugin',
'tor-transport-plugin?', 'tor-plugin-role',
'tor-plugin-protocol', and 'tor-plugin-program'.
(<tor-configuration>): Add 'transport-plugins' field.
(<tor-transport-plugin>): New variable.
(tor-configuration->torrc): Add content to 'torrc' computed-file.
(tor-shepherd-service): Add file-system-mapping(s).

Change-Id: I1b0319358778c7aee650bc843e021a6803a1cf3a
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Nigko Yerden 2024-10-06 22:39:08 +05:00 committed by Ludovic Courtès
parent 886b410e6f
commit eb1515849e
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
2 changed files with 124 additions and 13 deletions

View file

@ -22057,6 +22057,12 @@ If @code{#t}, Tor will listen for control commands on the UNIX domain socket
@file{/var/run/tor/control-sock}, which will be made writable by members of the
@code{tor} group.
@item @code{transport-plugins} (default: @code{'()})
The list of @code{<tor-transport-plugin>} records to use.
For any transport plugin you include in this list, appropriate
configuration line to enable transport plugin will be automatically
added to the default configuration file.
@end table
@end deftp
@ -22085,6 +22091,68 @@ maps ports 22 and 80 of the Onion Service to the local ports 22 and 8080.
@end table
@end deftp
@cindex pluggable transports, tor
@deftp {Data Type} tor-transport-plugin
Data type representing a Tor pluggable transport plugin in
@code{tor-configuration}. Plugguble transports are programs
that disguise Tor traffic, which can be useful in case Tor is
censored. See the the Tor project's
@url{https://tb-manual.torproject.org/circumvention/,
documentation} and
@url{https://spec.torproject.org/pt-spec/index.html,
specification} for more information.
Each transport plugin corresponds either to
@code{ClientTransportPlugin ...} or to
@code{ServerTransportPlugin ...} line in the default
configuration file, see @command{man tor}.
Available @code{tor-transport-plugin} fields are:
@table @asis
@item @code{role} (default: @code{'client})
This must be either @code{'client} or @code{'server}. Otherwise,
an error is raised. Set the @code{'server} value if you want to
run a bridge to help censored users connect to the Tor network, see
@url{https://community.torproject.org/relay/setup/bridge/,
the Tor project's brige guide}. Set the @code{'client} value
if you want to connect to somebody else's bridge, see
@url{https://bridges.torproject.org/, the Tor project's
``Get Bridges'' page}. In both cases the required
additional configuration should be provided via
@code{#:config-file} option of @code{tor-configuration}.
@item @code{protocol} (default: @code{"obfs4"})
A string that specifies a pluggable transport protocol.
@item @code{program}
This must be a ``file-like'' object or a string
pointing to the pluggable transport plugin executable.
This option allows the Tor daemon run inside the container
to access the executable and all the references
(e.g. package dependencies) attached to it.
@end table
Suppose you would like Tor daemon to use obfs4 type obfuscation and
to connect to Tor network via obfs4 bridge (a nonpublic Tor relay with
support for obfs4 type obfuscation). Then you may go to
@url{https://bridges.torproject.org/, https://bridges.torproject.org/}
and get there a couple of bridge lines (each starts with @code{obfs4 ...})
and use these lines in tor-service-type configuration as follows:
@lisp
(service tor-service-type
(tor-configuration
(config-file (plain-file "torrc"
"\
UseBridges 1
Bridge obfs4 ...
Bridge obfs4 ..."))
(transport-plugins
(list (tor-transport-plugin
(program
(file-append
go-gitlab-torproject-org-tpo-anti-censorship-pluggable-transports-lyrebird
"/bin/lyrebird")))))))
@end lisp
@end deftp
The @code{(gnu services rsync)} module provides the following services:
You might want an rsync daemon if you have files that you want available

View file

@ -161,10 +161,16 @@
tor-configuration-hidden-services
tor-configuration-socks-socket-type
tor-configuration-control-socket-path
tor-configuration-transport-plugins
tor-onion-service-configuration
tor-onion-service-configuration?
tor-onion-service-configuration-name
tor-onion-service-configuration-mapping
tor-transport-plugin
tor-transport-plugin?
tor-plugin-role
tor-plugin-protocol
tor-plugin-program
tor-hidden-service ; deprecated
tor-service-type
@ -975,7 +981,9 @@ applications in communication. It is used by Jami, for example.")))
(socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
(default 'tcp))
(control-socket? tor-configuration-control-socket-path
(default #f)))
(default #f))
(transport-plugins tor-configuration-transport-plugins
(default '())))
(define %tor-accounts
;; User account and groups for Tor.
@ -1005,10 +1013,24 @@ Onion Service.")
@end lisp
maps ports 22 and 80 of the Onion Service to the local ports 22 and 8080."))
(define-record-type* <tor-transport-plugin>
tor-transport-plugin make-tor-transport-plugin
tor-transport-plugin?
(role tor-plugin-role
(default 'client)
(sanitize (lambda (value)
(if (memq value '(client server))
value
(configuration-field-error #f 'role value)))))
(protocol tor-plugin-protocol
(default "obfs4"))
(program tor-plugin-program))
(define (tor-configuration->torrc config)
"Return a 'torrc' file for CONFIG."
(match-record config <tor-configuration>
(tor config-file hidden-services socks-socket-type control-socket?)
(tor config-file hidden-services socks-socket-type control-socket?
transport-plugins)
(computed-file
"torrc"
(with-imported-modules '((guix build utils))
@ -1047,6 +1069,20 @@ HiddenServicePort ~a ~a~%"
(cons name mapping)))
hidden-services))
(for-each (match-lambda
((role-string protocol program)
(format port "\
~aTransportPlugin ~a exec ~a~%"
role-string protocol program)))
'#$(map (match-lambda
(($ <tor-transport-plugin> role protocol program)
(list (if (eq? role 'client)
"Client"
"Server")
protocol
program)))
transport-plugins))
(display "\
### End of automatically generated lines.\n\n" port)
@ -1059,20 +1095,27 @@ HiddenServicePort ~a ~a~%"
(define (tor-shepherd-service config)
"Return a <shepherd-service> running Tor."
(let* ((torrc (tor-configuration->torrc config))
(transport-plugins (tor-configuration-transport-plugins config))
(tor (least-authority-wrapper
(file-append (tor-configuration-tor config) "/bin/tor")
#:name "tor"
#:mappings (list (file-system-mapping
(source "/var/lib/tor")
(target source)
(writable? #t))
(file-system-mapping
(source "/var/run/tor")
(target source)
(writable? #t))
(file-system-mapping
(source torrc)
(target source)))
#:mappings (append
(list (file-system-mapping
(source "/var/lib/tor")
(target source)
(writable? #t))
(file-system-mapping
(source "/var/run/tor")
(target source)
(writable? #t))
(file-system-mapping
(source torrc)
(target source)))
(map (lambda (plugin)
(file-system-mapping
(source (tor-plugin-program plugin))
(target source)))
transport-plugins))
#:namespaces (delq 'net %namespaces))))
(list (shepherd-service
(provision '(tor))