update docs

This commit is contained in:
Page Fault
2020-06-29 04:50:17 +00:00
parent 9ece8d8ff1
commit a485836d6c
15 changed files with 105 additions and 146 deletions
+13 -16
View File
@@ -12,7 +12,7 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/p4gefau1t/trojan-go)](https://goreportcard.com/report/github.com/p4gefau1t/trojan-go)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/p4gefau1t/trojan-go/pulls)
使用Go实现的完整Trojan代理,与Trojan协议以及Trojan-GFW版本的配置文件格式兼容。安全,高效,轻巧,易用。
使用Go实现的完整Trojan代理,与Trojan协议以及Trojan版本的配置文件格式兼容。安全,高效,轻巧,易用。
支持使用[多路复用](#多路复用)提升并发性能,使用[路由模块](#路由模块)实现国内直连。
@@ -28,7 +28,7 @@
## **下面的说明为简单介绍,完整配置教程和配置介绍参见[Trojan-Go文档](https://p4gefau1t.github.io/trojan-go)。**
Trojan-Go支持并且兼容Trojan-GFW的绝大多数功能,包括但不限于:
Trojan-Go支持并且兼容原版Trojan的绝大多数功能,包括但不限于:
- TLS/SSL隧道传输
@@ -70,7 +70,7 @@ Trojan-Go支持并且兼容Trojan-GFW的绝大多数功能,包括但不限于
## 图形界面客户端
Trojan-Go服务端可以兼容所有Trojan-GFW的客户端,如IgniterShadowRocket等。
Trojan-Go服务端可以兼容所有Trojan客户端,如IgniterShadowRocket等。
下面是支持Trojan-Go扩展特性(Websocket/Mux等)的客户端。
@@ -122,12 +122,12 @@ Trojan-Go服务端可以兼容所有Trojan-GFW的客户端,如IgniterShadow
p4gefau1t/trojan-go \
/path/in/container/config.json
```
镜像的latest标签对应master分支,nightly标签对应dev分支。
## 特性
一般情况下,Trojan-Go和Trojan-GFW版本是互相兼容的。但是一旦使用下面介绍的扩展特性(如多路复用,Websocket等),则无法与之兼容。
一般情况下,Trojan-Go和Trojan是互相兼容的。但是一旦使用下面介绍的扩展特性(如多路复用,Websocket等),则无法与之兼容。
### 移植性
@@ -147,7 +147,7 @@ CGO_ENABLE=0 GOOS=linux GOARCH=mips go build -tags "client" -ldflags "-s -w"
### 易用
配置文件格式与Trojan-GFW兼容,但做了大幅简化,未指定的字段会被赋给一个默认值。你可以更方便地部署你的服务器和客户端。下面是一个简单的例子,完整的配置文件可以参见[这里](https://p4gefau1t.github.io/trojan-go)。
配置文件格式与Trojan兼容,但做了大幅简化,未指定的字段会被赋给一个默认值。你可以更方便地部署你的服务器和客户端。下面是一个简单的例子,完整的配置文件可以参见[这里](https://p4gefau1t.github.io/trojan-go)。
服务器配置文件
@@ -166,7 +166,7 @@ server.json
"ssl": {
"cert": "your_cert.crt",
"key": "your_key.key",
"sni": "www.your_awesome_domain_name.com"
"sni": "www.your-awesome-domain-name.com"
}
}
```
@@ -180,7 +180,7 @@ client.json
"run_type": "client",
"local_addr": "127.0.0.1",
"local_port": 1080,
"remote_addr": "www.your_awesome_domain_name.com",
"remote_addr": "www.your-awesome-domain-name.com",
"remote_port": 443,
"password": [
"your_awesome_password"
@@ -196,7 +196,7 @@ client.yaml
run-type: client
local-addr: 127.0.0.1
local-port: 1080
remote-addr: www.your_awesome_domain_name.com
remote-addr: www.your-awesome-domain_name.com
remote-port: 443
password:
- your_awesome_password
@@ -214,8 +214,8 @@ Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流
...
"websocket": {
"enabled": true,
"path": "/im_a_url_path",
"hostname": "www.your_awesome_domain_name.com"
"path": "/your-websocket-path",
"hostname": "www.your-awesome-domain_name.com"
}
```
@@ -223,13 +223,12 @@ Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流
可以省略```hostname```, 但是服务器和客户端的```path```必须一致。服务器开启Websocket支持后可以同时支持Websocket和一般Trojan流量,未配置Websocket选项的客户端依然可以正常使用。
由于Trojan-GFW版本并不支持Websocket,因此,虽然开启了Websocket支持的Trojan-Go服务端可以兼容所有客户端,但是如果要使用Websocket承载流量,请确保双方都使用Trojan-Go。
由于Trojan并不支持Websocket,因此,虽然开启了Websocket支持的Trojan-Go服务端可以兼容所有客户端,但是如果要使用Websocket承载流量,请确保双方都使用Trojan-Go。
<a name="多路复用"></a>
### 多路复用
在很差的网络条件下,一次TLS握手可能会花费很多时间。
Trojan-Go支持多路复用(基于[smux](https://github.com/xtaci/smux))。通过一个TLS隧道连接承载多个TCP连接的方式,减少TCP和TLS握手带来的延迟,以期提升高并发情景下的性能。
@@ -296,7 +295,7 @@ Trojan-Go允许对Trojan协议基于Shadowsocks AEAD进行加密,以保证Webs
...
"shadowsocks": {
"enabled": true,
"password": "my_password"
"password": "my-password"
}
```
@@ -375,8 +374,6 @@ CGO_ENABLE=0 GOOS=linux GOARCH=arm go build -tags "full"
[smux](https://github.com/xtaci/smux)
[lego](https://github.com/go-acme/lego)
[go-tproxy](https://github.com/LiamHaworth/go-tproxy)
[utls](https://github.com/refraction-networking/utls)
+1 -1
View File
@@ -4,4 +4,4 @@ draft: false
weight: 30
---
这一部分内容将介绍更复杂的Trojan-Go配置方法。对于Trojan-GFW版本不支持和不兼容的功能,将在小节中明确标明。
这一部分内容将介绍更复杂的Trojan-Go配置方法。对于Trojan原版不兼容的特性,将在小节中明确标明。
+1 -1
View File
@@ -4,7 +4,7 @@ draft: false
weight: 8
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan协议本身无加密,其安全性依赖于下层的TLS。在一般情况下,TLS安全性很好,并不需要再次加密Trojan流量。但是,某些场景下,你可能无法保证TLS隧道的安全性:
+1 -1
View File
@@ -4,7 +4,7 @@ draft: false
weight: 10
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go使用gRPC提供了一组APIAPI支持以下功能:
@@ -4,7 +4,7 @@ draft: false
weight: 8
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go允许高级用户自定义协议栈。在自定义模式下,Trojan-Go将放弃对协议栈的控制,允许用户操作底层协议栈组合。例如
@@ -26,22 +26,22 @@ Trojan-Go将所有协议抽象为隧道,每个隧道可能提供客户端,
下面是Trojan-Go支持的隧道和他们的属性:
|隧道 | 需要下层提供流 | 需要下层提供包 | 向上层提供流 | 向上层提供包 | 可以作为入站 | 可以作为出站 |
|-------------------|--------------|-------------|-------------|------------|------------|------------|
|transport | n | n | y | y | y | y |
|dokodemo | n | n | y | y | y | n |
|tproxy | n | n | y | y | y | n |
|tls | y | n | y | n | y | y |
|trojan | y | n | y | y | y | y |
|mux | y | n | y | n | y | y |
|simplesocks | y | n | y | y | y | y |
|shadowsocks | y | n | y | n | y | y |
|websocket | y | n | y | n | y | y |
|freedom | n | n | y | y | n | y |
|socks | y | y | y | y | y | n |
|http | y | n | y | n | y | n |
|router | y | y | y | y | n | y |
|adapter | n | n | y | y | y | n |
| 隧道 | 需要下层提供流 | 需要下层提供包 | 向上层提供流 | 向上层提供包 | 可以作为入站 | 可以作为出站 |
| ----------- | -------------- | -------------- | ------------ | ------------ | ------------ | ------------ |
| transport | n | n | y | y | y | y |
| dokodemo | n | n | y | y | y | n |
| tproxy | n | n | y | y | y | n |
| tls | y | n | y | n | y | y |
| trojan | y | n | y | y | y | y |
| mux | y | n | y | n | y | y |
| simplesocks | y | n | y | y | y | y |
| shadowsocks | y | n | y | n | y | y |
| websocket | y | n | y | n | y | y |
| freedom | n | n | y | y | n | y |
| socks | y | y | y | y | y | n |
| http | y | n | y | n | y | n |
| router | y | y | y | y | n | y |
| adapter | n | n | y | y | y | n |
自定义协议栈的工作方式是,定义树/链上节点并分别它们起名(tag)并添加配置,然后使用tag组成的有向路径,描述这棵树/链。例如,对于一个典型的Trojan-Go服务器,可以如此描述:
+1 -1
View File
@@ -4,7 +4,7 @@ draft: false
weight: 1
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go支持使用多路复用提升网络并发性能。
+49
View File
@@ -0,0 +1,49 @@
---
title: "透明代理"
draft: false
weight: 11
---
### 注意,Trojan不完全支持这个特性(UDP)
Trojan-Go支持基于tproxy的透明TCP/UDP代理。
要开启透明代理模式,将一份正确的客户端配置(配置方式参见基本配置部分)其中的```run_type```修改为```nat```,并按照需求修改本地监听端口即可。
之后需要添加iptables规则。这里假定你的网关具有两个网卡,下面这份配置将其中一个网卡(局域网)的入站包转交给Trojan-Go,由Trojan-Go通过隧道,通过另一个网卡(互联网)发送到远端Trojan-Go服务器。你需要将下面的```$SERVER_IP``````$TROJAN_GO_PORT``````$INTERFACE```替换为自己的配置。
```shell
# 新建TROJAN_GO链
iptables -t mangle -N TROJAN_GO
# 绕过Trojan-Go服务器地址
iptables -t mangle -A TROJAN_GO -d $SERVER_IP -j RETURN
# 绕过私有地址
iptables -t mangle -A TROJAN_GO -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A TROJAN_GO -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A TROJAN_GO -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A TROJAN_GO -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A TROJAN_GO -d 240.0.0.0/4 -j RETURN
# 未命中上文的规则的包,打上标记
iptables -t mangle -A TROJAN_GO -j TPROXY -p tcp --on-port $TROJAN_GO_PORT --tproxy-mark 0x01/0x01
iptables -t mangle -A TROJAN_GO -j TPROXY -p udp --on-port $TROJAN_GO_PORT --tproxy-mark 0x01/0x01
# 从$INTERFACE网卡流入的所有TCP/UDP包,跳转TROJAN_GO链
iptables -t mangle -A PREROUTING -p tcp -i $INTERFACE -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i $INTERFACE -j TROJAN_GO
# 添加路由,打上标记的包重新进入本地回环
ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100
```
配置完成后以root权限启动Trojan-Go客户端:
```shell
sudo trojan-go
```
+1 -1
View File
@@ -4,7 +4,7 @@ draft: false
weight: 7
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go支持可插拔的传输层。原则上,Trojan-Go可以使用任何有TCP隧道功能的软件作为传输层,如v2ray、shadowsocks、kcp等。同时,Trojan-Go也兼容Shadowsocks的SIP003插件标准,如GoQuietv2ray-plugin等。也可以使用Tor的传输层插件,如obfs4,meek等。
+1 -1
View File
@@ -4,7 +4,7 @@ draft: false
weight: 3
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go内建的路由模块可以帮助你实现国内直连,即客户端对于国内网站不经过代理,直接连接。
+2 -2
View File
@@ -4,7 +4,7 @@ draft: false
weight: 2
---
### 注意,Trojan-GFW版本不支持这个特性
### 注意,Trojan不支持这个特性
Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流量中转成为可能。
@@ -40,7 +40,7 @@ Trojan协议本身不带加密,安全性依赖外层的TLS。但流量一旦
],
"websocket": {
"enabled": true,
"path": "/imaurlpath",
"path": "/your-websocket-path",
"hostname": "www.your_awesome_domain_name.com"
},
"shadowsocks": {
+16 -33
View File
@@ -34,8 +34,6 @@ weight: 30
"log_level": 1,
"log_file": "",
"password": [],
"buffer_size": 32,
"dns": [],
"disable_http_check": false,
"udp_timeout": 10,
"ssl": {
@@ -143,17 +141,17 @@ weight: 30
```log_level```指定日志等级。等级越高,输出的信息越少。合法的值有
- 0输出Debug以上日志(所有日志)
- 0 输出Debug以上日志(所有日志)
- 1输出Info及以上日志
- 1 输出Info及以上日志
- 2输出Warning及以上日志
- 2 输出Warning及以上日志
- 3输出Error及以上日志
- 3 输出Error及以上日志
- 4输出Fatal及以上日志
- 4 输出Fatal及以上日志
- 5完全不输出日志
- 5 完全不输出日志
```log_file```指定日志输出文件路径。如果未指定则使用标准输出。
@@ -161,21 +159,7 @@ weight: 30
```buffer_size```为单个连接缓冲区大小,单位KiB,默认32KiB。适当提升这个数值可以提升网络吞吐量和效率,但是也会增加内存消耗。对于路由器等嵌入式系统,建议根据实际情况,适当减小该数值。
```dns```指定trojan-go使用的DNS服务器列表,如果不指定则使用主机默认DNS。如果指定了服务器,按照列表顺序依次查询,支持UDP/TCP/DOT类型的DNS,查询结果会被缓存五分钟。使用URL格式描述服务器,例如
- "udp://1.1.1.1",基于UDP的DNS服务器,默认53端口
- "udp://1.1.1.1:53",与上一项等价
- "1.1.1.1",与上一项等价
- "tcp://1.1.1.1",基于TCP的DNS服务器,默认53端口
- "dot://1.1.1.1",基于DOT(DNS Over TLS)的DNS服务器,默认853端口
使用DOT可以防止DNS请求泄露,但由于TLS的握手耗费更多时间,查询速度也会有一定的下降,请自行斟酌性能和安全性的平衡。
```disable_http_check```是否禁用HTTP可用性检查。
```disable_http_check```是否禁用HTTP伪装服务器可用性检查。
```udp_timeout``` UDP会话超时时间。
@@ -189,15 +173,7 @@ weight: 30
```sni```指的是TLS客户端请求中的服务器名字段,一般和证书的Common Name相同。如果你使用let'sencrypt等机构签发的证书,这里填入你的域名。如果这一项未填,将使用```remote_addr```填充。你应当指定一个有效的SNI(和远端证书CN一致),否则客户端可能无法验证远端证书有效性从而无法连接。
```alpn```为TLS的应用层协议协商指定协议。在TLS Client/Server Hello中传输,协商应用层使用的协议,仅用作指纹伪造,并无实际作用。**如果使用了CDN,错误的alpn字段可能导致与CDN协商得到错误的应用层协议**。
```prefer_server_cipher```客户端是否偏好选择服务端在协商中提供的密码学套件。
```cipher```TLS使用的密码学套件。```cipher13``字段与此字段合并。只有在你明确知道自己在做什么的情况下,才应该去填写此项以修改trojan-go使用的TLS密码学套件。**正常情况下,你应该将其留空或者不填**,trojan-go会根据当前硬件平台以及远端的情况,自动选择最合适的加密算法以提升性能和安全性。如果需要填写,密码学套件名用分号(":")分隔,按优先顺序排列。Go的TLS库中弃用了TLS1.2中部分不安全的密码学套件,并完全支持TLS1.3。默认情况下,trojan-go将优先使用更安全的TLS1.3。
```curves```指定TLS在ECDHE中偏好使用的椭圆曲线。只有你明确知道自己在做什么的情况下,才应该填写此项。曲线名称用分号(":")分隔,按优先顺序排列。
```fingerprint```用于指定TLS Client Hello指纹伪造类型,以抵抗GFW对于TLS Client Hello指纹的特征识别和阻断。trojan-go使用[utls](https://github.com/refraction-networking/utls)进行指纹伪造,默认伪造Firefox的指纹。合法的值有
```fingerprint```用于指定客户端TLS Client Hello指纹伪造类型,以抵抗GFW对于TLS Client Hello指纹的特征识别和阻断。trojan-go使用[utls](https://github.com/refraction-networking/utls)进行指纹伪造,默认伪造Firefox的指纹。合法的值有
- "",不使用指纹伪造
@@ -207,7 +183,14 @@ weight: 30
- "ios",伪造iOS指纹
一旦指纹的值被设置,```cipher``````curves``````alpn``````session_ticket```等有可能影响指纹的字段将使用该指纹的特定设置覆写。
一旦指纹的值被设置,客户端的```cipher``````curves``````alpn``````session_ticket```等有可能影响指纹的字段将使用该指纹的特定设置覆写。
```alpn```为TLS的应用层协议协商指定协议。在TLS Client/Server Hello中传输,协商应用层使用的协议,仅用作指纹伪造,并无实际作用。**如果使用了CDN,错误的alpn字段可能导致与CDN协商得到错误的应用层协议**。
```prefer_server_cipher```客户端是否偏好选择服务端在协商中提供的密码学套件。
```cipher```TLS使用的密码学套件。```cipher13``字段与此字段合并。只有在你明确知道自己在做什么的情况下,才应该去填写此项以修改trojan-go使用的TLS密码学套件。**正常情况下,你应该将其留空或者不填**,trojan-go会根据当前硬件平台以及远端的情况,自动选择最合适的加密算法以提升性能和安全性。如果需要填写,密码学套件名用分号(":")分隔,按优先顺序排列。Go的TLS库中弃用了TLS1.2中部分不安全的密码学套件,并完全支持TLS1.3。默认情况下,trojan-go将优先使用更安全的TLS1.3。
```curves```指定TLS在ECDHE中偏好使用的椭圆曲线。只有你明确知道自己在做什么的情况下,才应该填写此项。曲线名称用分号(":")分隔,按优先顺序排列。
```plain_http_response```指服务端TLS握手失败时,明文发送的原始数据(原始TCP数据)。这个字段填入该文件路径。推荐使用```fallback_port```而不是该字段。
-70
View File
@@ -2,15 +2,10 @@ package freedom
import (
"context"
"crypto/tls"
"net"
"net/url"
"strconv"
"time"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/config"
"github.com/p4gefau1t/trojan-go/log"
"github.com/p4gefau1t/trojan-go/tunnel"
"golang.org/x/net/proxy"
)
@@ -19,7 +14,6 @@ type Client struct {
preferIPv4 bool
noDelay bool
keepAlive bool
dns []string
ctx context.Context
cancel context.CancelFunc
forwardProxy bool
@@ -28,69 +22,6 @@ type Client struct {
password string
}
func (c *Client) resolveIP(addr *tunnel.Address) ([]net.IPAddr, error) {
for _, s := range c.dns {
var dnsAddr string
var dnsHost, dnsType string
var err error
dnsURL, err := url.Parse(s)
if err != nil || dnsURL.Scheme == "" {
dnsType = "udp"
dnsAddr = s
} else {
dnsType = dnsURL.Scheme
dnsAddr = dnsURL.Host
}
dnsHost, tmp, err := net.SplitHostPort(dnsAddr)
dnsPort, err := strconv.ParseInt(tmp, 10, 32)
common.Must(err)
if err != nil {
dnsHost = dnsAddr
switch dnsType {
case "dot":
dnsPort = 853
case "tcp", "udp":
dnsPort = 53
}
}
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
dnsAddress := tunnel.NewAddressFromHostPort("tcp", dnsHost, int(dnsPort))
switch dnsType {
case "udp", "tcp":
d := net.Dialer{
Timeout: time.Second * 5,
}
conn, err := d.DialContext(ctx, dnsType, dnsAddress.String())
if err != nil {
return nil, err
}
return conn, nil
case "dot":
tlsConn, err := tls.Dial("tcp", dnsAddress.String(), nil)
if err != nil {
return nil, err
}
return tlsConn, nil
}
return nil, common.NewError("invalid dns type:" + dnsType)
},
}
ip, err := resolver.LookupIPAddr(c.ctx, addr.String())
if err != nil {
log.Error(err)
continue
}
return ip, nil
}
return nil, common.NewError("address not found")
}
func (c *Client) DialConn(addr *tunnel.Address, t tunnel.Tunnel) (tunnel.Conn, error) {
network := "tcp"
if c.preferIPv4 {
@@ -159,7 +90,6 @@ func NewClient(ctx context.Context, _ tunnel.Client) (*Client, error) {
return &Client{
ctx: ctx,
cancel: cancel,
dns: cfg.DNS,
noDelay: cfg.TCP.NoDelay,
keepAlive: cfg.TCP.KeepAlive,
preferIPv4: cfg.TCP.PreferIPV4,
-1
View File
@@ -5,7 +5,6 @@ import "github.com/p4gefau1t/trojan-go/config"
type Config struct {
LocalHost string `json:"local_addr" yaml:"local-addr"`
LocalPort int `json:"local_port" yaml:"local-port"`
DNS []string `json:"dns" yaml:"dns"`
TCP TCPConfig `json:"tcp" yaml:"tcp"`
ForwardProxy ForwardProxyConfig `json:"forward_proxy" yaml:"forward-proxy"`
}
+1 -1
View File
@@ -235,7 +235,7 @@ func GetClientHelloSpec(name string, websocket bool) (*ClientHelloSpec, error) {
func ParseCipher(s []string) []uint16 {
all := tls.CipherSuites()
result := []uint16{}
var result []uint16
for _, p := range s {
found := true
for _, q := range all {
+1
View File
@@ -278,6 +278,7 @@ func NewServer(ctx context.Context, underlay tunnel.Server) (*Server, error) {
if err != nil {
return nil, common.NewError("failed to open key log file")
}
log.Warn("tls key logging enabled")
server.keyLogger = file
}