VPS 初体验(四)trojan 和 Nginx 共用 443 端口

由于 trojan 默认工作在服务器的 443 端口,而 Nginx 的 HTTPS 服务端口也在 443,如果此时想同时使用两种服务。那么要么更改 trojan 默认端口,要么更改 Nginx 的 HTTPS 端口。如果选择更改 HTTPS 端口那么所有 URL 都要补充上端口号,既麻烦也不美观。那么更改 trojan 的默认监听端口可行吗?

trojan 的工作机制是客户端使用 TLS 对要代理的流量进行加密伪装成 HTTPS 流量发送给 trojan 服务端,trojan 服务端工作在 443 端口,对 TLS 加密的数据解密后进行流量识别,如果流量是 trojan 协议并且检查合法(检查 trojan 密码是否正确),说明来自正确的 trojan 客户端,对流量代理转发。如果流量不是 trojan 协议,说明不是来自 trojan 客户端的数据,则转发到则转发到服务端本地的 80 端口,而 80 端口则提前配置好一个 HTTP 伪装站点,向客户端响应 HTML 页面。

之前的代理协议例如 Shadowsocks、VMess,思路普遍都是使用各种复杂的加密,来避免流量特征被 GFW 识别,而 trojan 选择的是把 trojan 服务伪装成一个提供 HTTPS Web 服务的站点,流量在 GFW 看来和普通的 HTTPS 流量没什么区别,进而来躲避 GFW 的审查和封锁。 trojan 相比之前的协议传输效率更高(只有一层加密),抗封锁效果反而更好。

个人理解对 trojan 的伪装可以体现在下面几个方面

  1. TCP 端口号和 HTTPS 一样工作在 443 端口。
  2. 和普通 HTTPS 流量一样使用 TLS 协议进行加密。
  3. 如果用户(可能是探针)使用 HTTPS 协议来访问 trojan server,用户看到的是预先准备好的伪装 Web 站点,和普通 Web 站点没有任何区别。

因此 trojan 工作在 443 端口也是伪装的一部分,可以增加服务的隐蔽性,因此建议不要更改 trojan 的默认工作端口。

注意:没有谁能确认 GFW 真正的工作机制,有的人改了 trojan 端口用的好好的,有的人没改还是被封,没有准确的统计数据来说明 trojan 使用 443 端口是否能真正减少封禁的几率。并且使用 trojan 协议在 443 端口也不代表永远不会被封禁,就可以高枕无忧、一劳永逸了。每种协议新出的时候大家都是充满了乐观,但是 GFW 的检测手段也在不断进化,有可能 GFW 已经检测出流量异常只不过没下手罢了。如果滥用节点,比如拿来开机场,或者发表一些敏感言论,被封禁的风险就会大大增加,甚至请你过去喝茶。此外特殊敏感时期的无差别封禁也有可能误伤到你的 VPS。

那么有没有让 trojan 和 Nginx 公用 443 端口的办法呢?一番搜索之后得到了肯定的答案——利用 TLS 握手阶段的 SNI 信息将流量在 4 层进行转发。关于 SNI 转发的工作原理请看程小白的这篇文章 Trojan 共用 443 端口方案

前置环境:

  1. 已经使用 Jrohy 的一键脚本 安装了 trojan 和 trojan web 管理程序,trojan 所使用的域名为 free.kiku.vip, 访问 https://free.kiku.vip 看到的 trojan web 管理面板。trojan 搭建过程可以参考看我的这篇博客[在 VPS 上快速搭建 trojan 服务](https://kiku.vip/2021/10/16/在 VPS 快速搭建 trojan 服务/)
  2. 安装好 Nginx,并添加了两个站点 kiku.vipfree.kiku.vip,如果没有安装过 Nginx,可以直接在宝塔面板的应用商店搜索 Nginx 安装即可。

image-20211017193404608

想要达到的目标:free.kiku.vip 还是用用来使用 trojan 代理服务,直接访问 https://free.kiku.vip 看到的是伪装站点,访问 https://free.kiku.vip/admin 才是 trojan web 管理面板。除了 free.kiku.vip 外的 *.kiku.vip 访问到正常的 HTTPS 服务,如果通过 HTTP 协议访问则强制跳转到 HTTPS。服务端除了 80 和 443 端口,其余端口关闭。

image-20211017193845759

具体的配置步骤:

  1. 为 Nginx 设置 SNI 识别转发,如果是通过宝塔安装的 Nginx,配置文件路径在:/www/server/nginx/conf/nginx.conf
    在配置文件的 events 和 http 模块之间添加下面的内容。

    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
    # 流量转发核心配置
    stream {
    # 这里就是 SNI 识别,将域名映射成一个配置名
    map $ssl_preread_server_name $backend_name {
    *.kiku.vip web;
    free.kiku.vip trojan;
    # 域名都不匹配情况下的默认值
    default web;
    }

    # web,配置转发详情
    upstream web {
    server 127.0.0.1:4431;
    }
    # trojan,配置转发详情
    upstream trojan {
    server 127.0.0.1:4432;
    }

    # 监听 443 并开启 ssl_preread
    server {
    listen 443 reuseport;
    listen [::]:443 reuseport;
    proxy_pass $backend_name;
    ssl_preread on;
    }
    }

    也可以直接在宝塔面板 Nginx 管理中直接修改配置。

    image-20211017175843811

  2. 修改 trojan 的监听地址和端口号以及如果识别为非 trojan 流量的回落端口号,trojan配置文件路径为 /usr/local/etc/trojan/config.json
    下面是配置文件的关键内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "run_type": "server",
    "local_addr": "127.0.0.1",
    "local_port": 4432,
    "remote_addr": "127.0.0.1",
    "remote_port": 82,

    ......
    }
  3. 修改 free.kiku.vip 的站点的 Nginx 配置文件,文件路径为 /www/server/panel/vhost/nginx/free.kiku.vip.conf
    下面是配置文件的完整内容:

    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
    server
    {
    listen 127.0.0.1:82;
    listen 80;

    server_name free.kiku.vip;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/free.kiku.vip;

    # 80 端口的访问强制跳转到 https 443
    if ($server_port = 80){
    rewrite ^(/.*)$ https://$host$1 permanent;
    }

    # 后台管理页面,通过 free.kiku.vip/admin 访问
    location /admin {
    proxy_pass http://localhost:81/;
    }

    # 由于 trojan web 前端的部分资源是写在二进制中的,这些资源的访问路径固定
    location ~* ^/(static|common|auth|trojan)/ {
    proxy_pass http://localhost:81;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    }
    }

    也可以选择直接在宝塔面板中修改站点的配置文件。

    image-20211017175540571

  4. 修改 kiku.vip 的站点的 Nginx 配置文件,文件路径为 /www/server/panel/vhost/nginx/kiku.vip.conf
    下面是配置文件的关键内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server
    {
    listen 80;
    listen 4431 ssl http2;
    server_name kiku.vip;

    # http 强制跳转到 https
    if ($server_port !~ 443){
    rewrite ^(/.*)$ https://$host$1 permanent;
    }
    }
  5. 修改 trojan web 管理面板的监听端口号为 81,trojan web 的配置文件路径为 /etc/systemd/system/trojan-web.service
    下面是配置文件的完整内容,和原版配置区别在于第 9 行结尾使用 -p 指定了端口号。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [Unit]
    Description=trojan-web
    Documentation=https://github.com/Jrohy/trojan
    After=network.target network-online.target nss-lookup.target mysql.service mariadb.service mysqld.service docker.service

    [Service]
    Type=simple
    StandardError=journal
    ExecStart=/usr/local/bin/trojan web -p 81
    ExecReload=/bin/kill -HUP \$MAINPID
    Restart=on-failure
    RestartSec=3s

    [Install]
    WantedBy=multi-user.target
  6. 配置完毕后重启 Nginx 和 trojan,让配置生效。

    1
    2
    service nginx restart
    trojan restart

参考

  1. trojan 官方文档
  2. trojan 多用户管理部署程序 Wiki
  3. Trojan 共用 443 端口方案
  4. Trojan+Nginx+WordPress个人博客,共用443端口!所有访问全部开启HTTPS,Trojan终极伪装!
  5. 一键安装 trojan v2ray xray. Install v2ray / xray (VLESS) and trojan (trojan-go) script