From 669c67f38493e2ea42f3bf970b74f98afc5f249b Mon Sep 17 00:00:00 2001 From: Page Fault Date: Mon, 22 Jun 2020 11:59:29 +0000 Subject: [PATCH] fix typo, update docs --- .github/workflows/gh-pages.yml | 3 -- api/service/config.go | 15 ++++++++-- docs/content/advance/aead.md | 34 +++++++++++++++++++++ docs/content/advance/api.md | 2 +- docs/content/advance/mux.md | 23 +++++---------- docs/content/advance/plugin.md | 8 ++--- docs/content/advance/websocket.md | 49 +++++++------------------------ statistic/memory/memory_test.go | 30 +++++++++++++++++++ tunnel/tls/fingerprint/tls.go | 1 + tunnel/tproxy/server.go | 2 +- 10 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 docs/content/advance/aead.md create mode 100644 statistic/memory/memory_test.go diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f86322c..11d47c1 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -2,9 +2,6 @@ on: push: branches: - master - pull_request: - branches: - - master name: github-pages jobs: deploy: diff --git a/api/service/config.go b/api/service/config.go index 55cd4b9..5474416 100644 --- a/api/service/config.go +++ b/api/service/config.go @@ -4,10 +4,19 @@ import "github.com/p4gefau1t/trojan-go/config" const Name = "API_SERVICE" +type SSLConfig struct { + Enabled bool `json,yaml:"enabled"` + CertPath string `json:"cert" yaml:"cert"` + KeyPath string `json:"key" yaml:"key"` + ClientAuth bool `json:"client_auth" yaml:"client-auth"` + ClientCertPath []string `json:"client_cert" yaml:"client-cert"` +} + type APIConfig struct { - Enabled bool `json:"enabled" yaml:"enabled"` - APIHost string `json:"api_addr" yaml:"api-addr"` - APIPort int `json:"api_port" yaml:"api-port"` + Enabled bool `json:"enabled" yaml:"enabled"` + APIHost string `json:"api_addr" yaml:"api-addr"` + APIPort int `json:"api_port" yaml:"api-port"` + SSL SSLConfig `json,yaml:"ssl"` } type Config struct { diff --git a/docs/content/advance/aead.md b/docs/content/advance/aead.md new file mode 100644 index 0000000..1f18f16 --- /dev/null +++ b/docs/content/advance/aead.md @@ -0,0 +1,34 @@ +--- +title: "使用Shadowsocks AEAD进行二次加密" +draft: false +weight: 8 +--- + +### 注意,Trojan-GFW版本不支持这个特性 + +Trojan协议本身无加密,其安全性依赖于下层的TLS。在一般情况下,TLS安全性很好,并不需要再次加密Trojan流量。但是,某些场景下,你可能无法保证TLS隧道的安全性: + +- 你使用了Websocket,经过不可信的CDN进行中转(如国内CDN) + +- 你与服务器的连接遭到了GFW针对TLS的中间人攻击 + +- 你的证书失效,无法验证证书有效性 + +- 你使用了无法保证密码学安全的可插拔传输层 + +等等。 + +Trojan-Go支持使用Shadowsocks AEAD对Trojan-Go进行加密。其本质是在Trojan协议下方加上一层Shadowsocks AEAD加密。服务端和客户端必须同时开启,且密码和加密方式必须一致,否则无法进行通讯。 + +要开启AEAD加密,只需添加一个```shadowsocks```选项: + +```json +... +"shadowsocks": { + "enabled": true, + "method": "AES-128-GCM", + "password": "1234567890" +} +``` + +```method```如果省略,则默认使用AES-128-GCM。更多信息,参见“完整的配置文件”一节。 diff --git a/docs/content/advance/api.md b/docs/content/advance/api.md index 59e731c..e214179 100644 --- a/docs/content/advance/api.md +++ b/docs/content/advance/api.md @@ -1,7 +1,7 @@ --- title: "使用API动态管理用户" draft: false -weight: 7 +weight: 10 --- ### 注意,Trojan-GFW版本不支持这个特性 diff --git a/docs/content/advance/mux.md b/docs/content/advance/mux.md index 3a53e46..9376543 100644 --- a/docs/content/advance/mux.md +++ b/docs/content/advance/mux.md @@ -1,36 +1,27 @@ --- -title: "启用多路复用提升并发性能" +title: "启用多路复用提升网络并发性能" draft: false weight: 1 --- ### 注意,Trojan-GFW版本不支持这个特性 -Trojan-Go支持使用多路复用提升并发性能。 +Trojan-Go支持使用多路复用提升网络并发性能。 Trojan协议基于TLS。在一个TLS安全连接建立之前,连接双方需要进行密钥协商和交换等步骤确保后续通讯的安全性。这个过程即为TLS握手。 -目前GFW对于TLS握手有审查和干扰,同时由于出口网络拥塞的原因,普通的线路完成TLS握手通常需要将近一秒甚至更长的时间。这可能导致浏览网页和观看视频的延迟提高。 +目前GFW对于TLS握手存在审查和干扰,同时由于出口网络拥塞的原因,普通的线路完成TLS握手通常需要将近一秒甚至更长的时间。这可能导致浏览网页和观看视频的延迟提高。 Trojan-Go使用多路复用的方式解决这一问题。每个建立的TLS连接将承载多个TCP连接。当新的代理请求到来时,不需要和服务器握手发起一个新的TLS连接,而是尽可能重复使用已有的TLS连接。以此减少频繁TLS握手和TCP握手的带来的延迟。 -启用多路复用功能不会增加你的链路速度(甚至会有所减少),而且可能会增加服务器和客户端的计算负担。但在高并发的情景下,如浏览含有大量图片的网页时,或者发送大量UDP请求时,可以提升使用体验。 +启用多路复用不会增加你的链路速度(甚至会有所减少),而且可能会增加服务器和客户端的计算负担。可以粗略地理解为,多路复用牺牲网络吞吐和CPU功耗,换取更低的延迟。在高并发的情景下,如浏览含有大量图片的网页时,或者发送大量UDP请求时,可以提升使用体验。 激活```mux```模块,只需要将```mux```选项中```enabled```字段设为true即可,下面是一个客户端的例子 ```json -{ - "run_type": "client", - "local_addr": "127.0.0.1", - "local_port": 1080, - "remote_addr": "your_server", - "remote_port": 443, - "password": [ - "your_password" - ], - "mux" :{ - "enabled": true - } +... +"mux" :{ + "enabled": true } ``` diff --git a/docs/content/advance/plugin.md b/docs/content/advance/plugin.md index a9e360e..3adacf7 100644 --- a/docs/content/advance/plugin.md +++ b/docs/content/advance/plugin.md @@ -27,10 +27,10 @@ Trojan-Go支持可插拔的传输层。原则上,Trojan-Go可以使用任何 ```json ...(省略) "transport_plugin": { - "enabled": true, - "type": "shadowsocks", - "command": "./v2ray-plugin", - "arg": ["-server", "-host", "www.baidu.com"] + "enabled": true, + "type": "shadowsocks", + "command": "./v2ray-plugin", + "arg": ["-server", "-host", "www.baidu.com"] } ``` diff --git a/docs/content/advance/websocket.md b/docs/content/advance/websocket.md index 6f71260..584b556 100644 --- a/docs/content/advance/websocket.md +++ b/docs/content/advance/websocket.md @@ -6,29 +6,17 @@ weight: 2 ### 注意,Trojan-GFW版本不支持这个特性 -Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流量中转成为可能。这个特性的设计考虑了将来GFW部署大规模HTTPS中间人攻击的情景。开启Websocket后,因为Trojan-Go支持使用多重TLS,即使遭受GFW的HTTPS中间人攻击,**在正确的配置下**,连接的安全性依然能得到保证。 +Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流量中转成为可能。 -服务器和客户端配置文件中同时添加websocket选项,并将其```enabled```字段设置为true,并填写```path```字段和```hostname```字段即可启用Websocket支持。下面是一个完整的Websocket选项 +Trojan协议本身不带加密,安全性依赖外层的TLS。但流量一旦经过CDN,TLS对CDN是透明的。其服务提供者可以对TLS的明文内容进行审查。**如果你使用的是不可信任的CDN(任何在中国大陆注册备案的CDN服务均应被视为不可信任),请务必开启Shadowsocks AEAD对Webosocket流量进行加密,以避免遭到识别和审查。** + +服务器和客户端配置文件中同时添加websocket选项,并将其```enabled```字段设置为true,并填写```path```字段和```hostname```字段即可启用Websocket支持。下面是一个完整的Websocket选项: ```json "websocket": { "enabled": true, "path": "/imaurlpath", - "hostname": "www.your_awesome_domain_name.com", - "obfuscation_password": "another_password", - "double_tls": true, - "ssl": { - "verify": true, - "verify_hostname": true, - "cert": "", - "key": "", - "key_password": "", - "prefer_server_cipher": false, - "sni": "", - "session_ticket": true, - "reuse_session": true, - "plain_http_response": "", - } + "hostname": "www.your_awesome_domain_name.com" } ``` @@ -36,23 +24,7 @@ Trojan-Go支持使用TLS+Websocket承载Trojan协议,使得利用CDN进行流 ```path```指的是websocket所在的URL路径,必须以斜杠("/")开始。路径并无特别要求,满足URL基本格式即可,但要保证客户端和服务端的```path```一致。```path```应当选择较长的字符串,以避免遭到GFW直接的主动探测。 -```double_tls```表示是否开启双重TLS,如果省略,默认设置为true。因为Trojan-Go与CDN进行了TLS握手,对于CDN而言,TLS流量内容是明文。为了保证安全性,Trojan-Go默认将在Websocket连接上再建立一次TLS连接(双重TLS)。此时传输实际上经过了两次TLS握手。 - -```ssl```第二层TLS的配置。如果未填写,使用全局的```ssl```选项填充 - -```obfuscation_password```为Websocket流量混淆密码。如果你使用了国内的CDN,建议设置```obfuscation_password```字段进行流量混淆。Trojan-Go将对Websocket承载的流量再进行一次加密(AES-128-CTR)。注意这个字段的主要目的仅仅是**混淆**上层流量的特征(TLS/Trojan),防止被国内的CDN识别和封锁,**它无法确保传输数据安全性**。安全性应该由第二层TLS隧道保证。 - -服务器开启Websocket支持后可以同时支持Websocket和一般Trojan流量,未配置Websocket选项的客户端依然可以正常使用。 - -由于Trojan-GFW版本并不支持Websocket,因此,虽然开启了Websocket支持的服务端仍然可以兼容原版Trojan客户端,但是如果要使用Websocket承载流量进行CDN中转等,请确保双方都使用Trojan-Go。 - -如果你想提高传输的性能和吞吐量,可以将```double_tls```设为false或者将```obfuscation_password```设为空,此时websocket将会直接承载Trojan协议。但是出于安全性考虑,还是建议至少开启混淆和双重TLS中的至少一项。 - -**如果你使用的是国内的CDN,务必保证两者均开启。最坏情况下也应当保持混淆和双重TLS之一是打开的。** - -CDN转发的场景,和GFW在2020年3月29日进行的对包括github pages等站点进行的HTTPS流量劫持和中间人攻击,是类似的。它们的共同点是,第一层TLS承载的流量明文均可以被第三者窃听(CDN或GFW)。**如果你使用了Websocket模式**,你可以将客户端全局```ssl```选项中```verify```字段填写为false。并指定```websocket```选项的```ssl```选项并且打开证书校验。在这样的设置下,即使第一层TLS传输的明文遭到审查或攻击,由于第二层TLS的保护,传输的内容依旧安全。 - -Trojan-Go同样具有针对Websocket的主动探测的欺骗能力。当一个合法的Webosocket握手完成,但密码不匹配或内容不合法时,将会尝试与```http://remote_addr:remote_port/path```的HTTP服务器进行Websocket握手,并将连入的Websocket连接代理给它。如果连接失败,Websocket会被直接关闭。 +客户端的```hostname```将发送给CDN服务器,必须有效;服务端和客户端```path```必须一致,否则Websocket握手无法进行。 下面是一个客户端配置文件的例子 @@ -69,10 +41,11 @@ Trojan-Go同样具有针对Websocket的主动探测的欺骗能力。当一个 "websocket": { "enabled": true, "path": "/imaurlpath", - "hostname": "www.your_awesome_domain_name.com", - "obfuscation_password": "another_password", - "double_tls": true + "hostname": "www.your_awesome_domain_name.com" + }, + "shadowsocks": { + "enabled": true, + "password": "12345678" } } - ``` diff --git a/statistic/memory/memory_test.go b/statistic/memory/memory_test.go new file mode 100644 index 0000000..6ffcb74 --- /dev/null +++ b/statistic/memory/memory_test.go @@ -0,0 +1,30 @@ +package memory + +import ( + "context" + "fmt" + "runtime" + "strconv" + "testing" + + "github.com/p4gefau1t/trojan-go/common" + "github.com/p4gefau1t/trojan-go/config" +) + +func BenchmarkMemoryUsage(b *testing.B) { + cfg := &Config{ + Passwords: nil, + } + ctx := config.WithConfig(context.Background(), Name, cfg) + auth, err := NewAuthenticator(ctx) + common.Must(err) + m1 := runtime.MemStats{} + m2 := runtime.MemStats{} + runtime.ReadMemStats(&m1) + for i := 0; i < 100000; i++ { + err := auth.AddUser(common.SHA224String("hash" + strconv.FormatInt(int64(i), 10))) + common.Must(err) + } + runtime.ReadMemStats(&m2) + fmt.Println(float64(m2.Alloc-m1.Alloc)/1024/1024, "MiB") +} diff --git a/tunnel/tls/fingerprint/tls.go b/tunnel/tls/fingerprint/tls.go index 56bc8cc..4eb3176 100644 --- a/tunnel/tls/fingerprint/tls.go +++ b/tunnel/tls/fingerprint/tls.go @@ -9,6 +9,7 @@ import ( ) func GetClientHelloSpec(name string, websocket bool) (*ClientHelloSpec, error) { + // TODO fix websocket var spec *ClientHelloSpec switch name { case "chrome": diff --git a/tunnel/tproxy/server.go b/tunnel/tproxy/server.go index 6e1b1d6..5aa857e 100644 --- a/tunnel/tproxy/server.go +++ b/tunnel/tproxy/server.go @@ -144,7 +144,7 @@ func (s *Server) packetDispatchLoop() { func (s *Server) AcceptPacket(tunnel.Tunnel) (tunnel.PacketConn, error) { select { case conn := <-s.packetChan: - log.Info("tproxy packet conn accpeted") + log.Info("tproxy packet conn accepted") return conn, nil case <-s.ctx.Done(): return nil, io.EOF