Subject: [bug#70341] [PATCH v3] services: tor: Add support for pluggable transports.

From: Nigko Yerden <[email-masked]>
Date: Thu, 25 Apr 2024 11:08:52 +0500

Hi André,

Thank you for the feedback!

> I can confirm that the tor service is unable to fork-exec a 
> pluggable-transport and the bootstrap process is halted at its start 
> when trying to use a system wide bridge + PT. However, this patch 
> does not seem to address the issue at hand, since it just creates new
> tor-service-type configuration options that accomplish the same as
> configuring on config-file directly. Have you had success with this?
> I had no luck.
Yes, I have! This patch not only creates new tor-service-type
configuration options but, which is crucial, adds pluggable transport
(PT) executable, if provided, to #:mappings argument of the
least-authority-wrapper, see 'tor-shepherd-service' chunk. With this
patch Tor process gets access to PT plugin and, if bridges are
configured via config-file field, Tor starts using obfuscated traffic.

> Even if it had succeeded though, I'm not sure if this is the best 
> approach to it, since it would break guix system configuration,
> right?
No, the patch does not break any existing tor-service-type
configuration. If PT is not used, 'transport-plugin' defaults to '#f',
and the Tor works exactly as if there wasn't any patch at all.

> How would one know beforehand which binary to point to? One would
> first need to install the PT and look to its path on store and then
> link to it in a new configuration. And then this link would have to
> be manualy updated. Am I missing something here?
There is much simpler and convenient way of doing this. If users want to 
bring PT into action, they may simply write

(service tor-service-type
	(config-file ".... Bridge obfs4 ...")
	(transport-plugin (file-append PT-PACKAGE "/bin/name-of-executable"))

The PT-PACKAGE does not even have to be present in the list of
'operating-system 'packages field, since Guix will find the reference to
PT-package and install it automatically. The only thing which should be
known beforehand is the "name-of-executable".
For
'go-gitlab-torproject-org-tpo-anti-censorship-pluggable-transports-lyrebird 
package it is "lyrebird", while for 
'go-github-com-operatorfoundation-obfs4 it is "obfs4proxy". It is
unlikely that these names will change with upgrades.

> Finally, next time, try to keep the issue to a single thread. I'm 
> replying to #70332 and #70302 just for reference, but let's keep to 
> #70341 going forward.
Sorry about that! I have tried not to create new bug issue but was
unsuccessful. Perhaps I shouldn't have touched the email heading.

Regards,
Nigko

André Batista wrote:
> Hi Nigko,
> 
> seg 22 abr 2024 às 08:58:39 (1713787119), [email-masked]
> enviou:
>> 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).
> 
> I can confirm that the tor service is unable to fork-exec a 
> pluggable-transport and the bootstrap process is halted at its start 
> when trying to use a system wide bridge + PT. However, this patch 
> does not seem to address the issue at hand, since it just creates new
> tor-service-type configuration options that accomplish the same as
> configuring on config-file directly. Have you had success with this?
> I had no luck.
> 
> More comments bellow.
> 
>> * doc/guix.texi (Networking Services): Document 'transport-plugin'
>> and 'pluggable-transport' options for 'tor-configuration'. *
>> gnu/services/networking.scm: Export
>> 'tor-configuration-transport-plugin-path', 
>> 'tor-configuration-pluggable-transport'. (<tor-configuration>): Add
>> 'transport-plugin' and 'pluggable-transport' fields. 
>> (tor-configuration->torrc)[transport-plugin]: Add content to
>> 'torrc' computed-file. (tor-shepherd-service)[transport-plugin]:
>> Add file-system-mapping.
>> 
>> Change-Id: I64e7632729287ea0ab27818bb7322fddae43de48 --- 
>> doc/guix.texi               | 11 ++++++++ 
>> gnu/services/networking.scm | 54
>> ++++++++++++++++++++++++++----------- 2 files changed, 49
>> insertions(+), 16 deletions(-)
>> 
>> diff --git a/doc/guix.texi b/doc/guix.texi index
>> 65af136e61..eb0837860e 100644 --- a/doc/guix.texi +++
>> b/doc/guix.texi @@ -127,6 +127,7 @@ Copyright @copyright{} 2024
>> Herman Rimm@* Copyright @copyright{} 2024 Matthew Trzcinski@* 
>> Copyright @copyright{} 2024 Richard Sent@* +Copyright @copyright{}
>> 2024 Nigko Yerden@*
>> 
>> Permission is granted to copy, distribute and/or modify this
>> document under the terms of the GNU Free Documentation License,
>> Version 1.3 or @@ -21849,6 +21850,16 @@ Networking Services 
>> @file{/var/run/tor/control-sock}, which will be made writable by
>> members of the @code{tor} group.
>> 
>> +@item @code{transport-plugin} (default: @code{#f}) +This must be
>> either @code{#f} or a ``file-like'' object pointing to the 
>> +pluggable transport plugin executable.  In the latter case the 
>> +@code{#:config-file} file should contain line(s) configuring +one
>> or more bridges. + +@item @code{pluggable-transport} (default:
>> @code{"obfs4"}) +A string that specifies the type of the pluggable
>> transport in +case @code{#:transport-plugin} is not @code{#f}. + 
>> @end table @end deftp
>> 
>> diff --git a/gnu/services/networking.scm
>> b/gnu/services/networking.scm index 8e64e529ab..6e535ea8ef 100644 
>> --- a/gnu/services/networking.scm +++
>> b/gnu/services/networking.scm @@ -22,6 +22,7 @@ ;;; Copyright ©
>> 2023 Declan Tsien <[email-masked]> ;;; Copyright © 2023
>> Bruno Victal <[email-masked]> ;;; Copyright © 2023 muradm
>> <[email-masked]> +;;; Copyright © 2024 Nigko Yerden
>> <[email-masked]> ;;; ;;; This file is part of GNU Guix. 
>> ;;; @@ -159,6 +160,8 @@ (define-module (gnu services networking) 
>> tor-configuration-hidden-services 
>> tor-configuration-socks-socket-type 
>> tor-configuration-control-socket-path +
>> tor-configuration-transport-plugin-path +
>> tor-configuration-pluggable-transport 
>> tor-onion-service-configuration tor-onion-service-configuration? 
>> tor-onion-service-configuration-name @@ -955,7 +958,11 @@
>> (define-record-type* <tor-configuration> (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-plugin tor-configuration-transport-plugin-path +
>> (default #f)) +  (pluggable-transport
>> tor-configuration-pluggable-transport +                    (default
>> "obfs4")))
>> 
>> (define %tor-accounts ;; User account and groups for Tor. @@ -988,7
>> +995,8 @@ (define-configuration/no-serialization
>> tor-onion-service-configuration (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-plugin pluggable-transport) (computed-file "torrc" 
>> (with-imported-modules '((guix build utils)) @@ -1027,6 +1035,13 @@
>> (define (tor-configuration->torrc config) (cons name mapping))) 
>> hidden-services))
>> 
>> +               (when #$transport-plugin +                 (format
>> port "\ +UseBridges 1 +ClientTransportPlugin ~a exec ~a~%" +
>> #$pluggable-transport +
>> #$transport-plugin)) + (display "\ ### End of automatically
>> generated lines.\n\n" port)
> 
> Even if it had succeded though, I'm not sure if this is the best 
> approach to it, since it would break guix system configuration,
> right? How would one know beforehand which binary to point to? One
> would first need to install the PT and look to its path on store and
> then link to it in a new configuration. And then this link would have
> to be manualy updated. Am I missing something here?
> 
> Finally, next time, try to keep the issue to a single thread. I'm 
> replying to #70332 and #70302 just for reference, but let's keep to 
> #70341 going forward.
> 
> Cheers!