-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(client): introduce extensible YAML config #2329
Open
fortuna
wants to merge
15
commits into
master
Choose a base branch
from
fortuna-go-config
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1093e52
introduce extensible YAML config
fortuna 6adc72a
Add config doc
fortuna 896d41e
Remove unused fields
fortuna f97733e
Merge branch 'master' into fortuna-go-config
fortuna 80cf1fd
Clean up TEST_ONLY
fortuna 8a83990
Config lint
fortuna b9057af
Improve doc
fortuna e4d67a5
Remove ss transport
fortuna 8004623
Revamp Config
fortuna 909486b
Add examples
fortuna 4dcfe23
Use $type
fortuna 5beaddd
Fix test
fortuna a48ed20
Add Unsupported config
fortuna 479b052
Merge branch 'master' into fortuna-go-config
fortuna 80d1206
Tunnel Config Go parsing
fortuna File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
<!-- markdownlint-disable-file MD033 --> | ||
|
||
# Outline Config Reference | ||
|
||
Outline uses a YAML-based configuration to define VPN parameters and handle TCP/UDP traffic. The configuration supports composability at multiple levels, enabling flexible and extensible setups. | ||
|
||
The top-level configuration specifies a [TunnelConfig](#TunnelConfig). | ||
|
||
## Examples | ||
A typical Shadowsocks configuration will look like this: | ||
|
||
```yaml | ||
transport: | ||
$type: tcpudp | ||
|
||
tcp: | ||
$type: shadowsocks | ||
endpoint: ss.example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
prefix: "POST " | ||
|
||
udp: | ||
$type: shadowsocks | ||
endpoint: ss.example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
``` | ||
|
||
Note how we can now have TCP and UDP running on different ports or endpoints. | ||
|
||
You can leverage YAML anchors and the `<<` merge key to avoid duplication: | ||
|
||
```yaml | ||
transport: | ||
$type: tcpudp | ||
|
||
tcp: | ||
<<: &shared | ||
$type: shadowsocks | ||
endpoint: ss.example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
prefix: "POST " | ||
|
||
udp: *shared | ||
``` | ||
|
||
It's now possible to compose strategies and do multi-hops: | ||
|
||
```yaml | ||
transport: | ||
$type: tcpudp | ||
|
||
tcp: | ||
$type: shadowsocks | ||
|
||
endpoint: | ||
$type: dial | ||
address: exit.example.com:4321 | ||
dialer: | ||
$type: shadowsocks | ||
address: entry.example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: ENTRY_SECRET | ||
|
||
cipher: chacha20-ietf-poly1305 | ||
secret: EXIT_SECRET | ||
|
||
udp: *shared | ||
``` | ||
|
||
## Tunnels | ||
|
||
### <a id=TunnelConfig></a>TunnelConfig | ||
|
||
Tunnel is the top-level object in the Outline configuration returned by [Dynamic Access Keys](https://www.reddit.com/r/outlinevpn/wiki/index/dynamic_access_keys/). It specifies how the VPN should be configured. | ||
|
||
**Format:** [ExplicitTunnelConfig](#ExplicitTunnelConfig) | [LegacyShadowsocksConfig](#LegacyShadowsocksConfig) | [LegacyShadowsocksURI](#LegacyShadowsocksURI) | ||
|
||
### <a id=ExplicitTunnelConfig></a>ExplicitTunnelConfig | ||
|
||
**Format:** _struct_ | ||
|
||
**Fields:** | ||
|
||
- `transport` ([TransportConfig](#TransportConfig)): the transport to use to exchange packages with the target destination | ||
- `error` (_struct_): information to communicate to the user in case of service error (e.g. key expired, quota exhausted) | ||
- `message` (_string_): user-friendly message to display to the user | ||
- `details` (_string_): message to display when the user opens the error details. Helpful for troubleshooting. | ||
|
||
Fields `error` and `transport` are mutually exclusive. | ||
|
||
Successful example: | ||
|
||
```yaml | ||
transport: | ||
$type: tcpudp | ||
tcp: | ||
... # Stream Dialer for TCP | ||
udp: | ||
... # Packet Listener for UDP | ||
``` | ||
|
||
Error example: | ||
|
||
```yaml | ||
error: | ||
message: Quota exceeded | ||
details: Used 100GB out of 100GB | ||
``` | ||
|
||
## Transports | ||
|
||
### <a id=TransportConfig></a>TransportConfig | ||
|
||
Specifies how packets should be exchanged with the target destination. | ||
|
||
**Format:** [Interface](#Interface) | ||
|
||
Supported Interface types: | ||
|
||
- `tcpudp`: [TCPUDPConfig](#TCPUDPConfig) | ||
|
||
### <a id=TCPUDPConfig></a>TCPUDPConfig | ||
|
||
TCPUDPConfig allows for setting separate TCP and UDP strategies. | ||
|
||
**Format:** _struct_ | ||
|
||
**Fields:** | ||
|
||
- `tcp` ([DialerConfig](#DialerConfig)): the Stream Dialer to use for TCP connections. | ||
- `udp` ([PacketListenerConfig](#PacketListenerConfig)): the Packet Listener to use for UDP packets. | ||
|
||
Example sending TCP and UDP to different endpoints: | ||
|
||
```yaml | ||
tcp: | ||
$type: shadowsocks | ||
endpoint: ss.example.com:80 | ||
<<: &cipher | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
prefix: "POST " | ||
|
||
udp: | ||
$type: shadowsocks | ||
endpoint: ss.example.com:53 | ||
<<: *cipher | ||
``` | ||
|
||
## Endpoints | ||
|
||
Endpoints establish connections to a fixed endpoint. It's preferable over Dialers since it allows for endpoint-specific optimizations. There are Stream and Packet Endpoints. | ||
|
||
### <a id=EndpointConfig></a>EndpointConfig | ||
|
||
**Format:** _string_ | [Interface](#Interface) | ||
|
||
The _string_ Endpoint is the host:port address of the desired endpoint. The connection is established using the default Dialer. | ||
|
||
Supported Interface types for Stream and Packet Endpoints: | ||
|
||
- `dial`: [DialEndpointConfig](#DialEndpointConfig) | ||
<!-- - `shadowsocks`: [ShadowsocksConfig](#ShadowsocksConfig) --> | ||
<!-- - `websocket`: [WebsocketEndpointConfig](#WebsocketEndpointConfig) --> | ||
|
||
### <a id=DialEndpointConfig></a>DialEndpointConfig | ||
|
||
Establishes connections by dialing a fixed address. It can take a dialer, which allows for composition of strategies. | ||
|
||
**Format:** _struct_ | ||
|
||
**Fields:** | ||
|
||
- `address` (_string_): the endpoint address to dial | ||
- `dialer` ([DialerConfig](#dialers)): the dialer to use to dial the address | ||
|
||
## Dialers | ||
|
||
Dialers establishes connections given an endpoint address. There are Stream and Packet Dialers. | ||
|
||
### <a id=DialerConfig></a>DialerConfig | ||
|
||
**Format:** _null_ | [Interface](#Interface) | ||
|
||
The _null_ (absent) Dialer means the default Dialer, which uses direct TCP connections for Stream and direct UDP connections for Packets. | ||
|
||
Supported Interface types for Stream and Packer Dialers: | ||
|
||
- `shadowsocks`: [ShadowsocksConfig](#ShadowsocksConfig) | ||
|
||
## Packet Listeners | ||
|
||
A Packet Listener establishes an unbounded packet connection that can be used to send packets to multiple destinations. | ||
|
||
### <a id=PacketListenerConfig></a>PacketListenerConfig | ||
|
||
**Format:** _null_ | [Interface](#Interface) | ||
|
||
The _null_ (absent) Packet Listener means the default Packet Listener, which is a UDP Packet Listener. | ||
|
||
Supported Interface types: | ||
|
||
- `shadowsocks`: [ShadowsocksPacketListenerConfig](#ShadowsocksConfig) | ||
|
||
## Strategies | ||
|
||
### Shadowsocks | ||
|
||
#### <a id=LegacyShadowsocksConfig></a>LegacyShadowsocksConfig | ||
|
||
LegacyShadowsocksConfig represents a Tunnel that uses Shadowsocks as the transport. It implements the legacy format for backwards-compatibility. | ||
|
||
**Format:** _struct_ | ||
|
||
**Fields:** | ||
|
||
- `server` (_string_): the host to connect to | ||
- `server_port` (_number_): the port number to connect to | ||
- `method` (_string_): the [AEAD cipher](https://shadowsocks.org/doc/aead.html#aead-ciphers) to use | ||
- `password` (_string_): used to generate the encryption key | ||
- `prefix` (_string_): the [prefix disguise](https://www.reddit.com/r/outlinevpn/wiki/index/prefixing/) to use. Currently only supported on stream connections. | ||
|
||
Example: | ||
|
||
```yaml | ||
server: example.com | ||
server_port: 4321 | ||
method: chacha20-ietf-poly1305 | ||
password: SECRET | ||
prefix: "POST " | ||
``` | ||
|
||
#### <a id=LegacyShadowsocksURI></a>LegacyShadowsocksURI | ||
|
||
LegacyShadowsocksURI represents a Tunnel that uses Shadowsocks as the transport. It implements the legacy URL format for backwards-compatibility. | ||
|
||
**Format:** _string_ | ||
|
||
See [Legacy Shadowsocks URI Format](https://shadowsocks.org/doc/configs.html#uri-and-qr-code) and [SIP002 URI scheme](https://shadowsocks.org/doc/sip002.html). We don't support plugins. | ||
|
||
Example: | ||
|
||
```yaml | ||
ss://chacha20-ietf-poly1305:[email protected]:443?prefix=POST%20 | ||
``` | ||
|
||
#### <a id=ShadowsocksConfig></a>ShadowsocksConfig | ||
|
||
ShadowsocksConfig can represent a Stream or Packet Dialers, as well as a Packet Listener that uses Shadowsocks. | ||
|
||
**Format:** _struct_ | ||
|
||
**Fields:** | ||
|
||
- `endpoint` ([EndpointConfig](#EndpointConfig)): the Shadowsocks endpoint to connect to | ||
- `cipher` (_string_): the [AEAD cipher](https://shadowsocks.org/doc/aead.html#aead-ciphers) to use | ||
- `secret` (_string_): used to generate the encryption key | ||
- `prefix` (_string_, optional): the [prefix disguise](https://www.reddit.com/r/outlinevpn/wiki/index/prefixing/) to use. Currently only supported on stream connections. | ||
|
||
Example: | ||
|
||
```yaml | ||
endpoint: example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
prefix: "POST " | ||
``` | ||
|
||
## Meta Definitions | ||
|
||
### <a id=Interface></a>Interface | ||
|
||
Interfaces allow for choosing one of multiple implementations. It uses the `$type` field to specify the type that config represents. | ||
|
||
Example: | ||
|
||
```yaml | ||
$type: shadowsocks | ||
endpoint: example.com:4321 | ||
cipher: chacha20-ietf-poly1305 | ||
secret: SECRET | ||
``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍