Tor 可插拔传输规范

为了翻译速度,个别翻译可能与原词汇含义相佐,请对照原文进行理解。如果需要实现相关协议,请查看原文,本翻译仅适用于简单了解协议。

原文链接:

当前的翻译版本提交 Hash: e43a3f7ad001b3bebe34b379ecc4622a27ec887b ,对应 Github链接

摘要

查看原文

Pluggable Transport Specification (Version 1)

Abstract

Pluggable Transports (PTs) are a generic mechanism for the rapid development and deployment of censorship circumvention, based around the idea of modular sub-processes that transform traffic to defeat censors.

This document specifies the sub-process startup, shutdown, and inter-process communication mechanisms required to utilize PTs.

Table of Contents

1. Introduction
  1.1. Requirements Notation
2. Architecture Overview
3. Specification
  3.1. Pluggable Transport Naming
  3.2. Pluggable Transport Configuration Environment Variables
     3.2.1. Common Environment Variables
     3.2.2. Pluggable Transport Client Environment Variables
     3.2.3. Pluggable Transport Server Environment Variables
  3.3. Pluggable Transport To Parent Process Communication
     3.3.1. Common Messages
     3.3.2. Pluggable Transport Client Messages
     3.3.3. Pluggable Transport Server Messages
  3.4. Pluggable Transport Shutdown
  3.5. Pluggable Transport Client Per-Connection Arguments
4. Anonymity Considerations
5. References
6. Acknowledgments
Appendix A. Example Client Pluggable Transport Session
Appendix B. Example Server Pluggable Transport Session

可插拔传输(Pluggable Transports, PT)是一种快速开发和部署的用于绕过审查的机制,基于模块化子系统的思想通过转换流量来击败审查。

该文档阐述了 PT 子进程启动、关闭、进程间通信的规范。

1. 介绍

查看原文

1. Introduction

This specification describes a way to decouple protocol-level obfuscation from an application's client/server code, in a manne that promotes rapid development of obfuscation/circumvention tools and promotes reuse beyond the scope of the Tor Project's efforts in that area.

This is accomplished by utilizing helper sub-processes that implement the necessary forward/reverse proxy servers that handle the censorship circumvention, with a well defined and standardized configuration and management interface.

Any application code that implements the interfaces as specified in this document will be able to use all spec compliant Pluggable Transports.

该规范描述一种解耦后的客户端与服务端通信协议层混淆机制,可促进混淆工具的快速开发,并且促进 Tor 项目在其他领域的重用。

其通过辅助子流程完成,实现了必要的前向和反向代理服务器用于处理和规避审查,拥有良好的定义和标准化配置界面

实现本文档中指定的接口的任何程序都是符合规范的可插拔传输

1.1 符号规范

查看原文

1.1. Requirements Notation

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

本文中所有的“必须”、“不能”、“必要”、“应当”、“不应”、“建议”、“可能”、“可选”等词,参照 RFC2119 规范

2. 整体架构

查看原文
    +------------+                    +---------------------------+
    | Client App +-- Local Loopback --+ PT Client (SOCKS Proxy)   +--+
    +------------+                    +---------------------------+  |
                                                                     |
                Public Internet (Obfuscated/Transformed traffic) ==> |
                                                                     |
    +------------+                    +---------------------------+  |
    | Server App +-- Local Loopback --+ PT Server (Reverse Proxy) +--+
    +------------+                    +---------------------------+

On the client's host, the PT Client software exposes a SOCKS proxy [RFC1928] to the client application, and obfuscates or otherwise transforms traffic before forwarding it to the server's host.

On the server's host, the PT Server software exposes a reverse proxy that accepts connections from PT Clients, and handles reversing the obfuscation/transformation applied to traffic, before forwarding it to the actual server software. An optional lightweight protocol exists to facilitate communicating connection meta-data that would otherwise be lost such as the source IP address and port [EXTORPORT].

All PT instances are configured by the respective parent process via a set of standardized environment variables (3.2) that are set at launch time, and report status information back to the parent via writing output in a standardized format to stdout (3.3).

Each invocation of a PT MUST be either a client OR a server.

All PT client forward proxies MUST support either SOCKS 4 or SOCKS 5, and SHOULD prefer SOCKS 5 over SOCKS 4.

%3 client 客户端 程序 clientPT 客户端 PT(Socks5) client--clientPT 本地网络 server 服务端 程序 serverPT 服务端 PT(反向代理) server--serverPT 本地网络 clientPT--serverPT 公共网络

在客户端主机上,PT 客户端将启动一个 SOCKS 代理(符合 RFC1928 要求),并在流量发送至服务端主机前,对流量本身进行混淆。

在服务端主机上,PT 服务端将启动一个反向混淆的程序用于接收 PT 客户端发送的混淆流量,并在流量发送至服务端程序前将被混淆的流量还原。可能需要一个轻量级的协议来确保通信完成,否则诸如源 IP、端口等信息会丢失。

任何一个 PT 实例都应该由其父进程通过标准化的环境变量进行配置,环境变量将在启动时设置,并通过标准输出流(stdout)向父进程报告状态信息。

3 规范

查看原文

3. Specification

Pluggable Transport proxies follow the following workflow throughout their lifespan.
(1) Parent process sets the required environment values (3.2) and launches the PT proxy as a sub-process (fork()/exec()).
(2) The PT Proxy determines the versions of the PT specification supported by the parent"TOR_PT_MANAGED_TRANSPORT_VER" (3.2.1)
(2.1) If there are no compatible versions, the PT proxy writes a "VERSION-ERROR" message (3.3.1) to stdout and terminates.
(2.2) If there is a compatible version, the PT proxy writes a "VERSION" message (3.3.1) to stdout.
(3) The PT Proxy parses the rest of the environment values.
(3.1) If the environment values are malformed, or otherwise invalid, the PT proxy writes a "ENV-ERROR" message (3.3.1) to stdout and terminates.
(3.2) Determining if it is a client side forward proxy or a server side reverse proxy can be done via examining the "TOR_PT_CLIENT_TRANSPORTS" and "TOR_PT_SERVER_TRANSPORTS" environment variables.
(4) (Client only) If there is an upstream proxy specified via "TOR_PT_PROXY" (3.2.2), the PT proxy validates the URI provided.
(4.1) If the upstream proxy is unusable, the PT proxy writes a "PROXY-ERROR" message (3.3.2) to stdout and terminates.
(4.2) If there is a supported and well-formed upstream proxy the PT proxy writes a "PROXY DONE" message (3.3.2) to stdout.
(5) The PT Proxy initializes the transports and reports the status via stdout (3.3.2, 3.3.3)
(6) The PT Proxy forwards and transforms traffic as appropriate.
(7) Upon being signaled to terminate by the parent process (3.4), the PT Proxy gracefully shuts down.

可插拔传输在整个声明周期内都应该遵循如下工作流:

  1. 父进程设置所需要的环境变量(3.2 节),并以子进程形式启动 PT(fork()/exec())
  2. PT 代理确定父进程所支持的 PT 规范版本TOR_PT_MANAGED_TRANSPORT_VER(3.2.1 节))
    1. 如果没有兼容的版本,向 stdout 发送VERSION-ERROR消息并终止(3.3.1 节)
    2. 如果有兼容的版本,向 stdout 发送VERSION消息
  3. PT 解析其余的环境值,
    1. 如果环境值不正确无效,向 stdout 发送ENV-ERROR消息并终止
    2. 通过检查TOR_PT_CLIENT_TRANSPORTSTOR_PT_SERVER_TRANSPORTS确定是客户端转发代理还是服务端反向代理
  4. 对于客户端 PT,如果有通过TOR_PT_PROXY指定的上游代理,则 PT 要检查对应的 URI
    1. 如果上游代理不可用,向 stdout 发送PROXY-ERROR消息并终止
    2. 如果上游支持,向 stdout 发送PROXY DONE消息并终止
  5. PT 代理初始化,并使用 stdout 报告状态
  6. PT 代理按要求转发流量
  7. 当父进程发出关闭信号时,PT 代理也随之关闭

3.1 可插拔传输命名

查看原文

3.1. Pluggable Transport Naming

Pluggable Transport names serve as unique identifiers, and every PT MUST have a unique name.

PT names MUST be valid C identifiers. PT names MUST begin with a letter or underscore, and the remaining characters MUST be ASCII letters, numbers or underscores. No length limit is imposted.

PT names MUST satisfy the regular expression "[a-zA-Z_][a-zA-Z0-9_]*".

可插拔传输名称是其唯一标识符,并且必须是唯一的

PT 名称必须是有效的 C 语言标识符,以字符、下划线开始,并且其余字符必须是 ASCII 字符、数字、下划线。没有长度限制

名称需要满足正则表达式[a-zA-Z_][a-zA-Z0-9_]*

3.2 可插拔传输环境变量配置

查看原文

3.2. Pluggable Transport Configuration Environment Variables

All Pluggable Transport proxy instances are configured by their parent process at launch time via a set of well defined environment variables.

The "TOR_PT_" prefix is used for namespacing reasons and does not indicate any relations to Tor, except for the origins of this specification.

所有的可插拔传输程序在启动时通过环境变量进行配置

环境变量前缀为TOR_PT_,但其与 Tor 没有别的关系

3.2.1 常见环境变量

查看原文

3.2.1. Common Environment Variables

When launching either a client or server Pluggable Transport proxy, the following common environment variables MUST be set.

"TOR_PT_MANAGED_TRANSPORT_VER"

Specifies the versions of the Pluggable Transport specification the parent process supports, delimited by commas. All PTs MUST accept any well-formed list, as long as a compatible version is present.
Valid versions MUST consist entirely of non-whitespace, non-comma printable ASCII characters.
The version of the Pluggable Transport specification as of this document is "1".

Example: TOR_PT_MANAGED_TRANSPORT_VER=1,1a,2b,this_is_a_valid_ver

"TOR_PT_STATE_LOCATION"

Specifies an absolute path to a directory where the PT is allowed to store state that will be persisted across invocations. The directory is not required to exist when the PT is launched, however PT implementations SHOULD be able to create it as required.
PTs MUST only store files in the path provided, and MUST NOT create or modify files elsewhere on the system.

Example:TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state/

"TOR_PT_EXIT_ON_STDIN_CLOSE"

Specifies that the parent process will close the PT proxy's standard input (stdin) stream to indicate that the PT proxy should gracefully exit.
PTs MUST NOT treat a closed stdin as a signal to terminate unless this environment variable is set to "1".
PTs SHOULD treat stdin being closed as a signal to gracefully terminate if this environment variable is set to "1".

Example:TOR_PT_EXIT_ON_STDIN_CLOSE=1

"TOR_PT_OUTBOUND_BIND_ADDRESS_V4"

Specifies an IPv4 IP address that the PT proxy SHOULD use as source address for outgoing IPv4 IP packets. This feature allows people with multiple network interfaces to specify explicitly which interface they prefer the PT proxy to use.
If this value is unset or empty, the PT proxy MUST use the default source address for outgoing connections.
This setting MUST be ignored for connections to loopback addresses (127.0.0.0/8).

Example:TOR_PT_OUTBOUND_BIND_ADDRESS_V4=203.0.113.4

"TOR_PT_OUTBOUND_BIND_ADDRESS_V6"

Specifies an IPv6 IP address that the PT proxy SHOULD use as source address for outgoing IPv6 IP packets. This feature allows people with multiple network interfaces to specify explicitly which interface they prefer the PT proxy to use.
If this value is unset or empty, the PT proxy MUST use the default source address for outgoing connections.
This setting MUST be ignored for connections to the loopback address ([::1]).
IPv6 addresses MUST always be wrapped in square brackets.

Example:TOR_PT_OUTBOUND_BIND_ADDRESS_V6=[2001:db8::4]

在 PT 程序启动时,这些环境变量必须被设置

TOR_PT_MANAGED_TRANSPORT_VER
指定父进程支持的 PT 传输版本,使用逗号分隔。只要存在兼容的版本,PT 应该就接收对应的格式
有效的版本必须完全由非空格、非逗号的可打印 ASCII 字符组成。截至当前文档时,可插拔传输规范版本为 1
示例: TOR_PT_MANAGED_TRANSPORT_VER = 1, 1, 2 b, this_is_a_valid_ver
TOR_PT_STATE_LOCATION
指定一个用于存储 PT 状态的绝对路径,当 PT 启动时,目录可能不存在,PT 在需要时需要自己创建
PT 只能在对应的目录下创建文件,不能在其他位置存储内容
示例: TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state/
TOR_PT_EXIT_ON_STDIN_CLOSE
确定 PT 是否在 stdin 关闭时退出程序
只有该值为 1 时,PT 才可以在发现自己的标准输入流被关闭时关闭进程
示例: TOR_PT_EXIT_ON_STDIN_CLOSE=1
TOR_PT_OUTBOUND_BIND_ADDRESS_V4
指定一个 IPv4 地址,作为 PT 发送数据包的源 IP 地址,用于拥有多个网络接口的用户选择使用哪个接口发送数据
如果该值未设置或为空,PT 使用默认的 IP 地址发送数据
对于环回地址的连接,需要忽略该设置
示例: TOR_PT_OUTBOUND_BIND_ADDRESS_V4 = 203.0.113.4
TOR_PT_OUTBOUND_BIND_ADDRESS_V6
指定一个 IPv6 地址,作为 PT 发送数据包的源 IP 地址,用于拥有多个网络接口的用户选择使用哪个接口发送数据
如果该值未设置或为空,PT 使用默认的 IP 地址发送数据
对于环回地址的连接,需要忽略该设置
IPv6 地址必须用方括号括起来
示例: TOR_PT_OUTBOUND_BIND_ADDRESS_V6 = (2001: db8:: 4)

3.2.2 可插拔传输客户端环境变量

查看原文

3.2.2. Pluggable Transport Client Environment Variables

Client-side Pluggable Transport forward proxies are configured via the following environment variables.

"TOR_PT_CLIENT_TRANSPORTS"

Specifies the PT protocols the client proxy should initialize, as a comma separated list of PT names.
PTs SHOULD ignore PT names that it does not recognize.
Parent processes MUST set this environment variable when launching a client-side PT proxy instance.

Example: TOR_PT_CLIENT_TRANSPORTS=obfs2,obfs3,obfs4

"TOR_PT_PROXY"

Specifies an upstream proxy that the PT MUST use when making outgoing network connections. It is a URI [RFC3986] of the format:
<proxy_type>://[<user_name>[:][@]:.
The "TOR_PT_PROXY" environment variable is OPTIONAL and MUST be omitted if there is no need to connect via an upstream proxy.

Examples:
TOR_PT_PROXY=socks5://tor:test1234@198.51.100.1:8000
TOR_PT_PROXY=socks4a://198.51.100.2:8001
TOR_PT_PROXY=http://198.51.100.3:443

TOR_PT_CLIENT_TRANSPORTS
指定客户端需要初始化的 PT 协议,使用逗号分割 PT 列表。PT 应该忽略它无法识别的名称
父进程在启动时必须设置这个环境变量
示例: TOR_PT_CLIENT_TRANSPORTS=obfs2,obfs3,obfs4
TOR_PT_PROXY
PT 在进行外网连接时所使用的上游代理,格式为符合 RFC3986 标准的 URI:<proxy_type>://[<user_name>[:][@]:.
该选项是可选的,如果不需要使用上游代理,则必须省略该环境变量
示例:
  • TOR_PT_PROXY=socks5://tor:test1234@198.51.100.1:8000
  • TOR_PT_PROXY=socks4a://198.51.100.2:8001
  • TOR_PT_PROXY=http://198.51.100.3:443

3.2.3 可插拔传输服务端环境变量

查看原文

3.2.3. Pluggable Transport Server Environment Variables

Server-side Pluggable Transport reverse proxies are configured via the following environment variables.

"TOR_PT_SERVER_TRANSPORTS"

Specifies the PT protocols the server proxy should initialize, as a comma separated list of PT names.
PTs SHOULD ignore PT names that it does not recognize.
Parent processes MUST set this environment variable when launching a server-side PT reverse proxy instance.

Example: TOR_PT_SERVER_TRANSPORTS=obfs3,scramblesuit

"TOR_PT_SERVER_TRANSPORT_OPTIONS"

Specifies per-PT protocol configuration directives, as a semicolon-separated list of : pairs, where is a PT name and is a k=v string value with options that are to be passed to the transport.
Colons, semicolons, and backslashes MUST be escaped with a backslash.
If there are no arguments that need to be passed to any of PT transport protocols, "TOR_PT_SERVER_TRANSPORT_OPTIONS" MAY be omitted.

Example: TOR_PT_SERVER_TRANSPORT_OPTIONS=scramblesuit:key=banana;automata:rule=110;automata:depth=3

Will pass to 'scramblesuit' the parameter 'key=banana' and to 'automata' the arguments 'rule=110' and 'depth=3'.

"TOR_PT_SERVER_BINDADDR"

A comma separated list of <key>-<value> pairs, where <key> is a PT name and <value> is the <address>:<port> on which it should listen for incoming client connections.
The keys holding transport names MUST be in the same order as they appear in TOR_PT_SERVER_TRANSPORTS".
The <address> MAY be a locally scoped address as long as port forwarding is done externally.
The <address>:<port> combination MUST be an IP address supported by bind(), and MUST NOT be a host name.
Applications MUST NOT set more than one <address>:<port> pair per PT name.
If there is no specific <address>:<port> combination to be configured for any transports, "TOR_PT_SERVER_BINDADDR" MAY be omitted.

Example: TOR_PT_SERVER_BINDADDR=obfs3-198.51.100.1:1984,scramblesuit-127.0.0.1:4891

"TOR_PT_ORPORT"

Specifies the destination that the PT reverse proxy should forward traffic to after transforming it as appropriate, as an <address>:<port>.
Connections to the destination specified via "TOR_PT_ORPORT" MUST only contain application payload. If the parent process requires the actual source IP address of client connections (or other metadata), it should set "TOR_PT_EXTENDED_SERVER_PORT" instead.

Example: TOR_PT_ORPORT=127.0.0.1:9001

"TOR_PT_EXTENDED_SERVER_PORT"

Specifies the destination that the PT reverse proxy should forward traffic to, via the Extended ORPort protocol [EXTORPORT] as an <address>:<port>.
The Extended ORPort protocol allows the PT reverse proxy to communicate per-connection metadata such as the PT name and client IP address/port to the parent process.
If the parent process does not support the ExtORPort protocol, it MUST set "TOR_PT_EXTENDED_SERVER_PORT" to an empty string.

Example: TOR_PT_EXTENDED_SERVER_PORT=127.0.0.1:4200

"TOR_PT_AUTH_COOKIE_FILE"

Specifies an absolute filesystem path to the Extended ORPort authentication cookie, required to communicate with the Extended ORPort specified via "TOR_PT_EXTENDED_SERVER_PORT".
If the parent process is not using the ExtORPort protocol for incoming traffic, "TOR_PT_AUTH_COOKIE_FILE" MUST be omitted.

Example: TOR_PT_AUTH_COOKIE_FILE=/var/lib/tor/extended_orport_auth_cookie

TOR_PT_SERVER_TRANSPORTS
指定服务端需要初始化的 PT 协议,使用逗号分割 PT 列表。PT 应该忽略它无法识别的名称
父进程在启动时必须设置这个环境变量
示例: TOR_PT_SERVER_TRANSPORTS=obfs3,scramblesuit
TOR_PT_SERVER_TRANSPORT_OPTIONS
指定每个 PT 协议的配置指令,使用分号分割的name:k=v形式的列表,内容中所有的冒号、分号、反斜杠,都需要使用反斜杠转义
如果不需要传递参数,则可以省略
示例: TOR_PT_SERVER_TRANSPORT_OPTIONS=scramblesuit:key=banana;automata:rule=110;automata:depth=3
该示例会将key=banana传输给scramblesuit,将rule=110depth=3传输给automata
TOR_PT_SERVER_BINDADDR
逗号分割的<key>-<value>列表,前者是 PT 名称,后者则是应该监听的地址<address>:<port>
需要确保这里的顺序一定和TOR_PT_SERVER_TRANSPORTS相同
当在外部实现端口转发时,address可能是本地地址
<address>:<port>必须是可以被bind()接收的 IP 地址,不能是主机名
每一个 PT 只允许被设置一次
如果不需要设置 PT 监听地址,则该环境变量无需设置
示例: TOR_PT_SERVER_BINDADDR=obfs3-198.51.100.1:1984,scramblesuit-127.0.0.1:4891
TOR_PT_ORPORT
指定 PT 在反向代理时流量的目的地,格式为<address>:<port>
通过TOR_PT_ORPORT端口的连接只允许携带应用负载
如果父进程要求设置源 IP 地址,那么应该使用TOR_PT_EXTENDED_SERVER_PORT作为替代
示例: TOR_PT_ORPORT=127.0.0.1:9001
TOR_PT_EXTENDED_SERVER_PORT
指定 PT 在使用拓展 OR 端口协议时反向代理时流量的目的地,格式为<address>:<port>
拓展 OR 端口协议允许 PT 反向代理每一个通信连接的元数据,如 PT 客户端名称和地址端口
如果父进程不支持拓展 OR 端口协议,则该环境变量为空
示例: TOR_PT_EXTENDED_SERVER_PORT=127.0.0.1:4200
TOR_PT_AUTH_COOKIE_FILE
拓展 OR 端口协议认证 cookie 文件的绝对路径
如果设置了TOR_PT_EXTENDED_SERVER_PORT时,该环境变量必须存在
如果未设置TOR_PT_EXTENDED_SERVER_PORT时,该环境变量不能设置
示例: TOR_PT_AUTH_COOKIE_FILE=/var/lib/tor/extended_orport_auth_cookie

3.3 可插拔传输与父进程通信

查看原文

All Pluggable Transport Proxies communicate to the parent process via writing NL-terminated lines to stdout. The line metaformat is:

<Line> ::= <Keyword> <OptArgs> <NL>
<Keyword> ::= <KeywordChar> | <Keyword> <KeywordChar>
<KeywordChar> ::= <any US-ASCII alphanumeric, dash, and underscore>
<OptArgs> ::= <Args>*
<Args> ::= <SP> <ArgChar> | <Args> <ArgChar>
<ArgChar> ::= <any US-ASCII character but NUL or NL>
<SP> ::= <US-ASCII whitespace symbol (32)>
<NL> ::= <US-ASCII newline (line feed) character (10)>

The parent process MUST ignore lines received from PT proxies with unknown keywords.

所有可插拔传输代理与父进程通过 stdout 的命令通信

<Line> ::= <Keyword> <OptArgs> <NL>
 <Keyword> ::= <KeywordChar> | <Keyword><KeywordChar>
 <KeywordChar> ::= <any US-ASCII alphanumeric, dash,and underscore>
<OptArgs> ::= <Args>*
<Args> ::= <SP> <ArgChar> | <Args> <ArgChar>
<ArgChar> ::= <any US-ASCII character but NUL or NL>
<SP> ::= <US-ASCII whitespace symbol (32)>
 <NL> ::= <US-ASCII newline (line feed) character(10)>

父进程必须忽略所有 PT 输出的无法识别的关键字

3.3.1 普通消息

查看原文

3.3.1. Common Messages

When a PT proxy first starts up, it must determine which version of the Pluggable Transports Specification to use to configure itself.

It does this via the OR_PT_MANAGED_TRANSPORT_VER" (3.2.1) environment variable which contains all of the versions supported by the application.

Upon determining the version to use, or lack thereof, the PT proxy responds with one of two messages.

VERSION-ERROR <ErrorMessage>

The "VERSION-ERROR" message is used to signal that there was no compatible Pluggable Transport Specification version present in the "TOR_PT_MANAGED_TRANSPORT_VER" list.
The <ErrorMessage> SHOULD be set to "no-version" for historical reasons but MAY be set to a useful error message instead.
PT proxies MUST terminate after outputting a "VERSION-ERROR" message.

Example: VERSION-ERROR no-version

VERSION <ProtocolVersion>

The "VERSION" message is used to signal the Pluggable Transport Specification version (as in "TOR_PT_MANAGED_TRANSPORT_VER") that the PT proxy will use to configure it's transports and communicate with the parent process.
The version for the environment values and reply messages specified by this document is "1".
PT proxies MUST either report an error and terminate, or output a "VERSION" message before moving on to client/server proxy initialization and configuration.

Example: VERSION 1

After version negotiation has been completed the PT proxy must then validate that all of the required environment variables are provided, and that all of the configuration values supplied are well formed.

At any point, if there is an error encountered related to configuration supplied via the environment variables, it MAY respond with an error message and terminate.

ENV-ERROR <ErrorMessage>

The "ENV-ERROR" message is used to signal the PT proxy's failure to parse the configuration environment variables (3.2).
The <ErrorMessage> SHOULD consist of a useful error message that can be used to diagnose and correct the root cause of the failure.

PT proxies MUST terminate after outputting a "ENV-ERROR" message.

Example: ENV-ERROR No TOR_PT_AUTH_COOKIE_FILE when TOR_PT_EXTENDED_SERVER_PORT set

当一个 PT 代理第一次启动时,其必须确认需要使用哪个版本的可插拔传输规范。其通过OR_PT_MANAGED_TRANSPORT_VER环境变量来交互应用支持的所有版本
PT 通过一条或两条消息来确认使用的版本或向上报错

VERSION-ERROR
版本错误表明TOR_PT_MANAGED_TRANSPORT_VER列表中没有兼容的可插入传输规范版本
错误消息应该被设置为no-version,但也可能会被设置成其他更有意义的错误反馈
当 PT 代理必须在VERSION-ERROR发送后终止
示例: VERSION-ERROR no-version
VERSION
该信息用于协商可插拔传输规范版本
当前文档对应的版本为1
PT 代理必须返回VERSION信息,或者返回VERSION-ERROR并结束进程
示例: VERSION 1

在版本协商完毕后,PT 代理需要检查所有环境变量的合法性
在任何通信过程中,如果发环境变量错误,都可以返回错误信息,并终止进程

ENV-ERROR
用于声明 PT 代理解析环境变量错误
其应该包含有意义的错误信息,以便于检查错误
PT 代理必须在输出该信息后终止进程
示例: ENV-ERROR No TOR_PT_AUTH_COOKIE_FILE when TOR_PT_EXTENDED_SERVER_PORT set

3.3.2 可插拔传输客户端信息

查看原文

3.3.2. Pluggable Transport Client Messages

After negotiating the Pluggable Transport Specification version, PT client proxies MUST first validate "TOR_PT_PROXY" (3.2.2) if it is set, before initializing any transports.

Assuming that an upstream proxy is provided, PT client proxies MUST respond with a message indicating that the proxy is valid, supported, and will be used OR a failure message.

PROXY DONE

The "PROXY DONE" message is used to signal the PT proxy's acceptance of the upstream proxy specified by "TOR_PT_PROXY".

PROXY-ERROR <ErrorMessage>

The "PROXY-ERROR" message is used to signal that the upstream proxy is malformed/unsupported or otherwise unusable.
PT proxies MUST terminate immediately after outputting a "PROXY-ERROR" message.

Example: PROXY-ERROR SOCKS 4 upstream proxies unsupported.

After the upstream proxy (if any) is configured, PT clients then iterate over the requested transports in "TOR_PT_CLIENT_TRANSPORTS" and initialize the listeners.
For each transport initialized, the PT proxy reports the listener status back to the parent via messages to stdout.

CMETHOD <transport> <'socks4','socks5'> <address:port>

The "CMETHOD" message is used to signal that a requested PT transport has been launched, the protocol which the parent should use to make outgoing connections, and the IP address and port that the PT transport's forward proxy is listening on.

Example: CMETHOD trebuchet socks5 127.0.0.1:19999

CMETHOD-ERROR <transport> <ErrorMessage>

The "CMETHOD-ERROR" message is used to signal that requested PT transport was unable to be launched.

Example: CMETHOD-ERROR trebuchet no rocks available

Once all PT transports have been initialized (or have failed), the PT proxy MUST send a final message indicating that it has finished initializing.

CMETHODS DONE

The "CMETHODS DONE" message signals that the PT proxy has finished initializing all of the transports that it is capable of handling.
Upon sending the "CMETHODS DONE" message, the PT proxy initialization is complete.

Notes:

  • Unknown transports in "TOR_PT_CLIENT_TRANSPORTS" are ignored entirely, and MUST NOT result in a "CMETHOD-ERROR" message.
    Thus it is entirely possible for a given PT proxy to immediately output "CMETHODS DONE".
  • Parent processes MUST handle "CMETHOD"/"CMETHOD-ERROR" messages in any order, regardless of ordering in "TOR_PT_CLIENT_TRANSPORTS".

在协商可插拔传输规范版本后,PT 客户端需要验证TOR_PT_PROXY是否设置,而后初始化传输。
如果上游代理被设置,PT 客户端必须响应一条消息,表明代理是有效的、受支持的、被使用的或是失败消息

PROXY DONE
通知父进程TOR_PT_PROXY设置的代理已准备就绪
PROXY-ERROR <ErrorMessage>
通知父进程,上游代理无法使用。
在该消息发送后,PT 代理需要结束进程
示例: PROXY-ERROR SOCKS 4 upstream proxies unsupported.

在上游代理(如果存在)配置完毕后,PT 客户机需要启动侦听器。每一个传输初始化时,代理都需要通过 stdout 向父进程报告侦听器状态

CMETHOD <transport> <'socks4','socks5'> <address:port>
表明 PT 传输已启动,父进程应该根据协议建立外向连接。同时传输了 PT 传输前向代理监听的 IP 地址与端口
示例: CMETHOD trebuchet socks5 127.0.0.1:19999
CMETHOD-ERROR <ErrorMessage>
用于通知父进程传输失败
示例: CMETHOD-ERROR trebuchet no rocks available

一旦所有的PT传输被初始化(或失败),PT代理必须发送一个最终消息,表明它已经完成了初始化。

CMETHODS DONE
表明 PT 代理已经完成了它能够处理的所有传输的初始化

需要特别注意的是:

  • TOR_PT_CLIENT_TRANSPORTS中无法识别的传输将会被完全忽略,不需要发送CMETHOD-ERROR消息
  • 木进程必须可以接收任意顺序的CMETHODCMETHOD-ERROR

3.3.3 可插拔传输服务端信息

查看原文

3.3.3. Pluggable Transport Server Messages

PT server reverse proxies iterate over the requested transports in "TOR_PT_CLIENT_TRANSPORTS" and initialize the listeners.
For each transport initialized, the PT proxy reports the listener status back to the parent via messages to stdout.

SMETHOD <transport> <address:port> [options]

The "SMETHOD" message is used to signal that a requested PT transport has been launched, the protocol which will be used to handle incoming connections, and the IP address and port that clients should use to reach the reverse-proxy.
If there is a specific <address:port> provided for a given PT transport via "TOR_PT_SERVER_BINDADDR", the transport MUST be initialized using that as the server address.
The OPTIONAL 'options' field is used to pass additional per-transport information back to the parent process.
The currently recognized 'options' are: ARGS:[<Key>=<Value>,]+[<Key>=<Value>]
The "ARGS" option is used to pass additional key/value formatted information that clients will require to use the reverse proxy.
Equal signs and commas MUST be escaped with a backslash.
Tor: The ARGS are included in the transport line of the Bridge's extra-info document.

Examples: SMETHOD trebuchet 198.51.100.1:19999
SMETHOD rot_by_N 198.51.100.1:2323 ARGS:N=13

SMETHOD-ERROR <transport> <ErrorMessage>

The "SMETHOD-ERROR" message is used to signal that requested PT transport reverse proxy was unable to be launched.

Example: SMETHOD-ERROR trebuchet no cows available

Once all PT transports have been initialized (or have failed), the PT proxy MUST send a final message indicating that it has finished initializing.

SMETHODS DONE

The "SMETHODS DONE" message signals that the PT proxy has finished initializing all of the transports that it is capable of handling.

Upon sending the "SMETHODS DONE" message, the PT proxy initialization is complete.

PT 服务端反向代理遍历TOR_PT_CLIENT_TRANSPORT中的请求,并初始化侦听器。对于初始化的每一个传输,都通过向 stdout 发送消息将侦听器状态报告给父进程

SMETHOD <transport> <address:port> [options]
用于通知父进程请求的 PT 传输已经启动,处理传入的连接的协议,反向代理连接的地址、端口
如果通过TOR_PT_SERVER_BINDADDR提供了形如<address:port>的地址,传输必须使用对应的地址
可选参数使用如下的格式传输ARGS:[<Key>=<Value>,]+[<Key>=<Value>]
其中ARGS用于传递客户端使用反向代理时所需要的附加键值对信息,等号和逗号必须使用反斜杠转义。可参考网桥的额外信息文档
示例: SMETHOD trebuchet 198.51.100.1:19999 SMETHOD rot_by_N 198.51.100.1:2323 ARGS:N=13
SMETHOD-ERROR <transport><ErrorMessage>
表明请求的 PT 传输反向代理无法启动
示例: SMETHOD-ERROR trebuchet no cows available

一旦所有 PT 传输被初始化(成功或失败),PT 必须发送一个消息表明该阶段完成

SMETHODS DONE
说明 PT 代理已经完成了所有传输的初始化

3.3.4 可插拔传输日志信息

查看原文

3.3.4. Pluggable Transport Log Message

This message is for a client or server PT to be able to signal back to the parent process via stdout or stderr any log messages.

A log message can be any kind of messages (human readable) that the PT sends back so the parent process can gather information about what is going on in the child process. It is not intended for the parent process to parse and act accordingly but rather a message used for plain logging.

For example, the tor daemon logs those messages at the Severity level and sends them onto the control port using the PT_LOG (see control-spec.txt) event so any third part can pick them up for debugging.

The format of the message: LOG SEVERITY=Severity MESSAGE=Message

The SEVERITY value indicate at which logging level the message applies.
The accepted values for <Severity> are: error, warning, notice, info, debug

The MESSAGE value is a human readable string formatted by the PT. The <Message> contains the log message which can be a String or CString (see section 2 in control-spec.txt).

Example: LOG SEVERITY=debug MESSAGE="Connected to bridge A"

用于让客户端或服务端 PT 可以通过 stdout 或 stderr 向父进程发送日志消息

日志消息可以是 PT 发挥父进程的任何人类可读的消息,以便于父进程收集 PT 正在进行的时间。日志不需要由父进程解析,只用于记录

例如,Tor 守护进程可能会将这些消息记录在不同的日志级别,并通过PT_LOG(见 Tor 控制规范)事件发送,这样任何第三方都可以方便地进行调试

该消息的格式为LOG SEVERITY=Severity MESSAGE=Message
SEVERITY为事件严重性级别,包括errorwarningnoticeinfodebug
MESSAGE包含人类可读的字符串,可以是 String 也可以是 CString

示例: LOG SEVERITY=debug MESSAGE="Connected to bridge A"

该部分内容可参见 control-spec.txt 的第 2 节

3.3.5 可插拔传输状态消息

查看原文

3.3.5. Pluggable Transport Status Message

This message is for a client or server PT to be able to signal back to the parent process via stdout or stderr any status messages.

The format of the message: STATUS TRANSPORT=Transport <K_1>=<V_1> [<K_2>=<V_2>, ...]

The TRANSPORT value indicate a hint on what the PT is such has the name or the protocol used for instance. As an example, obfs4proxy would use "obfs4". Thus, the Transport value can be anything the PT itself defines and it can be a String or CString (see section 2 in control-spec.txt).

The <K_n>=<V_n> values are specific to the PT and there has to be at least one. They are messages that reflects the status that the PT wants to report. <V_n> can be a String or CString.

Examples (fictional):]
STATUS TRANSPORT=obfs4 ADDRESS=198.51.100.123:1234 CONNECT=Success
STATUS TRANSPORT=obfs4 ADDRESS=198.51.100.222:2222 CONNECT=Failed FINGERPRINT= ERRSTR="Connection refused"
STATUS TRANSPORT=trebuchet ADDRESS=198.51.100.15:443 PERCENT=42

用于让客户端或服务端 PT 可以通过 stdout 或 stderr 向父进程发送状态消息

消息格式为: STATUS TRANSPORT=Transport <K_1>=<V_1> [<K_2>=<V_2>, ...]
TRANSPORT表明了 PT 的类型(如名称或协议),可以是 PT 定义的任何值,可以是 String 也可以是 CString
<K_n>=<V_n>至少存在一个,表明了要汇报的状态,可以是 String 也可以是 CString

示例:

  • STATUS TRANSPORT=obfs4 ADDRESS=198.51.100.123:1234 CONNECT=Success
  • STATUS TRANSPORT=obfs4 ADDRESS=198.51.100.222:2222 CONNECT=Failed FINGERPRINT= ERRSTR="Connection refused"
  • STATUS TRANSPORT=trebuchet ADDRESS=198.51.100.15:443 PERCENT=42

3.4 可插拔传输关闭

查看原文

3.4. Pluggable Transport Shutdown

The recommended way for Pluggable Transport using applications and Pluggable Transports to handle graceful shutdown is as follows.

  • (Parent) Set "TOR_PT_EXIT_ON_STDIN_CLOSE" (3.2.1) when launching the PT proxy, to indicate that stdin will be used for graceful shutdown notification.
  • (Parent) When the time comes to terminate the PT proxy:
    1. Close the PT proxy's stdin.
    2. Wait for a "reasonable" amount of time for the PT to exit.
    3. Attempt to use OS specific mechanisms to cause graceful PT shutdown (eg: 'SIGTERM')
    4. Use OS specific mechanisms to force terminate the PT (eg: 'SIGKILL', 'ProccessTerminate()').
  • PT proxies SHOULD monitor stdin, and exit gracefully when it is closed, if the parent supports that behavior.
  • PT proxies SHOULD handle OS specific mechanisms to gracefully terminate (eg: Install a signal handler on 'SIGTERM' that causes cleanup and a graceful shutdown if able).
  • PT proxies SHOULD attempt to detect when the parent has terminated (eg: via detecting that it's parent process ID haso changed on U*IX systems), and gracefully terminate.

可插拔传输关闭的方式如下:

  • 父进程设置TOR_PT_EXIT_ON_STDIN_CLOSE时,说明使用 stdin 作为关闭的通知
  • 父进程需要关闭 PT 时,将会:
    1. 关闭 PT 的 stdin
    2. 等待一段合理的时间以供 PT 退出
    3. 使用特定的操作系统机制来关闭(如SIGTERM
    4. 使用特定的操作系统机制来强制关闭(如SIGKILLProcessTerminate())
  • PT 代理应该监控 stdin,并且在其关闭后退出
  • PT 代理应该监控系统信号,当收到响应信号后退出
  • PT 代理应该尝试检查父进程是否关闭,当发现关闭后退出

3.5 可插拔传输客户端单连接参数

查看原文

3.5. Pluggable Transport Client Per-Connection Arguments

Certain PT transport protocols require that the client provides per-connection arguments when making outgoing connections. On the server side, this is handled by the "ARGS" optional argument as part of the "SMETHOD" message.
On the client side, arguments are passed via the authentication fields that are part of the SOCKS protocol.

First the "=" formatted arguments MUST be escaped, such that all backslash, equal sign, and semicolon characters are escaped with a backslash.
Second, all of the escaped are concatenated together.

Example: shared-secret=rahasia;secrets-file=/tmp/blob

Lastly the arguments are transmitted when making the outgoing connection using the authentication mechanism specific to the SOCKS protocol version.

  • In the case of SOCKS 4, the concatenated argument list is transmitted in the "USERID" field of the "CONNECT" request.
  • In the case of SOCKS 5, the parent process must negotiate "Username/Password" authentication [RFC1929], and transmit the arguments encoded in the "UNAME" and "PASSWD" fields.

If the encoded argument list is less than 255 bytes in length, the "PLEN" field must be set to "1" and the "PASSWD" field must contain a single NUL character.

某些 PT 协议要求客户端在进行外向连接时提供每个连接的参数。在服务器端,这些由ARGS作为SMETHOD消息的一部分处理;在客户端通过 SOCKS 协议的一部分身份验证字段传递

首先,格式化的参数必须转义,所有反斜杠、等号、分号都需要使用反斜杠转义

接着,将所有转义后的字符连接在一起
示例: shared-secret=rahasia;secrets-file=/tmp/blob

最后,使用特定于 SOCKS 版本的身份验证机制传输传输参数

  • 对于 SOCKS4 ,连接的参数列表在CONNECT请求的USERID字段设置
  • 对于 SOCKS5,父进程必须协商用户名/密码爽身粉验证机制,并使用UNAMEPASSWD字段传输。如果已编码的参数列表长度小于 255 字节,则PLEN字段必须设置为1PASSWD字段必须包含一个NULL字符

4 匿名性

查看原文

4. Anonymity Considerations

When designing and implementing a Pluggable Transport, care should be taken to preserve the privacy of clients and to avoid leaking personally identifying information.

Examples of client related considerations are:

  • Not logging client IP addresses to disk.
  • Not leaking DNS addresses except when necessary.
  • Ensuring that "TOR_PT_PROXY"'s "fail closed" behavior is implemented correctly.

Additionally, certain obfuscation mechanisms rely on information such as the server IP address/port being confidential, so clients also need to take care to preserve server side information confidential when applicable.

在设计和实现可插拔传输时,应该注意保护客户隐私并避免泄露个人身份信息

客户考虑的例子有:

  • 没有记录客户端 IP 地址到硬盘
  • 不泄露 DNS 地址,除非有必要
  • 确保TOR_PT_PROXYfail closed行为正确实现

此外,某些混淆机制依赖于服务器的 IP 地址、端口等信息,因此客户机还需要注意在适用的情况下保持服务端信息的机密性

5 参考资料

查看原文

5. References

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC1928] Leech, M., Ganis, M., Lee, Y., Kuris, R., Koblas, D., Jones, L., "SOCKS Protocol Version 5", RFC 1928, March 1996.
  • [EXTORPORT] Kadianakis, G., Mathewson, N., "Extended ORPort and TransportControlPort", Tor Proposal 196, March 2012.
  • [RFC3986] Berners-Lee, T., Fielding, R., Masinter, L., "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005.
  • [RFC1929] Leech, M., "Username/Password Authentication for SOCKS V5", RFC 1929, March 1996.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC1928] Leech, M., Ganis, M., Lee, Y., Kuris, R., Koblas, D., Jones, L., "SOCKS Protocol Version 5", RFC 1928, March 1996.
  • [EXTORPORT] Kadianakis, G., Mathewson, N., "Extended ORPort and TransportControlPort", Tor Proposal 196, March 2012.
  • [RFC3986] Berners-Lee, T., Fielding, R., Masinter, L., "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005.
  • [RFC1929] Leech, M., "Username/Password Authentication for SOCKS V5", RFC 1929, March 1996.

6 致谢

查看原文

6. Acknowledgments

This specification draws heavily from prior versions done by Jacob Appelbaum, Nick Mathewson, and George Kadianakis.

这个规范大量借鉴了Jacob Appelbaum、Nick Mathewson和George Kadianakis之前的版本。

附录 A. 客户端会话案例

查看原文

Appendix A. Example Client Pluggable Transport Session

Environment variables:

TOR_PT_MANAGED_TRANSPORT_VER=1
TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state/
TOR_PT_EXIT_ON_STDIN_CLOSE=1
TOR_PT_PROXY=socks5://127.0.0.1:8001
TOR_PT_CLIENT_TRANSPORTS=obfs3,obfs4

Messages the PT Proxy writes to stdin:

VERSION 1
PROXY DONE
CMETHOD obfs3 socks5 127.0.0.1:32525
CMETHOD obfs4 socks5 127.0.0.1:37347
CMETHODS DONE

Environment variables:

    TOR_PT_MANAGED_TRANSPORT_VER=1
    TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state/
    TOR_PT_EXIT_ON_STDIN_CLOSE=1
    TOR_PT_PROXY=socks5://127.0.0.1:8001
    TOR_PT_CLIENT_TRANSPORTS=obfs3,obfs4

Messages the PT Proxy writes to stdin:

    VERSION 1
    PROXY DONE
    CMETHOD obfs3 socks5 127.0.0.1:32525
    CMETHOD obfs4 socks5 127.0.0.1:37347
    CMETHODS DONE

附录 B. 服务端会话案例

查看原文

Appendix B. Example Server Pluggable Transport Session

Environment variables:

TOR_PT_MANAGED_TRANSPORT_VER=1
TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state
TOR_PT_EXIT_ON_STDIN_CLOSE=1
TOR_PT_SERVER_TRANSPORTS=obfs3,obfs4
TOR_PT_SERVER_BINDADDR=obfs3-198.51.100.1:1984

Messages the PT Proxy writes to stdin:

VERSION 1
SMETHOD obfs3 198.51.100.1:1984
SMETHOD obfs4 198.51.100.1:43734 ARGS:cert=HszPy3vWfjsESCEOo9ZBkRv6zQ/1mGHzc8arF0y2SpwFr3WhsMu8rK0zyaoyERfbz3ddFw,iat-mode=0
SMETHODS DONE

 Environment variables:

    TOR_PT_MANAGED_TRANSPORT_VER=1
    TOR_PT_STATE_LOCATION=/var/lib/tor/pt_state
    TOR_PT_EXIT_ON_STDIN_CLOSE=1
    TOR_PT_SERVER_TRANSPORTS=obfs3,obfs4
    TOR_PT_SERVER_BINDADDR=obfs3-198.51.100.1:1984

 Messages the PT Proxy writes to stdin:

    VERSION 1
    SMETHOD obfs3 198.51.100.1:1984
    SMETHOD obfs4 198.51.100.1:43734 ARGS:cert=HszPy3vWfjsESCEOo9ZBkRv6zQ/1mGHzc8arF0y2SpwFr3WhsMu8rK0zyaoyERfbz3ddFw,iat-mode=0
    SMETHODS DONE