Trojan的搭建和使用(解锁奈飞和chatgpt)
问题与背景
对于经常有上外网需求的人来说,如何实现高效科学上网是一件必须要做的事情,大部分人可能会找个 机场 直接订阅就完事了,但是机场的质量参差不齐,使用的线路都是一些垃圾线路,像一些 大机场 使用的线路会好一点,但是都是订阅制的,如果一个月内流量没有用完,下个月又得重新续订,这对于我这些只查看学习资料,不看奈飞的人来说简直就是一种浪费。最近我的机场订阅也快到期了,我不打算再订阅了,最主要的原因就是,“我用的这个机场虽然是按流量收费的,速度也很快,但是延迟高,高峰期不稳定,最可恶的是chatgpt生成内容的时候老是断开连接“,干脆一不做二不休,自己搭建一个节点,好在最近腾讯云搞活动,境外(新加坡)服务器只要99元,而且有30M的带宽,这对个人使用完全够了,看个1080p的流视频问题也不大。
技术选型
购买服务器之后,接下来要做的就是使用什么工具来实现自己的节点,我首先想到的是使用 openVPN 这是一种比较成熟的私有局域网解决方案,搭建也有现成的代码,但是当我查阅资料之后直接pass掉了,原因很简单,openVPN和其他一众VPN工具的流量特征太明显了,简直就像举着一块牌子说我是VPN的流量,非常容易遭到 ”GFW“ 的封锁,轻则端口不能使用,严重的整个ip都不能用了(可通过套cdn解决,有机会再讲),之后了解了shadowsocks和vmess,发现也不太合适,还要配套的工具v2ray,那有没有一种又新,单协议,开箱即用的工具呢?答案是肯定的,这个东西就叫Trojan。这个Trojan可不是病毒,但是它的原理足够对得起这个名字。
Trojan原理
Trojan的原理是一种反向思维,既然不管我怎么加密,怎么混淆都会留下特征,那么干脆就直接伪装成https流量,作为使用最多的协议,根本就审查不过来,这样就实现了安全的数据传输,当防火墙主动连接trojan服务器时,会发送一个正常的https网页,这样这个服务在别人看来就是一个正常的https网站,具体的实现请看 这篇文章。
服务器搭建篇
Trojan是不分客户端和服务器的,具体取决于配置文件,如果配置文件是客户端的,那么trojan启动之后就是客户端,反之亦然。Trojan原本是用python实现的,但是功能并不是太多,所以这里我选择Trojan-Go,使用go语言实现的Trojan版本。
证书和密钥
trojian通过伪装成https来实现绕过GFW,所以我们需要为使用的域名申请证书,自签名证书不太推荐,我使用的方案是,使用1panel面板自带的ACME来申请证书,并设置证书保存的目录,当证书快过期的时候ACME会自动重新申请,不管是管理证书,还是上传证书,修改证书都可以在1panel面板里面操作,十分的方便。安装1panel,申请证书要有一个域名,之后在1panel上配置好DNS账户和ACME账户,然后就可以直接为指定域名申请证书了,嫌麻烦直接申请泛域名证书。
上面这两步搞不定还是用现成的机场吧!
安装Trojan-go和编写配置文件
- 下载可执行的二进制文件
- 赋予可执行权限
sudo chmod u+x trojan
- 编写服务端配置
{
"run_type": "server",
"local_addr": "127.0.0.1",
"local_port": 1443,
"remote_addr": "127.0.0.1",
"remote_port": 81,
"password": [
"uD1rP1n3RWHocukn"
],
"ssl": {
"cert": "./ca/fullchain.pem",
"key": "./ca/privkey.pem"
},
"api": {
"enabled": true,
"api_addr": "127.0.0.1",
"api_port": 10000
},
"forward_proxy": {
"enabled": true,
"proxy_addr": "127.0.0.1",
"proxy_port": 7890,
"username": "user",
"password": "passwd"
}
}
Trojan也支持yaml配置
run_type: server # 以服务端的方式启动
local_addr: 127.0.0.1 # 监听的地址,如果服务器没有运行nginx可以直接监听0.0.0.0
local_port: 1443 # 如果服务器没有运行nginx直接监听443
remote_addr: 127.0.0.1 # run_type为server的时候这个表示当GFW发起主动检测时跳转的地址
remote_port: 81 # 同上,表示端口
password:
- uD1rP1n3RWHocukn # 客户端连接时所需的密码
ssl: # acme客户端申请的证书
cert: ./ca/fullchain.pem
key: ./ca/privkey.pem
api: # 提供给后端服务的api,可查看流量,控制网速等
enabled: true
api_addr: 127.0.0.1
api_port: 10000
forward_proxy: # 收到客户端发来的流量交给谁处理,不写直接以服务器为源地址发起请求,这对于要解锁奈飞和chatgpt客户端非常重要,非必要
enabled: true
proxy_addr: 127.0.0.1
proxy_port: 7890
username: user1
password: *****
- 使用systemd来管理trojan-go进程
[Unit]
Description=Trojan-Go Service
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/trojan-go-server # 工作目录,进程会按照这个目录来找相对路径
ExecStart=/home/ubuntu/trojan-go-server/trojan-go -config /home/ubuntu/trojan-go-server/server.json # 这里需要指定为绝对路径
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
加载进程单元,并且执行
systemctl daemon-reload # 加载
systemctl enable trojan-go # 运行开机自启动
systemctl start trojan-go # 执行
补充
在Trojan服务器的配置中,有一个叫做forward_proxy的选项,这个选项作用是客户端发来的数据被服务端解析之后应该交由谁处理,这个时候如果没有写的话就是交由云服务器处理,云服务器会向指定的网站发起请求,比如google,在google看来就是云服务器的ip在请求自己,如果遇到对ip有封锁的应用,比如奈飞,或者chatgpt客户端,比如:android.chatgpt.com和ios.chatgpt.com,这个时候就会根据请求的ip来判断是否提供服务,可以使用如下命令来判断,自己的服务器ip是否解锁了对应服务。
bash <(curl -L -s halo.icoding.fun/upload/check.sh)
效果如下:
从上面的检测结果可以发现,服务器ip对chatgpt 的解锁情况是 Website Only (Region: SG),也就是说,我的服务器区域为SG(新加坡),只能使用网页版的chatgpt,所以我们需要一些手段来解锁,很容易想到的一种思路就是把没有解锁的域名交给一台解锁了的服务器,帮我们代理访问,那我们去哪里找这台服务器呢?这个时候就得找我们的大善人Cloudflare了,Cloudflare有一款工具叫做warp,只要连接上这个工具就可以访问cloudflare的网络,整个主机出去的流量都会由cloudflare代理,这个时候在奈飞或者chatgpt看来就是它允许的地区在访问,但是我们只需要代理访问被封锁的应用的流量,像没有被封锁的应用我们只需让云服务器发起请求就行,这个时候就需要用到一个分流的工具,并且它能接受socket代理的入站,也能连接socket代理的出站,这里我们使用clash来做这个分流工具,这样trojan接收到的流量再交由clash处理,如果需要走warp就交给warp提供的socket端口,如果不需要,就直接由服务器发起这个请求。这么说还是很模糊,看下面这个图就清楚了。
安装warp
安装就不多赘述了,直接上链接cloudflare warp
warp-cli mode proxy # 开启代理模式
warp-cli proxy port 2048 # 监听本地端口2048 127.0.0.1:2048
warp-cli connect # 连接到cloudflare网络
安装clash
clash的作用就是分流,clash功能非常强大,可以通过匹配域名来做分流,通过检测脚本已经得知,chatgpt对以下两个域名是没有没有开启原生访问的,一个是android手机端的chatgpt App,域名为:android.chat.openai.com,还有一个就是苹果移动端的chatgpt App, 域名为:ios.chat.openai.com。
安装就不多赘述了,直接上连接,这里使用clash和clash meta(mihomo)内核都可以。
mixed-port: 7890 # socket和http代理混合端口
tproxy-port: 7894 # 透明代理端口,可以给iptables/nftables使用提供强大的透明代理功能
allow-lan: true
bind-address: "*"
# 本地 SOCKS5/HTTP(S) 代理服务的认证
authentication:
- "user:passwd"
mode: rule
proxies: # 配置代理,如有多个出口,可以配置多个
- name: "warp-proxy"
type: socks5
server: 127.0.0.1
port: 2048
rules:
- DOMAIN-SUFFIX,ios.chat.openai.com,warp-proxy # 当匹配到域名ios.chat.openai.com直接走warp出去,不使用服务器原生网络环境
- DOMAIN-SUFFIX,android.chat.openai.com,warp-proxy # 同理
- MATCH,DIRECT
nginx分流转发(非必须)
有的小伙伴的服务器可能允许着web服务,会占用443端口,这个时候Trojan服务端有两个选择,1.使用其他端口代替443,比如1443。2.利用tcp握手的sni做分流,这样的话访问的域名只需和trojan配置的一样,trojan流量就会正常的转发到trojan服务器。nginx配置sni分流特别简单,直接贴配置。
# 流量转发核心配置
stream {
# 这里就是 SNI 识别,将域名映射成一个配置名
map $ssl_preread_server_name $backend_name {
*.icoding.icu web;
free.icoding.icu trojan;
# 域名都不匹配情况下的默认值
default web;
}
# web,配置转发详情
upstream web {
server 127.0.0.1:8443; # 原本的web服务要换成其他端口
}
# trojan,配置转发详情
upstream trojan {
server 127.0.0.1:1443;
}
# 监听 443 并开启 ssl_preread
server {
listen 443 reuseport ;
listen [::]:443 reuseport ;
proxy_pass $backend_name;
ssl_preread on;
}
}
客户端
客户端用法和服务端一样,下面直接贴一个简单的配置文件。
{
"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.com"
}
}
上面填入的内容要和服务端的匹配,启动这份配置之后,会在windows上监听127.0.0.1:1080这个端口,你只需在网络选项里面设置这个代理就可以愉快的上网了。
总结
整个流程其实还是挺复杂的,网上也有很多现成的解决方案,比如xui的一键安装脚本,集成了xray和xui面板,更有甚者可直接下发clash的配置文件,你只需提供一台能访问的主机和一个正常的域名,就可以实现愉快的上网,但是核心的逻辑还是一样的,其中warp解锁是一个非常常用的技巧,这得益于大善人cloudflare。在有clash做分流的情况下只需在rule里面添加规则就可解锁地区,从而愉快的访问奈飞和app版chatgpt。
评论区