config

package
v0.0.0-...-2318bba Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2024 License: Apache-2.0 Imports: 14 Imported by: 1

Documentation

Overview

Package config provides convenience functions to create dialer objects based on a text config. This is experimental and mostly for illustrative purposes at this point.

Configurable transports simplifies the way you create and manage transports. With the config package, you can use [NewPacketDialer] and [NewStreamDialer] to create dialers using a simple text string.

Key Benefits:

  • Ease of Use: Create transports effortlessly by providing a textual configuration, reducing boilerplate code.
  • Serialization: Easily share configurations with users or between different parts of your application, including your Go backend.
  • Dynamic Configuration: Set your app's transport settings at runtime.
  • DPI Evasion: Advanced nesting and configuration options help you evade Deep Packet Inspection (DPI).

Config Format

The configuration string is composed of parts separated by the `|` symbol, which define nested dialers. For example, `A|B` means dialer `B` takes dialer `A` as its input. An empty string represents the direct TCP/UDP dialer, and is used as the input to the first cofigured dialer.

Each dialer configuration follows a URL format, where the scheme defines the type of Dialer. Supported formats include:

Shadowsocks proxy (compatible with Outline's access keys, package github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks)

ss://[USERINFO]@[HOST]:[PORT]?prefix=[PREFIX]

SOCKS5 proxy (currently streams only, package github.com/Jigsaw-Code/outline-sdk/transport/socks5)

socks5://[USERINFO]@[HOST]:[PORT]

USERINFO field is optional and only required if username and password authentication is used. It is in the format of username:password.

Stream split transport (streams only, package github.com/Jigsaw-Code/outline-sdk/transport/split)

It takes the length of the prefix. The stream will be split when PREFIX_LENGTH bytes are first written.

split:[PREFIX_LENGTH]

TLS transport (currently streams only, package github.com/Jigsaw-Code/outline-sdk/transport/tls)

The sni parameter defines the name to be sent in the TLS SNI. It can be empty. The certname parameter defines what name to validate against the server certificate.

tls:sni=[SNI]&certname=[CERT_NAME]

TLS fragmentation (streams only, package github.com/Jigsaw-Code/outline-sdk/transport/tlsfrag).

The Client Hello record payload will be split into two fragments of size LENGTH and len(payload)-LENGTH if LENGTH>0. If LENGTH<0, the two fragments will be of size len(payload)-LENGTH and LENGTH respectively. For more details, refer to github.com/Jigsaw-Code/outline-sdk/transport/tlsfrag.

tlsfrag:[LENGTH]

Address override.

This dialer configuration is helpful for testing and development or if you need to fix the domain resolution. The host parameter, if not empty, specifies the host to dial instead of the original host. The port parameter, if not empty, specifies the port to dial instead of the original port.

override:host=[HOST]&port=[PORT]

Examples

Packet splitting - To split outgoing streams on bytes 2 and 123, you can use:

split:2|split:123

Evading DNS and SNI blocking - A blocked site hosted on Cloudflare can potentially be accessed by resolving cloudflare.net instead of the original domain and using stream split:

override:host=cloudflare.net.|split:2

SOCKS5-over-TLS, with domain-fronting - To tunnel SOCKS5 over TLS, and set the SNI to decoy.example.com, while still validating against your host name, use:

tls:sni=decoy.example.com&certname=[HOST]|socks5:[HOST]:[PORT]

Onion Routing with Shadowsocks - To route your traffic through three Shadowsocks servers, similar to Onion Routing, use:

ss://[USERINFO1]@[HOST1]:[PORT1]|ss://[USERINFO2]@[HOST2]:[PORT2]|ss://[USERINFO3]@[HOST3]:[PORT3]

In that case, HOST1 will be your entry node, and HOST3 will be your exit node.

DPI Evasion - To add packet splitting to a Shadowsocks server for enhanced DPI evasion, use:

split:2|ss://[USERINFO]@[HOST]:[PORT]

Defining custom transport - You can define your custom transport by implementing and registering the WrapStreamDialerFunc and WrapPacketDialerFunc functions:

// create new config parser
// p := new(ConfigParser)
// or
p := NewDefaultConfigParser()
// register your custom dialer
p.RegisterPacketDialerWrapper("custom", wrapStreamDialerWithCustom)
p.RegisterStreamDialerWrapper("custom", wrapPacketDialerWithCustom)
// then use it
dialer, err := p.WrapStreamDialer(innerDialer, "custom://config")

where wrapStreamDialerWithCustom and wrapPacketDialerWithCustom implement WrapPacketDialerFunc and WrapStreamDialerFunc.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewPacketListener

func NewPacketListener(transportConfig string) (transport.PacketListener, error)

NewpacketListener creates a new transport.PacketListener according to the given config, the config must contain only one "ss://" segment. TODO: make NewPacketListener configurable.

func SanitizeConfig

func SanitizeConfig(transportConfig string) (string, error)

Types

type ConfigParser

type ConfigParser struct {
	// contains filtered or unexported fields
}

ConfigParser enables the creation of stream and packet dialers based on a config. The config is extensible by registering wrappers for config subtypes.

func NewDefaultConfigParser

func NewDefaultConfigParser() *ConfigParser

NewDefaultConfigParser creates a ConfigParser with a set of default wrappers already registered.

func (*ConfigParser) RegisterPacketDialerWrapper

func (p *ConfigParser) RegisterPacketDialerWrapper(subtype string, wrapper WrapPacketDialerFunc) error

RegisterPacketDialerWrapper will register a wrapper for packet dialers under the given subtype.

func (*ConfigParser) RegisterStreamDialerWrapper

func (p *ConfigParser) RegisterStreamDialerWrapper(subtype string, wrapper WrapStreamDialerFunc) error

RegisterStreamDialerWrapper will register a wrapper for stream dialers under the given subtype.

func (*ConfigParser) WrapPacketDialer

func (p *ConfigParser) WrapPacketDialer(dialer transport.PacketDialer, transportConfig string) (transport.PacketDialer, error)

WrapPacketDialer creates a transport.PacketDialer according to transportConfig, using dialer as the base transport.PacketDialer. The given dialer must not be nil.

func (*ConfigParser) WrapStreamDialer

func (p *ConfigParser) WrapStreamDialer(dialer transport.StreamDialer, transportConfig string) (transport.StreamDialer, error)

WrapStreamDialer creates a transport.StreamDialer according to transportConfig, using dialer as the base transport.StreamDialer. The given dialer must not be nil.

type WrapPacketDialerFunc

type WrapPacketDialerFunc func(dialer transport.PacketDialer, wrapConfig *url.URL) (transport.PacketDialer, error)

WrapPacketDialerFunc wraps a transport.PacketDialer based on the wrapConfig.

type WrapStreamDialerFunc

type WrapStreamDialerFunc func(dialer transport.StreamDialer, wrapConfig *url.URL) (transport.StreamDialer, error)

WrapStreamDialerFunc wraps a transport.StreamDialer based on the wrapConfig.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL