mirror of
https://github.com/p4gefau1t/trojan-go.git
synced 2024-04-21 12:21:34 +00:00
update docs
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
[](https://goreportcard.com/report/github.com/p4gefau1t/trojan-go)
|
||||
[](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的客户端,如Igniter,ShadowRocket等。
|
||||
Trojan-Go服务端可以兼容所有原Trojan客户端,如Igniter,ShadowRocket等。
|
||||
|
||||
下面是支持Trojan-Go扩展特性(Websocket/Mux等)的客户端。
|
||||
|
||||
@@ -122,12 +122,12 @@ Trojan-Go服务端可以兼容所有Trojan-GFW的客户端,如Igniter,Shadow
|
||||
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)
|
||||
|
||||
@@ -4,4 +4,4 @@ draft: false
|
||||
weight: 30
|
||||
---
|
||||
|
||||
这一部分内容将介绍更复杂的Trojan-Go配置方法。对于Trojan-GFW版本不支持和不兼容的功能,将在小节中明确标明。
|
||||
这一部分内容将介绍更复杂的Trojan-Go配置方法。对于与Trojan原版不兼容的特性,将在小节中明确标明。
|
||||
|
||||
@@ -4,7 +4,7 @@ draft: false
|
||||
weight: 8
|
||||
---
|
||||
|
||||
### 注意,Trojan-GFW版本不支持这个特性
|
||||
### 注意,Trojan不支持这个特性
|
||||
|
||||
Trojan协议本身无加密,其安全性依赖于下层的TLS。在一般情况下,TLS安全性很好,并不需要再次加密Trojan流量。但是,某些场景下,你可能无法保证TLS隧道的安全性:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ draft: false
|
||||
weight: 10
|
||||
---
|
||||
|
||||
### 注意,Trojan-GFW版本不支持这个特性
|
||||
### 注意,Trojan不支持这个特性
|
||||
|
||||
Trojan-Go使用gRPC提供了一组API,API支持以下功能:
|
||||
|
||||
|
||||
@@ -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服务器,可以如此描述:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ draft: false
|
||||
weight: 1
|
||||
---
|
||||
|
||||
### 注意,Trojan-GFW版本不支持这个特性
|
||||
### 注意,Trojan不支持这个特性
|
||||
|
||||
Trojan-Go支持使用多路复用提升网络并发性能。
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -4,7 +4,7 @@ draft: false
|
||||
weight: 7
|
||||
---
|
||||
|
||||
### 注意,Trojan-GFW版本不支持这个特性
|
||||
### 注意,Trojan不支持这个特性
|
||||
|
||||
Trojan-Go支持可插拔的传输层。原则上,Trojan-Go可以使用任何有TCP隧道功能的软件作为传输层,如v2ray、shadowsocks、kcp等。同时,Trojan-Go也兼容Shadowsocks的SIP003插件标准,如GoQuiet,v2ray-plugin等。也可以使用Tor的传输层插件,如obfs4,meek等。
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ draft: false
|
||||
weight: 3
|
||||
---
|
||||
|
||||
### 注意,Trojan-GFW版本不支持这个特性
|
||||
### 注意,Trojan不支持这个特性
|
||||
|
||||
Trojan-Go内建的路由模块可以帮助你实现国内直连,即客户端对于国内网站不经过代理,直接连接。
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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```而不是该字段。
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user