Featured image of post Trojan, 划时代的代理协议

Trojan, 划时代的代理协议

用真实TLS协议栈 bypass GFW 的开创者


trojan协议介绍

相比v2ray来说,trojan更加纯粹,trojan的设计目的就是为了绕过GFW的。v2ray可以是一个多用途的网络工具,但trojan不一样,它就是一个专门的用来科学上网的代理协议。所以单纯从bypass GFW这个角度来说,trojan其实更加合适。

Trojan 的核心思想是:它通过模拟标准 HTTPS 协议的行为,将代理流量隐藏在看起来完全正常的TLS加密流量中。

我在上一期说了在v2ray中,给vmess协议外面套一层TLS,这种方法也是一样,最终目的都是将代理流量包装成普通的TLS流量。

从时间线上来看,trojan是最早提出来这种设计的,并且把它成功实现了的代理协议。所以Trojan是这个理念的先驱,在trojan之前,并没有哪个代理协议是完全用真实的TLS协议栈的。

还有现在非常流行的xray, xray的XTLS的核心逻辑就是将代理流量完全隐藏在真实的TLS通信之中,这个概念与Trojan高度一致。如果不出意外,我下一期来分享一下xray。看一下xray又有哪些创新是值得我们学习的。欢迎关注我的频道,一起来探索一些既有用又有趣的东西。

如果说v2ray的底层协议vmess还有协议特征,那么Trojan 的设计理念,就是要彻底抛弃那些特殊的、容易被识别的流量特征。让整个流量看起来就像是最普通、最常见的流量一样。所以Trojan的创新在于它完全利用标准的TLS协议栈,让流量在网络层面几乎看不出来与正常HTTPS有什么区别。

当trojan客户端连接到服务器的时候,它首先会进行真正的 TLS握手。这里要强调一下,它是真正的TLS握手,不是伪装的,这一点很关键. 如果握手成功,所有后续流量都会受到TLS的保护;如果说握手失败,trojan服务器会像其它服务器一样马上关闭HTTPS连接。这跟标准的HTTPS协议的行为是完全一样的。

虽然这个创新已经过去了很多年,但是直到今天仍然有效,而且基本上这也是目前大多数的代理协议的最终的一个呈现方式。所以这也是我个人非常喜欢trojan的原因之一,因为它很早就看到了这种方式的有效性,并且很简单很纯粹的实现了它.

trojan还设计了一个回落(fallback)机制, 对于非法请求,比如探测性的请求,trojan会自动转发到一个正常网站.这样看起来我们在访问的就是一个正常的网站,所以反探测能力就更强了.虽然在今天来看,这样的机制已经很普遍,很多协议都在用,但是在当初trojan刚发布的时候,还是很了不起的.


trojan搭建步骤

下面我们就来具体实现trojan搭建,需要的工具:

  • 1台VPS
  • 1个域名
  • trojan
  • cloudflare账户
  • certbot

步骤: 安装trojan,绑定域名(DNS),申请证书,配置trojan, 客户端连接

trojan 部署步骤


安装trojan

下面来安装torjan, 安装之前我需要说明一下,trojan有2个版本,一个是原始的C++版本,原作者是用C++语言写的。另一个是trojan-go. trojan-go是根据原始的C++版本重新用go语言写的一个版本. 这2个版本并没有直接的关系. 我更倾向于使用原始的C++版本, 这期视频我也会用原始C++版本来做演示.

Trojan官方github仓库👉: 原始C++版

虽然原版的trojan已经好几年没有更新了,最新的版本已经是5年前的了。但是这并不影响它仍然可以使用。因为过墙的方式并没有变,就像我刚才前面说的,trojan提出的将代理流量加密为TLS流量,这个底层逻辑并没有变。 另外作为一个代理应用,完成的是一个相对简单的任务。所以,如果你没有非常复杂的需求的话,trojan原版仍然好用。

所以trojan仍然是我非常喜欢的代理协议之一。当然现在也有其它很多协议也很好,到时候可以都来尝试一下。

我这里准备好了一台VPS, 操作系统是ubuntu24,安装trojan非常简单,直接使用ubuntu/debian的包管理器安装:

1
sudo apt install trojan  #安装trojan

安装完成以后,如果提示重启,就重启一下系统。

1
sudo reboot  #重启系统

绑定域名DNS

trojan安装完成以后,下面来绑定域名DNS,绑定域名DNS跟上一期v2ray里面的步骤是完全一样的。 登录cloudflare,添加一个子域名。如果你是刚注册的新域名的话,先把根域名添加进来,再添加子域名。 来到DNS记录的页面,添加一条DNS-A记录,指定一个子域名的名称,这个名称是可以随便自定义的。你定义成张三李四都可以。IP这里输入VPS的IP地址。建立这样的对应关系的目的就是,当客户端解析我们的域名的时候,就会将访问请求定向到我们的VPS。

DNS绑定好了以后,这里还需要做一件事。等一下后面申请证书的时候需要用到cloudflare提供的API口令,所以这里要先把API口令取出来。

口令取出来以后,先放到一边,等一下要用到。这个口令非常重要,千万不要公开暴露。因为通过这个口令,其他人就可以对你的域名进行任意的非法篡改。 不过这个口令是可以改的,如果你担心口令可能有暴露,可以回到这里来,点一下轮转。这样cloudflare就会生成一个新口令,原来的就没用了。


申请证书

域名和DNS都绑定好了,下面来申请证书。 申请证书的环节在上一期讲v2ray的时候,讲得很详细。这里再复现一下。

申请证书这一步,对于没有技术背景的朋友来说可能会显得有点复杂,所以我写了一个交互式脚本,你只需要输入API口令和你自己的域名就可以了,非常简单。

交互脚本👉: Certbot申请证书脚本

输入刚才取出来的API口令, 输入你的域名,支持通配符。前面输入根域名,然后逗号,再输入星号加上域名。通配符申请的好处是,它会自动匹配所有子域名。

输入一个邮箱地址, 按Y继续, 按Y继续,


配置trojan

证书申请成功以后,现在开始配置trojan。 打开配置文件:

1
sudo vim /etc/trojan/config.json

Tips: 由于标准的JSON文件格式不支持解析注释,所以复制以下配置内容以后,应该删除掉所有的注释内容,否则可能会解析失败。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//trojan服务端配置
{
    "run_type": "server",
    "local_addr": "0.0.0.0",  //监听所有来源地址
    "local_port": 443,  //监听443端口,只推荐使用443端口
    "remote_addr": "www.amazon.com",  //回落(fallback)网址,对非trojan的请求会被定向到此网址,增强伪装能力
    "remote_port": 80, //回落(fallback)网址的端口
    "password": [
        "5ede&546eab97"  //认证密码,客户端需使用此密码连接
    ],
    "log_level": 1,
    "ssl": {
        "cert": "/etc/letsencrypt/live/domain.com/fullchain.pem",  //证书路径
        "key": "/etc/letsencrypt/live/domain.com/privkey.pem",   //私钥路径
        "key_password": "",
        "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384",
        "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
        "prefer_server_cipher": true,
        "alpn": [
            "http/1.1"
        ],
        "alpn_port_override": {
            "h2": 81
        },
        "reuse_session": true,
        "session_ticket": false,
        "session_timeout": 600,
        "plain_http_response": "",
        "curves": "",
        "dhparam": ""
    },
    "tcp": {
        "prefer_ipv4": false,
        "no_delay": true,
        "keep_alive": true,
        "reuse_port": false,
        "fast_open": false,
        "fast_open_qlen": 20
    },
    "mysql": {
        "enabled": false,
        "server_addr": "127.0.0.1",
        "server_port": 3306,
        "database": "trojan",
        "username": "trojan",
        "password": "",
        "key": "",
        "cert": "",
        "ca": ""
    }
}

配置好了,尝试启动trojan:

1
2
3
4
sudo systemctl start trojan    # 启动trojan
sudo systemctl enable trojan   # 开机自启动
sudo systemctl status trojan   # 查看运行状态
sudo systemctl stop trojan     # 停止运行

如果启动失败,分析失败的原因:

  • 因为trojan默认是以最低权限在操作系统上运行的,trojan进程没有权限读取证书私钥,所以导致了trojan启动失败。

解决办法有3种:

  1. 第1种是简单粗暴法,打开trojan守护进程的配置文件trojan.service,将文件中的user=nobody这一行删除。没有这一行,trojan将会以最高权限root身份运行。这种方法简单粗暴,但是有潜在安全风险,我不推荐这么做。
  2. 第2种方法是将证书及其目录的权限设置为755,让任何用户都能读取证书私钥。这种方法风险更高,强烈建议不要这样做。
  3. 前面这两种方法都是不安全的做法,专业的做法是创建一个权限受限的新用户,并且给这个新用户赋予读取证书和私钥的权限,然后指定trojan以这个新用户的身份运行,这样就完美解决了以上的安全问题。实现步骤👉: 证书权限管理的最佳安全实践

客户端连接

trojan服务端启动成功以后,现在就可以打开客户端来连接上网了. 如果你用的是图形客户端,添加一下服务器就能连接了,这个很简单,这里不展开了.

我更喜欢trojan的原版客户端,它是命令行模式的,还可以实时看到连接日志. 首先去trojan原版仓库下载客户端, 我的是windows系统, 下载windows版本. 解压出来以后, 如果你是第一次安装这个原版客户端,可能要装一下C++运行库,直接双击VC_redist.x64安装一下就好.

然后,修改一下客户端的配置文件,把服务器信息添加到配置文件里面,这样客户端才知道连接哪个服务器.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//trojan客户端配置
{
    "run_type": "client",
    "local_addr": "127.0.0.1", //监听本地地址
    "local_port": 1080,  //本地监听端口
    "remote_addr": "sub.domain.com",  //服务端域名(在cloudflare中配置的域名,关键!)
    "remote_port": 443,  //服务端端口,默认都是443
    "password": [
        "5ede546eab97"  //服务端配置的认证密码,必须与服务端一致
    ],
    "log_level": 1,
    "ssl": {
        "verify": true,
        "verify_hostname": true,
        "cert": "",
        "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
        "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
        "sni": "sub.domain.com", //指定服务端域名
        "alpn": [
            "h2",
            "http/1.1"
        ],
        "reuse_session": true,
        "session_ticket": false,
        "curves": ""
    },
    "tcp": {
        "no_delay": true,
        "keep_alive": true,
        "reuse_port": false,
        "fast_open": false,
        "fast_open_qlen": 20
    }
}

配置写好以后,在trojan客户端目录中右键,选择-打开终端(或者是命令提示符),输入命令: .\trojan.exe -c config.json, 回车,启动trojan客户端。

为了以后打开方便,不需要每次都输入这个命令,可以创建一个批处理文件,然后创建一个快捷方式到桌面上,这样以后直接双击快捷方式就可以启动trojan了。


Privoxy for Windows

对于windows操作系统来说,trojan客户端启动以后,但是我们还不能马上就上网。还需要装一个工具——Privoxy,因为windows默认支持的是http代理, trojan客户端监听的是socks5代理,所以要通过privoxy将http代理转换为socks5代理。

官方下载Privoxy: For Windows

Tips: 如果是macOS,不需要安装privoxy,直接支持配置socks5代理。

配置Privoxy:
打开Privoxy配置文件,在末尾添加以下这两行配置。保存退出。(第二行后面的.点不要漏了)

1
2
listen-address 127.0.0.1:8118  # 监听本机8118端口
forward-socks5 / 127.0.0.1:1080 .  # 转发数据到socks5代理,这里是trojan监听的1080

然后设置系统代理,修改系统代理为127.0.0.1,端口是8118。

打开浏览器,打开google.com搜索, 成功实现trojan代理上网。

欢迎关注我的 Youtube频道 观看视频。

END.

Designed By Jimmycai https://jimmycai.com