From 8232db8404829401b92a27a4b6e2bc55b9b99bc5 Mon Sep 17 00:00:00 2001 From: p4gefau1t Date: Mon, 13 Apr 2020 22:13:00 -0400 Subject: [PATCH] hugo docs --- common/common.go | 2 +- docs/archetypes/default.md | 6 ++ docs/config.toml | 120 ++++++++++++++++++++++++++++++ docs/content/_index.md | 39 ++++++++++ docs/content/advance/_index.md | 7 ++ docs/content/advance/forward.md | 23 ++++++ docs/content/advance/mux.md | 44 +++++++++++ docs/content/advance/router.md | 96 ++++++++++++++++++++++++ docs/content/advance/websocket.md | 53 +++++++++++++ docs/content/basic/_index.md | 7 ++ docs/content/basic/config.md | 106 ++++++++++++++++++++++++++ docs/content/basic/trojan.md | 35 +++++++++ docs/makefile | 20 +++++ go.mod | 2 +- go.sum | 2 + proxy/forward/forward.go | 2 +- proxy/server/server.go | 3 +- proxy/server/tcp_option_stub.go | 2 +- test/proxy_test.go | 66 ++++++++++++++++ 19 files changed, 629 insertions(+), 6 deletions(-) create mode 100644 docs/archetypes/default.md create mode 100755 docs/config.toml create mode 100644 docs/content/_index.md create mode 100644 docs/content/advance/_index.md create mode 100644 docs/content/advance/forward.md create mode 100644 docs/content/advance/mux.md create mode 100644 docs/content/advance/router.md create mode 100644 docs/content/advance/websocket.md create mode 100644 docs/content/basic/_index.md create mode 100644 docs/content/basic/config.md create mode 100644 docs/content/basic/trojan.md create mode 100644 docs/makefile diff --git a/common/common.go b/common/common.go index b2f36cc..31a4232 100644 --- a/common/common.go +++ b/common/common.go @@ -11,7 +11,7 @@ import ( ) const ( - Version = "v0.1.2" + Version = "v0.1.3" ) type Runnable interface { diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md new file mode 100644 index 0000000..00e77bd --- /dev/null +++ b/docs/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/docs/config.toml b/docs/config.toml new file mode 100755 index 0000000..0d972a3 --- /dev/null +++ b/docs/config.toml @@ -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", + ] diff --git a/docs/content/_index.md b/docs/content/_index.md new file mode 100644 index 0000000..eb4b4ce --- /dev/null +++ b/docs/content/_index.md @@ -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证书 diff --git a/docs/content/advance/_index.md b/docs/content/advance/_index.md new file mode 100644 index 0000000..78ff693 --- /dev/null +++ b/docs/content/advance/_index.md @@ -0,0 +1,7 @@ +--- +title: "高级配置" +draft: false +weight: 30 +--- + +这一部分内容将介绍更复杂的Trojan-Go配置方法 \ No newline at end of file diff --git a/docs/content/advance/forward.md b/docs/content/advance/forward.md new file mode 100644 index 0000000..686031c --- /dev/null +++ b/docs/content/advance/forward.md @@ -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链接起来作为多重跳板,如果你忍受这种做法带来的延迟升高和吞吐量下降的话。 \ No newline at end of file diff --git a/docs/content/advance/mux.md b/docs/content/advance/mux.md new file mode 100644 index 0000000..58b2159 --- /dev/null +++ b/docs/content/advance/mux.md @@ -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连接将不会因为长时间空闲而被关闭。 diff --git a/docs/content/advance/router.md b/docs/content/advance/router.md new file mode 100644 index 0000000..d5a113f --- /dev/null +++ b/docs/content/advance/router.md @@ -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数据库和域名数据库。一旦匹配,则执行相应策略。 \ No newline at end of file diff --git a/docs/content/advance/websocket.md b/docs/content/advance/websocket.md new file mode 100644 index 0000000..02ff31b --- /dev/null +++ b/docs/content/advance/websocket.md @@ -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" + } +} + +``` diff --git a/docs/content/basic/_index.md b/docs/content/basic/_index.md new file mode 100644 index 0000000..8eebc2a --- /dev/null +++ b/docs/content/basic/_index.md @@ -0,0 +1,7 @@ +--- +title: "基本配置" +draft: false +weight: 20 +--- + +这一部分内容将介绍如何配置基本的Trojan-Go代理服务器和客户端 \ No newline at end of file diff --git a/docs/content/basic/config.md b/docs/content/basic/config.md new file mode 100644 index 0000000..21536fc --- /dev/null +++ b/docs/content/basic/config.md @@ -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等已经被封锁的域名,否则很有可能导致你的服务器也被封锁。 \ No newline at end of file diff --git a/docs/content/basic/trojan.md b/docs/content/basic/trojan.md new file mode 100644 index 0000000..172a7cc --- /dev/null +++ b/docs/content/basic/trojan.md @@ -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连接)或发动大规模的中间人攻击(证书劫持)。之后的高级配置方法中会讲述相应对策。 diff --git a/docs/makefile b/docs/makefile new file mode 100644 index 0000000..95898d3 --- /dev/null +++ b/docs/makefile @@ -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 \ No newline at end of file diff --git a/go.mod b/go.mod index 27b35bf..07e8a2b 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index 506ebb8..6b721bc 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/proxy/forward/forward.go b/proxy/forward/forward.go index 85f982a..5ee9e14 100644 --- a/proxy/forward/forward.go +++ b/proxy/forward/forward.go @@ -43,7 +43,7 @@ func (f *Forward) Run() error { default: } log.Error(err) - continue + return err } go f.handleConn(conn) } diff --git a/proxy/server/server.go b/proxy/server/server.go index 8857ded..dfddf57 100644 --- a/proxy/server/server.go +++ b/proxy/server/server.go @@ -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) diff --git a/proxy/server/tcp_option_stub.go b/proxy/server/tcp_option_stub.go index 0f85ad4..86bb8eb 100644 --- a/proxy/server/tcp_option_stub.go +++ b/proxy/server/tcp_option_stub.go @@ -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") } diff --git a/test/proxy_test.go b/test/proxy_test.go index e039956..1389bfc 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -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,