Console Script Guide

The console script can be used to build a standalone PT tunnel. Borrowing from the illustration in PT specifications:

+------------+                    +-------------------+
| Client App +-- Local Loopback --+ ptadapter Client  +--+
+------------+                    +-------------------+  |
                                                         |
    Public Internet (Obfuscated/Transformed traffic) ==> |
                                                         |
+------------+                    +-------------------+  |
| Server App +-- Local Loopback --+ ptadapter Server  +--+
+------------+                    +-------------------+

One copy of ptadapter runs on the client host, and one copy runs on the server host. The client app connects to the client-side ptadapter, which obfuscates traffic and sends it to the server-side ptadapter, which then unobfuscates it and forward it to the server app.

Invocation

If ptadapter is installed via pip, simply run it by name:

$ ptadapter

Otherwise, ensure the ptadapter directory is in the working directory or somewhere else in PYTHONPATH, and run:

$ python -m ptadapter

(All examples below will use the first format. Add python -m to the command line yourself where appropriate.)

Running ptadapter without command line arguments will print a brief usage message and an error. To see an explanation of the available command line arguments, run:

$ ptadapter --help

In most cases, the command line arguments required are pretty simple. To create the server end of an obfuscated tunnel, run:

$ ptadapter -S <config-file>

And to create the client end, run:

$ ptadapter -C <config-file>

But then, what should the config file look like?

Config file

Config files for ptadapter are written in the familiar INI format. For the client side, a [client] section is required, while for the server side a [server] section is required. In these sections, basic configuration options about the PT are specified, as well as a list of section names, where each of the named section describes a single transport to be used.

Below is an example config file. Please read the comments before writing your own config file, and do not copy the file wholesale.

# This is the example configuration file for ptadapter's console script.
#
# Lines beginning with "#" are comments.
#
# Use absolute paths whenever possible.
# If a relative path is used in any path config, it will be converted to an
# abosolute path relative to the working directory when ptadapter starts.
#
# Section names are case-insensitive. Do not use the section name "default" or
# any case variation thereof.
#
# It is possible to have separate client and server configuration in the same
# config file.
#
# This file is for demonstration purposes. If two instances of ptadapter
# is run using this config file, one as server and one as client, three
# separate PT tunnels will be established, between client ends
# 127.0.0.1:8000, 127.0.0.1:8001 and 127.0.0.1:8002, and the server end
# 127.0.0.1:7000.
#
# Do not use this file on your actual server! When running an obfs4proxy
# server, you do not need to specify server keys in the config file. obfs4proxy
# will generate keys and store them in the state directory.

# ====================

# Client configuration
#
# A client configuration file must have a [client] section.

[client]

exec = /usr/bin/obfs4proxy
# The Pluggable Transport's executable. It is also possible to include command
# line arguments, like the following:
# exec = /usr/bin/obfs4proxy -enableLogging

state = ./state
# The state directory. Omit this line or specify an empty value to use a
# temporary directory, which is cleaned when the PT exits.

tunnels = client_obfs4_1 client_obfs4_2 client_obfs3
# Section names describing client transport tunnels, separated by whitespace.
# Each specified section must exist.


[client_obfs4_1]
# This is the config section for a client transport tunnel.

transport = obfs4
# Name of the transport for this tunnel. Should be a supported transport method
# of the PT.

listen = 127.0.0.1:8000
# Address and port to listen for unobfuscated client traffic.

upstream = 127.0.0.1:7900
# Upstream PT address and port to send obfuscated traffic to.

# If the client transport tunnel requires per-tunnel options, specify them
# on separate lines, one line for each option.
# The configuration key should be named "options-<option name>".
# The two lines below specify the options "cert" and "iat-mode" respectively.

options-cert = TT5FYRSZBwJVcYJ6EndmG1+fykZDk9dkEEJiCmCIGnLrtH74xaWECstPhY5cACbLLnX9bw
options-iat-mode = 0

[client_obfs4_2]
transport = obfs4
listen = 127.0.0.1:8001
upstream = 127.0.0.1:7900
options-cert = TT5FYRSZBwJVcYJ6EndmG1+fykZDk9dkEEJiCmCIGnLrtH74xaWECstPhY5cACbLLnX9bw
options-iat-mode = 0

[client_obfs3]
# This is a client transport tunnel section with no additional options.
transport = obfs3
listen = 127.0.0.1:8002
upstream = 127.0.0.1:7901


# ====================

# Server configuration
#
# A server configuration must have a [server] section.

[server]

exec = /usr/bin/obfs4proxy
# The Pluggable Transport's executable. It is also possible to include command
# line arguments, like the following:
# exec = /usr/bin/obfs4proxy -enableLogging

state = ./state
# The state directory. Omit this line or specify an empty value to use a
# temporary directory, which is cleaned when the PT exits.
# For servers, it is recommended to use an actual persistent location for the
# state directory, instead of using a temporary directory, since the server
# is more likely to store state (like crypto keys, certificates, etc.)

forward = 127.0.0.1:7000
# Address and port to forward unobfuscated traffic to.

tunnels = server_obfs4 server_obfs3
# Section names describing server transports, separated by whitespace.
# Each specified section must exist.


[server_obfs4]
# This is the config section of a server transport.

transport = obfs4
# Name of the transport for this tunnel. Should be a supported transport method
# of the PT.

listen = 127.0.0.1:7900
# Address and port to listen for obfuscated client traffic.

# If the server transport  requires per-transport options, specify them
# on separate lines, one line for each option.
# The configuration key should be named "options-<option name>".
# The two lines below specify five options,
# "node-id", "private-key", "public-key", "drbg-seed" and "iat-mode"
# respectively.

options-node-id = 4d3e4561149907025571827a1277661b5f9fca46
options-private-key = 7886017adfd178cd139e91250dddee0b2af8ab6cf93f1fe9a7a469d3a13a3067
options-public-key = 4393d7641042620a60881a72ebb47ef8c5a5840acb4f858e5c0026cb2e75fd6f
options-drbg-seed = c23e876ddc408cc392317e017a6796a96161f76d8dd90522
options-iat-mode = 0


[server_obfs3]
# This is a server tranposrt config section with no options.
transport = obfs3
listen = 127.0.0.1:7901

To reiterate, do not copy the server and client options in the example config file and use it in your own production server!