trojan协议
Trojan协议
Trojan绕过GFW原理:
与Shadowsocks相反,Trojan不使用自定义的加密协议来隐藏自身。相反,使用特征明显的TLS协议(TLS/SSL),使得流量看起来与正常的HTTPS网站相同。
即,将出国的HTTPS数据包后添加协议相关字段,整体再用TLS加密,作为外层HTTPS的数据内容。
但是既然HTTPS本身就对数据做了加密,何必多此一举再套一层HTTPS呢?
在HTTPS数据包中,目标网址(也称为主机名或域名)是在握手过程中的服务器名称指示(Server Name Indication,SNI)字段中发送的。SNI字段是在建立TLS连接时发送给服务器的一个扩展字段,用于指定客户端要连接的目标网址。
SNI字段是明文发送的,因此中间的网络节点或观察者可以查看到目标网址信息。这是为了让服务器能够根据目标网址选择正确的证书进行TLS握手,建立安全连接。因此,当国内直接对google.com
发起HTTPS请求时,国际出口的GFW会直接拦截该数据包或者重定向到其他指定页面。值得注意的是,除了SNI字段外,HTTPS的其他内容(包括请求和响应的头部、正文等)都是加密的,无法直接查看。只有目标服务器才能解密这些数据。
尽管SNI字段可以被观察者看到,但它通常只包含目标网址的域名部分,而不包含具体的路径或查询参数。例如,对于https://www.example.com/path?param=value
这样的URL,SNI字段只会包含www.example.com
。
关于TLS
TLS是一个成熟的加密体系,HTTPS即使用TLS承载HTTP流量。使用正确配置的加密TLS隧道,可以保证传输的
- 保密性(GFW无法得知传输的内容)
- 完整性(一旦GFW试图篡改传输的密文,通讯双方都会发现)
- 不可抵赖(GFW无法伪造身份冒充服务端或者客户端)
- 前向安全(即使密钥泄露,GFW也无法解密先前的加密流量)
Trojan如何避免被墙?
对于被动检测,Trojan协议的流量与HTTPS流量的特征和行为完全一致。而HTTPS流量占据了目前互联网流量的一半以上,且TLS握手成功后流量均为密文,几乎不存在可行方法从其中分辨出Trojan协议流量。
对于主动检测,当防火墙主动连接Trojan服务器进行检测时,Trojan可以正确识别非Trojan协议的流量。与Shadowsocks等代理不同的是,此时Trojan不会断开连接,而是将这个连接代理到一个正常的Web服务器。在GFW看来,该服务器的行为和一个普通的HTTPS网站行为完全相同,无法判断是否是一个Trojan代理节点。这也是Trojan推荐使用合法的域名、使用权威CA签名的HTTPS证书的原因: 这让你的服务器完全无法被GFW使用主动检测判定是一个Trojan服务器。
因此,就目前的情况来看,若要识别并阻断Trojan的连接,只能使用无差别封锁(封锁某个IP段,某一类证书,某一类域名,甚至阻断全国所有出境HTTPS连接)或发动大规模的中间人攻击(劫持所有TLS流量并劫持证书,审查内容)。对于中间人攻击,可以使用Websocket的双重TLS应对,高级配置中有详细讲解。
Trojan节点搭建(Ubuntu 22.04):
trojan-go:https://github.com/p4gefau1t/trojan-go
trojan-go官方文档:https://p4gefau1t.github.io/trojan-go/
1.下载对应版本项目压缩包,上传到/root/trojan目录下解压
其中example文件夹中为示例配置文件,绿色的Trojan-go为可执行文件
2.在当前目录下创建 config.json
配置文件,填入以下内容或者复制example中的示例
1 | { |
3.申请证书
申请证书前要先准备好域名,将域名解析到该服务器IP上,可通过ping域名的方式验证DNS解析是否生效
1 | 安装acme: |
申请成功后会返回证书、私钥和证书链的路径
补充:证书链
证书链(Certificate Chain)是一组证书的集合,用于验证数字证书的有效性和信任。它由一系列证书组成,每个证书都由上一个证书签发机构(Certificate Authority,CA)签发,并形成一个信任链。
证书链的最后一个证书是目标证书,也称为服务器证书或终端证书。该证书包含了一个公钥和与之对应的私钥,用于建立安全连接和进行加密通信。
证书链的其他证书是中间证书或根证书。中间证书由较高级别的CA签发,而根证书是顶级CA签发的自签名证书。根证书是信任链的根源,因为它们是信任的起点。
验证证书的过程是通过检查每个证书的签名和有效期,并验证签发机构的信任链来确保证书的有效性。客户端会使用根证书来验证中间证书的签发机构,然后使用中间证书来验证目标证书的签发机构。如果整个证书链都被验证通过,那么目标证书就被视为有效和受信任。
也可以自签证书
1 | 生成私钥: |
但需要在客户端手动添加受信任的CA机构
4.安装证书
1 | 安装证书: |
安装之后路径下多了两个证书文件,与配置文件中的相对路径对应:
5.运行trojan-go
1 | root@localhost:~/trojan# ./trojan-go |
常驻后台运行:
1 | nohup ./trojan-go > trojan.log 2>&1 & |
后面的2>&1参数是指将标准错误重定向到标准输出,意味着将错误消息与正常输出一起写入到trojan.log
文件中。
具体来说,数字2代表标准错误流(stderr),>
表示重定向操作符,&1
表示将输出重定向到与标准输出相同的地方。
6.客户端配置
- 地址:服务端地址
- 端口:
config.json
设定的服务端口 - 密码:同
config.json
,用于身份验证 - SNI:外层HTTPS中的SNI字段,默认为服务端域名
连接测试(开启CDN后):
7.一些小问题
- 配置DNS解析时默认开启了cloudflare的CDN加速,服务端启动几分钟后,客户端都连接不上,起初以为ip或者端口被GFW墙了,通过https://tcp.ping.pe/网站测试发现全球都能tcping通该服务器443端口,后来将CDN服务关闭才连接成功。
- 于是我又参考了trojan-go的官方文档,发现要开启CDN加速必须在
config.json
文件中添加配置,开启websocket功能,完整配置如下:
1 | { |
!!!注意websocket路径最后还有个/
- 同时还需要修改客户端配置:
主要是将传输层协议修改为websocket(ws),添加websocket路径
- 如果觉得CloudFlare默认分配的CDN IP较慢,可通过
CloudflareST
自动测速优选IP,然后将地址替换为优选IP,同时伪装域名为该服务器所绑定的域名,如下所示: