docs(*): update architecture and middleware

This commit is contained in:
Micooz 2017-03-01 14:10:28 +08:00
parent 53ca92178c
commit 0f5e6f1fc5
6 changed files with 109 additions and 224 deletions

@ -23,7 +23,6 @@ And [ShadowsocksR](https://github.com/shadowsocksr/shadowsocksr/tree/manyuser).
* [Principle](docs/principle)
* [Architecture](docs/architecture)
* [Middleware](docs/middleware)
* [Preset](docs/preset)
## Features

@ -7,5 +7,3 @@
3. [Architecture](architecture)
4. [Middleware](middleware)
5. [Preset](preset)

@ -54,14 +54,13 @@ there are several built-in presets already:
* protocol/*: implement for ProtocolMiddleware
* obfs/*: implement for ObfsMiddleware
For more detail document of each presets, please refer to [docs/preset](../docs/preset).
### Custom Preset
A typical preset must implement four methods of IPreset interface:
```js
export class CustomPreset extends IPreset {
// custom.js
export default class CustomPreset extends IPreset {
clientOut(/* {buffer, next, broadcast} */) {
// next(buf); for async
@ -114,7 +113,8 @@ Once a method broadcast, all other middlewares will receive the action in
**onNotified(action)** immediately:
```js
export class CustomPreset extends IPreset {
// custom.js
export default class CustomPreset extends IPreset {
/**
* how to deal with the action, return false to ignore
@ -134,7 +134,8 @@ export class CustomPreset extends IPreset {
There are two hooks avaialble:
```js
export class CustomPreset extends IPreset {
// custom.js
export default class CustomPreset extends IPreset {
beforeOut({buffer/* , next, broadcast */}) {
return buffer;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@ -1,42 +1,121 @@
# Plugins
# Protocol Stack
Blinksocks supports plugin system, this makes blinksocks more flexible and security.
The protocol stack of blinksocks is middleware based and ultra **flexible**.
There are two kinds of plugins in the blinksocks:
Like TCP/IP, you can define your own protocol in each layer.
Application data are processed **step by step** from the lowest layer to the top.
* Protocol Plugin
* Obfuscation Plugin
Middlewares here act as a specific layers in the stack.
## Procedure
We have four kind of middlewares currently, however the classification among middlewares **is not fixed**.
You can add or subtract some middlewares on demand.
Application data <--> `Protocol Plugin` <--> `Obfuscation Plugin` <--> Data Frame(transfer on the network).
A typical protocol stack is defined as following(**just for example**):
## Protocol Plugin
```
# TCP handshake
Protocol plugin combines application data with additional headers, forming particular frame.
+-----------+-------------------------------------------------------+
| HEADER | PAYLOAD |
+-----------+-------------------------------------------------------+ <-------+
| Variable | Variable | |
+-----------+-------------------------------------------------------+ |
ObfsMiddleware(--obfs="http")
+-----+-------------------------------------------------+ |
| LEN | PAYLOAD | |
+-----+-------------------------------------------------+ <-------+
| 2 | Variable | |
+-----+-------------------------------------------------+ |
ProtocolMiddleware(--protocol="basic")
+--------+----------------------------------------+ |
| IV | PAYLOAD | |
+--------+----------------------------------------+ <-------+
| 16 | Variable | |
+--------+----------------------------------------+ |
|
CryptoMiddleware(--crypto="openssl")
+------+----------+----------+-----------+ |
| ATYP | DST.ADDR | DST.PORT | PAYLOAD | |
+------+----------+----------+-----------+ <-------+
| 1 | Variable | 2 | Variable | |
+------+----------+----------+-----------+ |
FrameMiddleware(--frame="origin")
+-----------+ |
| DATA | |
Application Data -----> +-----------+ --------+
| Variable |
+-----------+
There are several built-in protocol plugins:
# TCP chunk
* `none`
+-----------------+
| PAYLOAD |
+-----------------+ <-------+
| Variable | |
+-----------------+ |
ObfsMiddleware(--obfs="http")
+-----+-----------+ |
| LEN | PAYLOAD | |
+-----+-----------+ <-------+
| 2 | Variable | |
+-----+-----------+ |
ProtocolMiddleware(--protocol="basic")
+-----------+ |
| PAYLOAD | |
+-----------+ <-------+
| Variable | |
+-----------+ |
|
CryptoMiddleware(--crypto="openssl")
+-----------+ |
| PAYLOAD | |
+-----------+ <-------+
| Variable | |
+-----------+ |
FrameMiddleware(--frame="origin")
+-----------+ |
| DATA | |
Application Data -----> +-----------+ --------+
| Variable |
+-----------+
```
Do not add any headers to the application data.
As you can see, you start from **Application Data**, custom middleware behaviour in each preset and
send them out.
* `basic`
Ordinarily, `DST.ADDR` and `DST.PORT` is required to be sent to server(like "origin" preset),
otherwise server cannot figure out where to send data to.
Use AES to ensure confidentiality.
Blinksocks will pass **target address** to the FrameMiddleware once a connection between application
and blinksocks client was constructed, so you can obtain that address in your frame preset.
* `aead-gcm`(**Recommended**)
```js
// core/socket.js
this._pipe.setMiddlewares(MIDDLEWARE_DIRECTION_UPWARD, [
createMiddleware(MIDDLEWARE_TYPE_FRAME, [this._targetAddress]),
createMiddleware(MIDDLEWARE_TYPE_CRYPTO),
createMiddleware(MIDDLEWARE_TYPE_PROTOCOL),
createMiddleware(MIDDLEWARE_TYPE_OBFS),
]);
```
Use AES and HMAC to ensure confidentiality, integrity and authentication.
`md5` and `sha1` are algorithms applied for HMAC.
```js
// preset/frame/origin.js
export default class OriginFrame extends IPreset {
## Obfuscation Plugin
_targetAddress = null; // client use only
After protocol plugin created data frames, cheat plugin wrap the output of
protocol plugins, disguising a particular protocol such as HTTP or TLS packages,
rather than an unknown protocol to attackers.
constructor(address) {
super();
this._targetAddress = address;
}
There are several built-in Obfuscation plugins:
// ...
* `none`, do not wrap output data of protocol plugin
* `http`, make the handshake packet looks like a http GET/POST request
}
```
# Presets
For more document about built-in presets, please check out each implementation
files in [src/presets](../../src/presets).

@ -1,192 +0,0 @@
# Protocol
The protocol of blinksocks is similar to [SOCKS5](https://www.ietf.org/rfc/rfc1928.txt), but simpler.
```
TCP handshake (AEAD-MIXED)
(Optional)
+-----------+-----------------------------------------------------------------------------------------+
| obfs.DATA | PAYLOAD |
+-----------+-----------------------------------------------------------------------------------------+ <-------+
| Variable | Variable | |
+-----------+-----------------------------------------------------------------------------------------+ |
ObfsMiddleware(*)
+---------+-----+--------+-----------+----------------------------------------+-----------+ |
| NONCE | LEN | IV | HMAC-MD5 | PAYLOAD | HMAC-MD5 | |
+---------+-----+--------+-----------+----------------------------------------+-----------+ <-------+
| 12 | 2 | 16 | 16 | Variable | 16 | |
+---------+-----+--------+-----------+----------------------------------------+-----------+ |
|<---- (AES-128-CBC) --->| ProtocolMiddleware(*)
+----------------------------------------+ |
| PAYLOAD | |
+----------------------------------------+ <-------------------+
| Variable | |
+----------------------------------------+ |
|<------ (user specified cipher) ------->| |
CryptoMiddleware
+------+----------+----------+-----------+ |
| ATYP | DST.ADDR | DST.PORT | PAYLOAD | |
+------+----------+----------+-----------+ <-------------------+
| 1 | Variable | 2 | Variable | |
+------+----------+----------+-----------+ |
FrameMiddleware
+-----------+ |
| DATA | |
Application Data -----> +-----------+ --------------------+
| Variable |
+-----------+
TCP handshake (BASIC)
(Optional)
+-----------+-------------------------------------------------------+
| obfs.DATA | PAYLOAD |
+-----------+-------------------------------------------------------+ <-------+
| Variable | Variable | |
+-----------+-------------------------------------------------------+ |
ObfsMiddleware(*)
+-----+--------+----------------------------------------+ |
| LEN | IV | PAYLOAD | |
+-----+--------+----------------------------------------+ <-------+
| 2 | 16 | Variable | |
+-----+--------+----------------------------------------+ |
|<--cipherA--->| ProtocolMiddleware(*)
+----------------------------------------+ |
| PAYLOAD | |
+----------------------------------------+ <-------+
| Variable | |
+----------------------------------------+ |
|<------ (user specified cipherA) ------>| |
CryptoMiddleware
+------+----------+----------+-----------+ |
| ATYP | DST.ADDR | DST.PORT | PAYLOAD | |
+------+----------+----------+-----------+ <-------+
| 1 | Variable | 2 | Variable | |
+------+----------+----------+-----------+ |
FrameMiddleware
+-----------+ |
| DATA | |
Application Data -----> +-----------+ --------+
| Variable |
+-----------+
TCP chunk:
(Optional)
+-----------+---------------------+
| obfs.DATA | obfs.PAYLOAD |
+-----------+---------------------+
| Variable | Variable |
+-----------+---------------------+
||
ObfsMiddleware
||
+---------------------+
| crypto.DATA |
+---------------------+
| Variable |
+---------------------+
||
CryptoMiddleware
||
+---------------------+
| protocol.PAYLOAD |
+---------------------+
| Variable |
+---------------------+
||
ProtocolMiddleware
||
+---------------------+
| DATA |
+---------------------+
| Variable |
+---------------------+
```
## Requests
### Normal request
The blinksocks normal request is formed as follows:
```
+------+------+----------+----------+----------+
| LEN | ATYP | DST.ADDR | DST.PORT | DATA |
+------+------+----------+----------+----------+ = PAYLOAD
| 2 | 1 | Variable | 2 | Variable |
+------+------+----------+----------+----------+
```
Where:
* LEN the total length of the frame
* ATYP address type of following address
* IP V4 address: X'01'
* DOMAINNAME: X'03'
* IP V6 address: X'04'
* DST.ADDR desired destination address
* DST.PORT desired destination port in network octet order
* DATA the application data
### IV request
The **first packet** sent from client contains an IV base on the normal request frame:
```
+----------------+-------+
| PAYLOAD | IV |
+----------------+-------+
| Variable | Fixed |
+----------------+-------+
```
IV is optional and used for more secure encryption.
## Addressing
Follow [SOCKS5](https://www.ietf.org/rfc/rfc1928.txt).
## Replies
The blinksocks reply is formed as follows:
```
+----------+
| DATA |
+----------+
| Variable |
+----------+
```
Where:
* DATA the application data(encrypted)
# Encryption
All data transferred between client and server shall be encrypted using:
1. specified cipher - defined in config.json
2. a pre-shared key - defined in config.json
3. initialization vector(IV) - auto-generate
All of them are **optional**. `IV` is always generated for each connection
no matter it's **TCP** or **UDP**.
## Non-Encryption mode
For **development** or **special cases**, you can turn on non-encryption mode by setting
`cipher` option to an empty string.
## Supported Ciphers
The length of cipher key must be satisfied with IV Length:
| Cipher | Key Length | IV Length |
|:-------------|:------------|:------------|
| aes-128-ctr | 16 | 16 |
| aes-192-ctr | 24 | 16 |
| aes-256-ctr | 32 | 16 |
| aes-128-cfb | 16 | 16 |
| aes-192-cfb | 24 | 16 |
| aes-256-cfb | 32 | 16 |