mirror of
https://github.com/p4gefau1t/trojan-go.git
synced 2024-04-21 12:21:34 +00:00
hugo docs
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Version = "v0.1.2"
|
||||
Version = "v0.1.3"
|
||||
)
|
||||
|
||||
type Runnable interface {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
baseURL = "https://example.com"
|
||||
|
||||
languageCode = "en-us"
|
||||
DefaultContentLanguage = "en"
|
||||
title = "Trojan-Go"
|
||||
theme = "hugo-theme-techdoc"
|
||||
|
||||
hasCJKLanguage = true
|
||||
metaDataFormat = "yaml"
|
||||
|
||||
defaultContentLanguage = "en"
|
||||
defaultContentLanguageInSubdir= false
|
||||
enableMissingTranslationPlaceholders = false
|
||||
|
||||
[params]
|
||||
|
||||
# Source Code repository section
|
||||
description = "An unidentifiable mechanism that helps you bypass GFW. "
|
||||
github_repository = "https://github.com/p4gefau1t/trojan-go"
|
||||
version = "0.1.3"
|
||||
|
||||
# Documentation repository section
|
||||
# documentation repository (set edit link to documentation repository)
|
||||
github_doc_repository = "https://github.com/p4gefau1t/trojan-go/docs"
|
||||
|
||||
# Analytic section
|
||||
google_analytics_id = "" # Your Google Analytics tracking id
|
||||
tag_manager_container_id = "" # Your Google Tag Manager container id
|
||||
google_site_verification = "" # Your Google Site Verification for Search Console
|
||||
|
||||
# Open Graph and Twitter Cards settings section
|
||||
# Open Graph settings for each page are set on the front matter.
|
||||
# See https://gohugo.io/templates/internal/#open-graph
|
||||
# See https://gohugo.io/templates/internal/#twitter-cards
|
||||
title = "Hugo Techdoc Theme"
|
||||
images = ["images/og-image.png"] # Open graph images are placed in `static/images`
|
||||
|
||||
# Theme settings section
|
||||
# Theme color
|
||||
# See color value reference https://developer.mozilla.org/en-US/docs/Web/CSS/color
|
||||
custom_font_color = ""
|
||||
custom_background_color = ""
|
||||
|
||||
# Documentation Menu section
|
||||
# Menu style settings
|
||||
menu_style = "open-menu" # "open-menu" or "slide-menu"
|
||||
|
||||
# Date format
|
||||
dateformat = "" # default "2 Jan 2006"
|
||||
# See the format reference https://gohugo.io/functions/format/#hugo-date-and-time-templating-reference
|
||||
|
||||
# path name excluded from documentation menu
|
||||
menu_exclusion = [
|
||||
"archives",
|
||||
"archive",
|
||||
"blog",
|
||||
"entry",
|
||||
"post",
|
||||
"posts",
|
||||
]
|
||||
|
||||
# Algolia site search section
|
||||
# See https://www.algolia.com/doc/
|
||||
algolia_search_enable = true
|
||||
algolia_indexName = "hugo-demo-techdoc"
|
||||
algolia_appId = "7W4SAN4PLK"
|
||||
algolia_apiKey = "cbf12a63ff72d9c5dc0c10c195cf9128" # Search-Only API Key
|
||||
|
||||
# Global menu section
|
||||
# See https://gohugo.io/content-management/menus/
|
||||
[menu]
|
||||
[[menu.main]]
|
||||
name = "Home"
|
||||
url = "/"
|
||||
weight = 1
|
||||
|
||||
[[menu.main]]
|
||||
name = "GitHub"
|
||||
url = "https://github.com/p4gefau1t"
|
||||
weight = 2
|
||||
|
||||
[[menu.main]]
|
||||
name = "Twitter"
|
||||
url = "https://twitter.com/p4gefau1t"
|
||||
weight = 3
|
||||
|
||||
# Markup configure section
|
||||
# See https://gohugo.io/getting-started/configuration-markup/
|
||||
[markup]
|
||||
defaultMarkdownHandler = "goldmark"
|
||||
[markup.goldmark.renderer]
|
||||
unsafe= true
|
||||
[markup.tableOfContents]
|
||||
startLevel = 2
|
||||
endLevel = 4
|
||||
ordered = false
|
||||
|
||||
# Algolia Search configure section
|
||||
[outputFormats.Algolia]
|
||||
baseName = "algolia"
|
||||
isPlainText = true
|
||||
mediaType = "application/json"
|
||||
notAlternative = true
|
||||
|
||||
[params.algolia]
|
||||
vars = [
|
||||
"title",
|
||||
"summary",
|
||||
"content",
|
||||
"date",
|
||||
"publishdate",
|
||||
"description",
|
||||
"permalink",
|
||||
"keywords",
|
||||
"lastmod",
|
||||
]
|
||||
params = [
|
||||
"tags",
|
||||
"categories",
|
||||
]
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "简介"
|
||||
draft: false
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# Trojan-Go
|
||||
|
||||
Trojan-Go是使用Golang实现的完整的Trojan代理,和Trojan协议以及原版的配置文件格式兼容。
|
||||
|
||||
Trojan-Go的开发将传输安全性和隐蔽性放在首位。在此前提下,尽可能提升传输性能和易用性。
|
||||
|
||||
Trojan-Go支持并且兼容原版Trojan的绝大多数功能,包括但不限于:
|
||||
|
||||
- TLS隧道传输
|
||||
|
||||
- 透明代理 (NAT模式,iptables设置参见[这里](https://github.com/shadowsocks/shadowsocks-libev/tree/v3.3.1#transparent-proxy))
|
||||
|
||||
- UDP代理
|
||||
|
||||
- 对抗GFW被动/主动检测的机制
|
||||
|
||||
- MySQL数据库支持
|
||||
|
||||
- 流量统计,用户流量配额限制
|
||||
|
||||
- 从数据库中的用户列表进行认证
|
||||
|
||||
- TCP性能方面的选项,如TCP Fast Open,端口复用等
|
||||
|
||||
同时,Trojan-Go还支持更多高效易用的功能:
|
||||
|
||||
- 多路复用,显著提升并发性能
|
||||
|
||||
- 自定义路由模块,可实现国内直连/广告屏蔽等功能
|
||||
|
||||
- Websocket,用于支持CDN流量中转(基于WebSocket over TLS/SSL)和对抗GFW中间人攻击
|
||||
|
||||
- 自动化HTTPS证书申请,使用ACME协议从Let's Encrypt自动申请和更新HTTPS证书
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: "高级配置"
|
||||
draft: false
|
||||
weight: 30
|
||||
---
|
||||
|
||||
这一部分内容将介绍更复杂的Trojan-Go配置方法
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "流量中继"
|
||||
draft: false
|
||||
---
|
||||
|
||||
Trojan-Go支持进行流量转发。一个典型的使用场景是,你所使用的ISP提供的网络服务,出境的线路质量并不理想。这时你可以使用国内的一些线路更好的服务器,作为中继,将你的流量转发给trojan服务器。
|
||||
|
||||
Forward中继的配置很简单,下面是一个Forward的配置
|
||||
|
||||
```
|
||||
{
|
||||
"run_type": "forward",
|
||||
"local_addr": "0.0.0.0",
|
||||
"local_port": 1234,
|
||||
"remote_addr": "your_trojan_server",
|
||||
"remote_port": 443,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Forwad启动后,客户端连接该主机的1234端口,和直接连接Trojan服务器443端口是等效的。为了保证安全性和稳定性,Forward只做简单的流量转发,本地不需要任何的证书文件和密钥文件。
|
||||
|
||||
你可以使用多个Forward链接起来作为多重跳板,如果你忍受这种做法带来的延迟升高和吞吐量下降的话。
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: "使用多路复用提升并发性能"
|
||||
draft: false
|
||||
---
|
||||
|
||||
Trojan-Go支持使用多路复用提升并发性能。
|
||||
|
||||
Trojan协议基于TLS。在一个TLS安全连接建立之前,连接双方需要进行密钥协商和交换等步骤确保后续通讯的安全性。这个过程即为TLS握手。
|
||||
|
||||
目前GFW对于TLS握手有审查和干扰,同时由于出口网络拥塞的原因,普通的线路完成TLS握手通常需要将近一秒甚至更长的时间。这可能会使得浏览网页和观看视频的延迟提高。
|
||||
|
||||
Trojan-Go使用多路复用的方式解决这一问题。每个建立的TLS连接将承载多个TCP连接。当新的代理请求到来时,不需要和服务器握手发起一个新的TLS连接,而是尽可能重复使用已有的TLS连接。这样就可以减少TLS握手的带来的延迟。在高并发的情况下,如浏览含有大量图片的网页时,优势尤其突出。
|
||||
|
||||
激活mux模块,只需要将```mux```选项中```enabled```字段设为true即可,下面是一个例子
|
||||
|
||||
```
|
||||
{
|
||||
"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配置如下
|
||||
|
||||
```
|
||||
"mux": {
|
||||
"enabled": false,
|
||||
"concurrency": 8,
|
||||
"idle_timeout": 60
|
||||
}
|
||||
```
|
||||
|
||||
```concurrency```是每个TLS连接最多可以承载的TCP连接数。这个数值越大,TLS连接被复用的比例就更高,握手导致的延迟越低,但服务器和客户端的计算负担也会越大,这有可能使你的网络吞吐量降低。如果你的线路的TLS握手极端缓慢,你可以将这个数值设置为-1,Trojan-Go将只进行一次TLS握手,只使用唯一的一条TLS连接进行传输。
|
||||
|
||||
```idle_timeout```指的是每个TLS连接空闲多长时间后关闭。设置超时时间,**可能**有助于减少不必要的长连接存活确认(Keep Alive)流量传输引发GFW的探测。你可以将这个数值设置为-1,TLS连接将不会因为长时间空闲而被关闭。
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: "使用路由功能实现国内直连和广告屏蔽"
|
||||
draft: false
|
||||
---
|
||||
|
||||
Trojan-Go内建的路由模块可以帮助你实现国内直连,即国内网站不经过代理,直接连接。
|
||||
|
||||
下面是一个例子
|
||||
|
||||
```
|
||||
{
|
||||
"run_type": "client",
|
||||
"local_addr": "127.0.0.1",
|
||||
"local_port": 1080,
|
||||
"remote_addr": "your_server",
|
||||
"remote_port": 443,
|
||||
"password": [
|
||||
"your_password"
|
||||
],
|
||||
"ssl": {
|
||||
"sni": "your_domain_name"
|
||||
},
|
||||
"mux" :{
|
||||
"enabled": true
|
||||
},
|
||||
"router":{
|
||||
"enabled": true,
|
||||
"bypass": [
|
||||
"geosite:cn",
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
所需要的geoip.dat和geosite.dat已经包含在release的压缩包中,直接使用即可。它们来自v2ray的[domain-list-community](https://github.com/v2ray/domain-list-community)和[geoip](https://github.com/v2ray/geoip)。
|
||||
|
||||
这个配置文件激活了router模块,使用的是白名单的模式,当匹配到中国大陆的ip或域名时,将使用直接连接,否则使用trojan代理进行连接。
|
||||
|
||||
你也可以配置自己的列表文件,列表文件每一行是一个域名或者IP子网(CIDR)。例如,你想要屏蔽所有example.com域名以及其子域名,以及192.168.1.0/24,只需要编写一个txt文件
|
||||
|
||||
test_list.txt
|
||||
```
|
||||
example.com
|
||||
192.168.1.0/24
|
||||
```
|
||||
|
||||
然后在block字段中填入该文件名
|
||||
|
||||
同时geosite中也含有广告提供商的域名,可以通过"geosite:category-ads"指定屏蔽它们。下面这个例子使用了一个列表文件,和geosite的category-ads标签,对相关连接进行屏蔽
|
||||
|
||||
```
|
||||
"router":{
|
||||
"enabled": true,
|
||||
"bypass": [
|
||||
"geosite:cn",
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
],
|
||||
"block": [
|
||||
"test_list.txt",
|
||||
"geosite:category-ads"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
下面介绍完整的路由功能
|
||||
|
||||
路由策略有三种
|
||||
|
||||
- Proxy 代理。将请求通过TLS隧道进行代理,由trojan服务器和目的地址进行连接。
|
||||
|
||||
- Bypass 绕过。直接在本地和目的地址进行连接。
|
||||
|
||||
- Block 封锁。不代理请求,直接关闭连接。
|
||||
|
||||
```
|
||||
"router": {
|
||||
"enabled": true,
|
||||
"bypass": [
|
||||
"geoip:tag1",
|
||||
"geosite:tag2",
|
||||
"bypass_list1.txt",
|
||||
"bypass_list2.txt"
|
||||
],
|
||||
"block": [
|
||||
"block_list.txt"
|
||||
]
|
||||
"proxy": [
|
||||
"proxy_list.txt"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
其中```bypass```,```block```, ```proxy```字段中填入相应的列表文件或者geo数据库tag。列表文件每行是一个域名或者IP地址段(CIDR)。geo数据库geoip和geosite为IP数据库和域名数据库。一旦匹配,则执行相应策略。
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: "使用Websocket进行CDN转发"
|
||||
draft: false
|
||||
---
|
||||
|
||||
Trojan-Go支持使用TLS+Websocket+TLS(多重TLS)承载Trojan协议,使得利用CDN进行流量中转成为可能。这个特性的同时考虑了将来GFW部署大规模HTTPS中间人攻击的情景。开启Websocket后,因为Trojan-Go使用了多重TLS,即使遭受GFW的HTTPS中间人攻击,**在正确的配置下**,连接的安全性依然能得到保证。
|
||||
|
||||
服务器和客户端配置文件中同时添加websocket选项,并将其```enabled```字段设置为true,并填写```path```字段即可启用Websocket支持。下面是一个完整的Websocket选项
|
||||
|
||||
```
|
||||
"websocket": {
|
||||
"enabled": true,
|
||||
"path": "/imaurlpath",
|
||||
"hostname": "www.your_awesome_domain_name.com",
|
||||
"password": "another_password"
|
||||
}
|
||||
```
|
||||
|
||||
客户端```hostname```是可选的,填写你的域名。如果留空,将会使用```remote_addr```填充,服务端可以省略```hostname```。
|
||||
|
||||
```path```指的是websocket所在的URL路径,必须以斜杠("/")开始。路径并无特别要求,满足URL基本格式即可,但要保证客户端和服务端的```path```一致。```path```应当选择较长的字符串,以避免遭到主动检测。
|
||||
|
||||
服务器开启Websocket支持后可以同时支持Websocket和一般Trojan流量,未配置Websocket选项的客户端依然可以正常使用。
|
||||
|
||||
由于原版Trojan并不支持Websocket,因此,虽然开启了Websocket支持的服务端可以兼容原版Trojan客户端,但是如果要使用Websocket承载流量进行CDN中转等,请确保双方都使用Trojan-Go。
|
||||
|
||||
因为Trojan-Go与CDN进行了TLS握手,对于CDN而言,TLS流量内容是明文。为了保证安全性,Trojan-Go默认将在Websocket连接上再建立一次TLS连接。此时传输实际上经过了两次TLS连接,并且这个TLS隧道的证书校验被**强制开启**。
|
||||
|
||||
|
||||
如果你使用了国内的CDN,建议设置```password```字段进行二次加密,Trojan-Go将使用该密码对Websocket承载的流量再进行一次加密(AES-128-CTR)。注意这个字段的作用仅仅是**混淆**TLS的特征,防止被国内的CDN识别和封锁Trojan流量。无论是否使用二次加密,传输的安全性都可以由第二层TLS隧道保证。注意确保服务端和客户端混淆密码一致。
|
||||
|
||||
CDN转发的场景和在GFW在2020年3月29日进行的HTTPS流量劫持和中间人攻击类似。它们的共同点是,第一层TLS承载的流量明文均可以被第三者窃听。**如果你使用了websocket模式**,你可以将客户端的```verify```字段填写为false,并指定```cert```字段。在这样的设置下,即使第一层TLS传输的明文遭到审查,由于第二层TLS的保护(证书校验强制开启),传输的内容依旧安全。
|
||||
|
||||
下面是一个客户端配置文件的例子
|
||||
|
||||
```
|
||||
{
|
||||
"run_type": "client",
|
||||
"local_addr": "127.0.0.1",
|
||||
"local_port": 1080,
|
||||
"remote_addr": "your_server",
|
||||
"remote_port": 443,
|
||||
"password": [
|
||||
"your_password"
|
||||
],
|
||||
"websocket": {
|
||||
"enabled": true,
|
||||
"path": "/imaurlpath",
|
||||
"hostname": "www.your_awesome_domain_name.com"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: "基本配置"
|
||||
draft: false
|
||||
weight: 20
|
||||
---
|
||||
|
||||
这一部分内容将介绍如何配置基本的Trojan-Go代理服务器和客户端
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: "正确配置Trojan-Go"
|
||||
draft: false
|
||||
weight: 22
|
||||
---
|
||||
|
||||
下面将介绍如何正确配置Trojan-Go以完全隐藏你的代理节点特征
|
||||
|
||||
在开始之前,你需要
|
||||
|
||||
- 一个服务器,且未被GFW封锁
|
||||
|
||||
- 一个域名,可以使用免费的域名服务,如.tk等
|
||||
|
||||
- Trojan-Go,可以从release页面下载
|
||||
|
||||
### 配置证书
|
||||
|
||||
为了伪装成一个正常的HTTPS站点,也为了保证传输的安全,我们需要一份经过权威证书机构签名的证书。Trojan-Go支持从Let's Encrypt自动申请证书。首先将你的域名正确解析到你的服务器IP。然后准备好一个邮箱地址,合乎邮箱地址规则即可,不需要真实邮箱地址。保证你的服务器443和80端口没有被其他程序(nginx,apache,正在运行的Trojan等)占用。然后执行
|
||||
|
||||
```
|
||||
sudo ./trojan-go -cert request
|
||||
```
|
||||
|
||||
按照屏幕提示填入相关信息。如果操作成功,当前目录下将得到四个文件
|
||||
|
||||
- server.key 服务器私钥
|
||||
|
||||
- server.crt 经过Let's Encrypt签名的服务器证书
|
||||
|
||||
- user.key 用户Email对应的私钥
|
||||
|
||||
- domain_info.json 域名和用户Email信息
|
||||
|
||||
备份好这些文件,不要将.key文件分享给其他任何人,否则你的身份可能被冒用。
|
||||
|
||||
证书的有效期通常是三个月,你可以使用
|
||||
|
||||
|
||||
```
|
||||
sudo ./trojan-go -cert renew
|
||||
```
|
||||
|
||||
进行证书更新。更新之前请确保同目录下有上述的四个文件。
|
||||
|
||||
### 服务端配置
|
||||
|
||||
我们的目标是,使得你的服务器和正常的HTTPS网站表现相同。
|
||||
|
||||
首先你需要一个配置Web服务器,可以使用nginx,apache,caddy等。Web服务器的作用是,当GFW主动探测时,向它展示一个完全正常的Web页面。
|
||||
|
||||
这是一份比较安全的服务器配置,需要你在本地80端口配置一个HTTP服务(必要),在1234端口配置一个HTTPS服务(可选,可以删除fallback_port字段,跳过这个步骤)
|
||||
|
||||
```
|
||||
{
|
||||
"run_type": "server",
|
||||
"local_addr": "0.0.0.0",
|
||||
"local_port": 443,
|
||||
"remote_addr": "127.0.0.1",
|
||||
"remote_port": 80,
|
||||
"password": [
|
||||
"your_awesome_password"
|
||||
],
|
||||
"ssl": {
|
||||
"cert": "server.crt",
|
||||
"key": "server.key",
|
||||
"fallback_port": 1234
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这个配置文件使Trojan-Go在服务器的所有网卡上(0.0.0.0)监听443端口,使用server.crt和server.key作为证书和密钥进行TLS握手。你应该使用尽可能复杂的密码,同时确保客户端和服务端```password```是一致的。
|
||||
|
||||
如果TLS连接建立后,检测到TLS的内容非法,将TLS连接代理到本地127.0.0.1:80上的HTTP服务,这时远端看起来就是一个HTTPS的网站页面。
|
||||
|
||||
如果TLS握手失败了,说明对方使用的不是TLS协议进行主动探测,此时Trojan-Go将连接代理到本地127.0.0.1:1234上运行的HTTPS服务,本地HTTPS服务器也会检测到连接不是TLS连接,返回一个400 Bad Reqeust的HTTP页面。```fallback_port```是一个可选选项,如果没有填写,Trojan-Go会直接终止连接。虽然是可选的,但是还是强烈建议填写。
|
||||
|
||||
如果TLS连接建立,并且确认是Trojan协议,而且密码正确,那么服务器将解析来自客户端的请求并进行代理。
|
||||
|
||||
你可以通过使用浏览器访问你的域名 https://your_domain_name 来验证。如果工作正常,你的浏览器会显示一个正常的HTTPS保护的Web页面,页面内容与服务器本机80端口上的页面一致。你还可以使用 http://your_domain_name:443 验证```fallback_port```工作是否正常。
|
||||
|
||||
事实上,你甚至可以将Trojan-Go当作你的HTTPS服务器,用来给你的网站提供HTTPS服务。访客可以正常地通过Trojan-Go浏览你的网站,而和代理流量互不影响。
|
||||
|
||||
### 客户端配置
|
||||
|
||||
对应的客户端配置
|
||||
|
||||
```
|
||||
{
|
||||
"run_type": "client",
|
||||
"local_addr": "127.0.0.1",
|
||||
"local_port": 1080,
|
||||
"remote_addr": "your_awesome_server",
|
||||
"remote_port": 443,
|
||||
"password": [
|
||||
"your_awesome_password"
|
||||
],
|
||||
"ssl": {
|
||||
"sni": "your_domain_name"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这个客户端配置使Trojan-Go开启一个监听在本地1080端口的socks5/http代理(自动识别),远端服务器为your_awesome_server:443,your_awesome_server可以是IP或者域名。
|
||||
|
||||
如果你在```remote_addr```中填写的是域名,```sni```可以省略。```sni```字段应当填写你申请证书的对应域名,或者你自己签发证书时证书的Common Name,而且必须一致。注意,```sni```字段目前的在TLS协议中是规定**明文传送**的(目的是使服务器提供相应证书),所以不要填写类似google.com等已经被封锁的域名,否则很有可能导致你的服务器也被封锁。
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "Trojan基本原理"
|
||||
draft: false
|
||||
weight: 21
|
||||
---
|
||||
|
||||
|
||||
这个页面将会简单讲述Trojan协议的基本工作原理。如果你对于GFW和Trojan的工作方式不感兴趣,可以跳过这一小节。但为了更好地保护你的通讯安全性和节点的隐蔽性,我还是建议你阅读。
|
||||
|
||||
|
||||
## 为什么Shadowsocks容易遭到封锁
|
||||
|
||||
防火墙在早期仅仅只是对出境流量进行截获和审查,也即**被动检测**。Shadowsocks的加密协议设计使得传输的数据包本身几乎没有任何特征,看起来类似于完全随机的比特流,这在早一些年的确能有效绕过GFW。
|
||||
|
||||
目前的GFW已 经开始采用**主动探测**的方式。具体来说,当GFW发现一个可疑的无法识别的连接时(大流量,随机字节流,高位端口等特征),将会**主动连接**这个服务器端口,重放之前捕获到的流量(或者经过一些精心修改后重放)。Shadowsocks服务器检测到不正常的连接,将连接断开。这种不正常的流量和断开连接的行为被视作可疑的Shadowsocks服务器的特征,于是该服务器被加入GFW的可疑名单中。这个名单不一定立即生效,而是在某些特殊的敏感时期,可疑名单中的服务器会遭到暂时或者永久的封锁。该可疑名单是否封锁,可能由人为因素决定。
|
||||
|
||||
如果你想了解更多,可以参考[这篇文章](https://gfw.report/blog/gfw_shadowsocks/)。
|
||||
|
||||
## Trojan如何绕过GFW
|
||||
|
||||
与Shadowsocks相反,Trojan不使用自定义的加密协议来隐藏自身。相反,使用特征明显的TLS加密协议,使得流量看起来与正常的HTTPS网站相同。TLS是一个成熟的加密体系,使用**正确配置**的加密TLS隧道,可以保证传输的
|
||||
|
||||
- 保密性(GFW无法得知传输的内容)
|
||||
|
||||
- 完整性(一旦GFW试图篡改传输的密文,通讯双方都会发现)
|
||||
|
||||
- 不可抵赖(GFW无法伪造身份冒充服务端或者客户端)
|
||||
|
||||
- 前向安全(即使密钥泄露,GFW也无法解密先前的加密流量)
|
||||
|
||||
对于被动检测,Trojan协议与HTTPS协议流量的行为完全一致,而HTTPS流量占据了目前互联网流量的一半以上,且HTTPS握手成功后流量是加密的,几乎不存在可行方法从其中分辨出Trojan协议流量。
|
||||
|
||||
对于主动检测,当防火墙连接Trojan服务器进行主动检测时,Trojan可以发现非Trojan协议的流量。与Shadowsocks等代理不同,此时Trojan不会断开连接,而是将这个连接代理到一个正常的Web服务器。在GFW看来,该服务器的行为和一个普通的HTTPS网站行为完全相同,无法判断是否是一个Trojan代理节点。这也是Trojan推荐使用合法的域名、使用CA签名的HTTPS证书的原因: 这让你的服务器完全无法被GFW使用主动检测判定是一个Trojan服务器。
|
||||
|
||||
因此,就目前的情况来看,若要阻断Trojan的连接,只能使用无差别封锁(封锁某个IP段,某一类证书,甚至阻断全国所有出境HTTPS连接)或发动大规模的中间人攻击(证书劫持)。之后的高级配置方法中会讲述相应对策。
|
||||
@@ -0,0 +1,20 @@
|
||||
.PHONY: default clean hugo hugo-build
|
||||
|
||||
default: hugo
|
||||
|
||||
clean:
|
||||
rm -rf public/
|
||||
|
||||
|
||||
hugo-build: clean hugo-themes
|
||||
hugo --enableGitInfo --source .
|
||||
|
||||
hugo:
|
||||
hugo server --disableFastRender --enableGitInfo --watch --source .
|
||||
# hugo server -D
|
||||
|
||||
hugo-themes:
|
||||
rm -rf themes
|
||||
mkdir themes
|
||||
git clone --depth=1 git@github.com:thingsym/hugo-theme-techdoc.git themes/hugo-theme-techdoc
|
||||
rm -rf themes/hugo-theme-techdoc/.git
|
||||
@@ -13,6 +13,6 @@ require (
|
||||
github.com/xtaci/smux v2.0.1+incompatible
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
||||
golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa
|
||||
v2ray.com/core v4.19.1+incompatible
|
||||
)
|
||||
|
||||
@@ -390,6 +390,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b h1:h03Ur1RlPrGTjua4koYdpGl8W0eYo8p1uI9w7RPlkdk=
|
||||
golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -43,7 +43,7 @@ func (f *Forward) Run() error {
|
||||
default:
|
||||
}
|
||||
log.Error(err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
go f.handleConn(conn)
|
||||
}
|
||||
|
||||
@@ -212,8 +212,7 @@ func (s *Server) Run() error {
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
log.Warn(err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
go func(conn net.Conn) {
|
||||
tlsConn := tls.Server(conn, tlsConfig)
|
||||
|
||||
@@ -7,5 +7,5 @@ import (
|
||||
)
|
||||
|
||||
func ListenWithTCPOption(fastOpen, reusePort, noDelay bool, ip net.IP, addr string) (net.Listener, error) {
|
||||
panic("os not support tcp option")
|
||||
panic("this os does not support tcp options")
|
||||
}
|
||||
|
||||
@@ -339,6 +339,10 @@ func TestWebsocketMuxClientServer(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkNormalClientToServer(b *testing.B) {
|
||||
go func() {
|
||||
err := http.ListenAndServe("0.0.0.0:8000", nil)
|
||||
log.Error(err)
|
||||
}()
|
||||
config1 := &conf.GlobalConfig{
|
||||
LogLevel: 5,
|
||||
LocalIP: getLocalIP(),
|
||||
@@ -433,6 +437,68 @@ func BenchmarkMuxClientToServer(b *testing.B) {
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func BenchmarkWebsocketClientToServer(b *testing.B) {
|
||||
config1 := &conf.GlobalConfig{
|
||||
LogLevel: 5,
|
||||
LocalIP: getLocalIP(),
|
||||
LocalPort: 4444,
|
||||
LocalAddr: getLocalAddr(4444),
|
||||
RemoteIP: getLocalIP(),
|
||||
RemotePort: 4445,
|
||||
RemoteAddr: getLocalAddr(4445),
|
||||
TLS: getTLSConfig(),
|
||||
Hash: getHash("pass123"),
|
||||
Mux: conf.MuxConfig{
|
||||
Enabled: true,
|
||||
Concurrency: 8,
|
||||
IdleTimeout: 30,
|
||||
},
|
||||
Websocket: conf.WebsocketConfig{
|
||||
Enabled: true,
|
||||
HostName: "localhost",
|
||||
Path: "/ws",
|
||||
Password: "password",
|
||||
},
|
||||
}
|
||||
c := client.Client{}
|
||||
c.Build(config1)
|
||||
go c.Run()
|
||||
|
||||
config2 := &conf.GlobalConfig{
|
||||
LocalIP: getLocalIP(),
|
||||
LocalPort: 4445,
|
||||
LocalAddr: getLocalAddr(4445),
|
||||
RemoteIP: getLocalIP(),
|
||||
RemotePort: 80,
|
||||
RemoteAddr: getLocalAddr(80),
|
||||
TLS: getTLSConfig(),
|
||||
Hash: getHash("pass123"),
|
||||
Websocket: conf.WebsocketConfig{
|
||||
Enabled: true,
|
||||
HostName: "localhost",
|
||||
Path: "/ws",
|
||||
Password: "password",
|
||||
},
|
||||
}
|
||||
s := server.Server{}
|
||||
s.Build(config2)
|
||||
go s.Run()
|
||||
|
||||
target := RunBlackHoleTCPServer()
|
||||
dialer, err := proxy.SOCKS5("tcp", getLocalAddr(4444).String(), nil, nil)
|
||||
common.Must(err)
|
||||
conn, err := dialer.Dial("tcp", target.String())
|
||||
common.Must(err)
|
||||
mbytes := 512
|
||||
payload := GeneratePayload(1024 * 1024 * mbytes)
|
||||
t1 := time.Now()
|
||||
conn.Write(payload)
|
||||
t2 := time.Now()
|
||||
speed := float64(mbytes) / t2.Sub(t1).Seconds()
|
||||
b.Log("Speed: ", speed, "MB/s")
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func BenchmarkNormalClientToServerHighConcurrency(b *testing.B) {
|
||||
config1 := &conf.GlobalConfig{
|
||||
LogLevel: 5,
|
||||
|
||||
Reference in New Issue
Block a user