Opened 5 years ago

Last modified 6 weeks ago

#10671 new enhancement

Pluggable Transports: Improve method of transferring parameters to client-side transports

Reported by: asn Owned by:
Priority: Medium Milestone:
Component: Obfuscation/Pluggable transport Version:
Severity: Normal Keywords: needs-spec-change, needs-tor-change
Cc: dcf, zwol, phw, yawning, kpdyer, infinity0, isis Actual Points:
Parent ID: #10629 Points:
Reviewer: Sponsor:

Description

Currently, client-side pluggable transports (like scramblesuit) that need parameters (like shared-secrets, etc.) are supposed to get them through the SOCKS protocol. Specifically, Tor is supposed to shove the shared-secret in the username/password fields of the SOCKS handshake.

Apart from the solution being ugly and super hacky it also imposes a size limit to our parameters, since SOCKS5 has a maximum length of 512 bytes of username/password (#9163). SOCKS5 is needed since it's the only SOCKS version that officially supports IPv6.

As a more permanent solution than #9163 we should think of how to improve this situation. At least three ways come in mind:

a) We use the reserved METHOD field of the SOCKS protocol to define our own authentication method (see section 3 of http://csocks.altervista.org/rfc/rfc1928.txt). Then we use this new authentication method to pass parameters to pluggable transports.

This seems cleaner than before, but we still piggyback on the authentication mechanism (which means that if we ever wanted to password protect obfsproxy's SOCKS listener we can't) so it's not perfect. Also many libraries might not support reserved authentication methods, which means that some monkey patching will be needed.

b) We design and specify our own SOCKS protocol. SOCKS kinda sucks for PTs anyway (#7153). I don't like this idea, because I don't like homebrewed protocols and it will require significant specification/development efforts to replace all the current uses of SOCKS in PTs.

c) We write yet another metadata protocol that happens after SOCKS but before application-layer data is transferred to obfsproxy. It's the equivalent of Extended ORPort for the client-side, and it might be useful for other information apart from client-side parameters. I don't like this solution either.

d) We define an environment varialbe similar to TOR_PT_SERVER_TRANSPORT_OPTIONS but for the client-side. Unfortunately, the client-side parameters are dynamic (parameters are different for different destination addresses) so the environment variable will also need to include the destination bridge address along with the parameter. Furthermore, if we ever wanted to make parameters completely dynamic (so that they change after Tor startup) this solution might complicate matters. Still this is not terribly bad (since we already parse env vars and we already do something similar on the server side), but it's not good either.

Child Tickets

Change History (12)

comment:1 Changed 5 years ago by asn

Cc: infinity0 added
Type: defectenhancement

comment:2 Changed 5 years ago by infinity0

Parent ID: #10629

comment:3 Changed 5 years ago by dcf

e) We make socks4a one of the possible CMETHOD SOCKS types (along with the existing socks4 and socks5), and pass IPv6 addresses as if they were host names. Benefits: works with IPv6 (like socks5) and has unlimited credentials length (like socks4). Another benefit: would allow Tor to pass host names to pluggable transports (currently it always pre-resolves names that you put in a Bridge line).

Downside: it's not safe for PTs to advertise socks4a unless they know that the tor they are talking to supports it. So we'd either have to bump

TOR_PT_MANAGED_TRANSPORT_VER=2

or (better) make a new variable

TOR_PT_CMETHOD_PROXY_TYPES=socks4,socks5,socks4a

whose default value would be socks4,socks5. The nice thing about this is that PTs only need to implement SOCKS4a. If they get socks4a in TOR_PT_CMETHOD_PROXY_TYPES (new tor), then they send socks4a in their CMETHOD lines. Otherwise (old tor), they send socks4, for which their SOCKS4a code also suffices.

This idea is actually how I assumed tor worked when I added SOCKS to goptlib. (I thought that socks4 was really SOCKS4a, but I was wrong.)
http://godoc.org/git.torproject.org/pluggable-transports/goptlib.git#SocksConn.Grant
https://gitweb.torproject.org/pluggable-transports/goptlib.git/blob/5a089f3f33bab6b066baad3911dc6e0d8231ce1c:/socks.go#l159

comment:4 in reply to:  3 Changed 5 years ago by yawning

Replying to dcf:

e) We make socks4a one of the possible CMETHOD SOCKS types (along with the existing socks4 and socks5), and pass IPv6 addresses as if they were host names. Benefits: works with IPv6 (like socks5) and has unlimited credentials length (like socks4). Another benefit: would allow Tor to pass host names to pluggable transports (currently it always pre-resolves names that you put in a Bridge line).

As long as Tor ignores the DSTIP field in the PT->Tor socks response, then this would work. I don't see Tor needing the remote IP for anything, but I haven't given it massive amounts of thought (Maybe if we allow name resolution it could do something with it?).

Personally I'm in favor of "a" since it will:

  • Support binary data
  • Be backwards compatible (The only failure case is PTs that require extended config with an old Tor, but ALL currently deployed Tor binaries can't use such PTs regardless of auth method anyway)
  • Still allow password protecting the SOCKS endpoint (though only for clients that support the extension auth method, so new PT + old Tor = no passwords for you)

Something like:

METHOD - 0x80 (Reserved range is 0x80-0xFE)

Fields common to RFC 1929 have the same values/definitions.
+-----+------+----------+------+----------+--------+------------+
| VER | ULEN |  UNAME   | PLEN |  PASSWD  | EXTLEN |   EXTDATA  | 
+-----+------+----------+------+----------+--------+------------+
|  1  |  1   | 1 to 255 |  1   | 1 to 255 |   2    | 0 to 65535 |
+-----+------+----------+------+----------+--------+------------+

VER: 0x01 (Also in RFC 1929, but this is our auth method version)

EXTLEN: Length of EXTDATA in network byte order (64k is enough for anybody?)

EXTDATA: PT specific per-endpoint configuration data

Possible changes:

  • Change EXTLEN/EXTDATA to Key/Value pairs (NR_EXTDATA, KLEN, KEY, VLEN, VAL, ...)
  • If it is conceivable that PTs will use more that 64k of per bridge config information, then EXTLEN could be 4 bytes. I would hate to see the bridgeline for such a transport though.

comment:5 Changed 5 years ago by asn

I like your approach Yawning. We will also need to define what happens if Tor wants to do the 0x80 SOCKS PT method but it's not sure whether the PT supports it. We will probably need to define a TOR_PT_CMETHOD_PROXY_TYPES environment variable like David suggested (and the PT will have to advertise socks5pt support or something). I guess this is not too bad but not too good either.

I'm also thinking on whether EXTDATA needs to be (NR_EXTDATA, KLEN, KEY, VLEN, VAL, ...). To be honest, I think it's fine as it is (opaque towards the extra data).

David I also like your idea about SOCKSv4a. I think I slightly prefer the SOCKS5PT avenue because it seems a bit less hacky (we don't use SOCKSv4a in unspecified ways) and we also don't clog the SOCKS username/password method (which might be useful in the future). I think the implementation effort is pretty much the same for both approaches. It's also worth noting that SOCKS5 supports domain names on the CONNECT method.

comment:6 in reply to:  5 Changed 5 years ago by yawning

Replying to asn:

I like your approach Yawning. We will also need to define what happens if Tor wants to do the 0x80 SOCKS PT method but it's not sure whether the PT supports it. We will probably need to define a TOR_PT_CMETHOD_PROXY_TYPES environment variable like David suggested (and the PT will have to advertise socks5pt support or something). I guess this is not too bad but not too good either.

We do? The SOCKS5 protocol negotiates, so this all is transparent.

With a Tor that supports our extension:
Tor->PT: 0x05 0x03 0x00 0x02 0x80 (SOCKSv5, 3 auth methods, None, Username/Password, Tor Extended)

Ext capable PT->Tor: 0x05 0x80 (SOCKSv5, we will use 0x80)
Old or argument less PT->Tor: 0x05 0x02 (SOCKSv5, we will use Username/Password)

Tor can them make the decision as to if the PT can be used. IMO doing it on a per bridge basis when the relevant bridge is actually used is preferable, but it can be done via the pt config protocol by having the PT declare itself as "socks5pt". I don't see a reason for another env var in any case, Tor binaries that support the extension can and should just request the method as needed.

Something like (somewhere deep in the guts of Tor):

  • If authentication is required, request auth 0x80 (We've coded ourselves into a corner wrt using Username/Password for actual auth since it would break backward compatibility).
  • If the bridge line has 0 arguments, request auth 0x00 (None required)
  • If the bridge line has arguments that fit into the old style config space, request auth 0x02 and 0x80 (Either works, this should allow old PTs to continue to work unless their SOCKS5 implementation is garbage).
  • If the bridge line has arguments that requires the extended space, request auth 0x80.

After some thought our auth method should probably allow ULEN/PLEN fields to be 0 (with UNAME/PASSWD omitted, instead of requiring at least 1 byte). I just blindly cribbed those fields from the RFC, but requiring them is somewhat nonsensical for our common use case.

comment:7 Changed 5 years ago by isis

Cc: isis added

comment:9 Changed 5 years ago by asn

Keywords: needs-spec-change needs-tor-change added

comment:10 Changed 16 months ago by teor

Severity: Normal

Set all open tickets without a severity to "Normal"

comment:11 Changed 7 weeks ago by teor

Owner: asn deleted
Status: newassigned

asn does not need to own any obfuscation tickets any more. Default owners are trouble.

comment:12 Changed 6 weeks ago by cohosh

Status: assignednew

tickets were assigned to asn, setting them as unassigned (new) again.

Note: See TracTickets for help on using tickets.