Skip to content
Go back

使用 Caddy (layer4) 和 Trojan-Go 搭建 Trojan 节点

| 0 Views Edit page

前言

使用 Caddy (layer4) 和 GOST 搭建 HTTPS 代理的基础上更进一步,搭建日常使用的 Trojan 节点。


方案概述

  1. 安装 Caddy 并获取 TLS 证书
  2. 使用 Docker 启动 Trojan-Go 以创建 Trojan 节点
  3. 配置 systemd.path 来监控 TLS 证书的变化并重启 Trojan-Go 容器
  4. 配置 Caddy 进行 443 端口的分流
  5. 开启 BBR 拥塞控制算法以提升网络性能

详细步骤

一、安装 Caddy 并获取 TLS 证书

首先去域名注册商处将你的域名解析到服务器的 IP 地址上,并确保服务器的 80 和 443 端口对外开放,以便 Caddy 能够成功申请 TLS 证书。
安装 Caddy 的话,可以参考官方文档:安装 Caddy

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

然后在 /etc/caddy/Caddyfile 中添加以下配置:

nano /etc/caddy/Caddyfile
# 替换为你的域名
yourdomain.com {
    respond "ok" 200
}

保存后,重启 Caddy 服务:

sudo systemctl reload caddy
sudo systemctl restart caddy

此时访问 https://yourdomain.com 应该能看到 “ok” 的响应,并且 Caddy 已经成功申请了 TLS 证书。
而证书则在 /var/lib/caddy/.local/share/caddy/certificates 目录下,文件名通常是 yourdomain.com.crtyourdomain.com.key

ls /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.com/*

二、使用 Docker 启动 Trojan-Go 以创建 Trojan 节点

安装 Docker 参考:Ubuntu 20.04 从官方源安装最新的 Docker
我们需要先创建 Trojan-Go 运行所需的配置文件,创建目录并编辑配置:

sudo mkdir -p /etc/trojan-go
sudo nano /etc/trojan-go/config.json
{
  "run_type": "server",
  "local_addr": "0.0.0.0",
  "local_port": 9443,
  "remote_addr": "httpforever.com",
  "remote_port": 80,
  "password": ["your_awesome_password"],
  "ssl": {
    "cert": "/certs/yourdomain.com.crt",
    "key": "/certs/yourdomain.com.key",
    "sni": "yourdomain.com"
  },
  "mux": {
    "enabled": true,
    "concurrency": 8,
    "idle_timeout": 60
  },
  "websocket": {
    "enabled": false
  }
}

需要注意的几项:

  • remote_addrremote_port:伪装的目标地址和端口,我这里指向了 httpforever.com 的 80 端口。
  • password:客户端连接时所需的认证密码,建议设置一个强密码。
  • ssl:指定 TLS 证书和私钥的路径,这里我们挂载 Caddy 管理的证书目录到容器内的 /certs,并在配置中引用它们。
  • mux:开启多路复用以提升性能。
  • websocket:不开启 WebSocket 支持。

更多配置项参考官方文档:完整的配置文件

启动 Trojan-Go 容器的话就简单一些,不用 docker compose,直接用 docker run 了:

# 启动容器
docker run -d \
    --name trojan \
    --restart unless-stopped \
    -p 9443:9443 \
    -v /etc/trojan-go/:/etc/trojan-go \
    -v /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.com/:/certs \
    p4gefau1t/trojan-go

启动完成后,在任意客户端尝试连接一下这个 Trojan 节点,理论上应该是可用的。
如果不可用的话,依次排查云服务器安全组是否放开了 9443 端口、云服务器防火墙是否放开了 9443 端口(一般默认没问题)、Trojan-Go 容器日志(使用 docker logs trojan 查看)等。

如果出现了以下错误:

[FATAL] 2026/04/17 12:50:09 github.com/p4gefau1t/trojan-go/proxy.(*Option).Handle:option.go:78 invalid character ’}’ looking for beginning of object key string

不一定是你的配置项目有问题,也有可能是你的配置文件不是标准的 JSON 格式,例如多注释或是多了逗号等。

三、配置 systemd.path 来监控 TLS 证书的变化并重启 Trojan-Go 服务

关于 systemd.path:提供了监控文件、目录变化并触发执行指定操作的功能。
它支持 PathExistsPathChangedPathModified 等事件,可以监控文件的创建、修改、删除等操作。

我们会创建两个 systemd 单元文件:

  • trojan-cert-watch.path:监控 TLS 证书文件的变化
  • trojan-restart.service:当证书变化时重启 Trojan-Go 服务

首先创建 trojan-cert-watch.path

sudo nano /etc/systemd/system/trojan-cert-watch.path
[Unit]
Description=Watch Trojan-Go certificate changes

[Path]
PathChanged=/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.com
Unit=trojan-restart.service

[Install]
WantedBy=multi-user.target

然后创建 trojan-restart.service

sudo nano /etc/systemd/system/trojan-restart.service
[Unit]
Description=Restart Trojan-Go container
Wants=docker.service
After=docker.service

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/docker restart trojan

保存后,启用并启动 trojan-cert-watch.path

sudo systemctl daemon-reload
sudo systemctl enable --now trojan-cert-watch.path

这样当 Caddy 自动续签 TLS 证书时,trojan-cert-watch.path 会检测到证书文件的变化并触发 trojan-restart.service 来重启 Trojan-Go 容器,从而确保 HTTPS 代理始终使用最新的 TLS 证书。

四、配置 Caddy 进行 443 端口的分流

Caddy 原生并不支持直接对 TCP 流量进行操作,但我们可以通过安装 caddy-l4 插件来实现 TCP 分流功能:

# 直接使用 caddy add-package 命令安装插件
sudo caddy add-package github.com/mholt/caddy-l4
# 安装完重启 Caddy 服务
sudo systemctl restart caddy

然后在 /etc/caddy/Caddyfile 中添加以下配置来实现分流:

{
    # 全局配置,指定 ACME 证书颁发机构为 Let's Encrypt
    cert_issuer acme {
        dir https://acme-v02.api.letsencrypt.org/directory
    }

    servers :443 {
        listener_wrappers {
            layer4 {
                # 匹配 SNI 为 yourdomain.com 的流量,转发到 Trojan-Go 监听的 9443 端口
                @trojan tls sni yourdomain.com
                route @trojan {
                    proxy tcp/127.0.0.1:9443
                }

                route {
                }
            }
            tls
        }
    }
}

如果有多条分流规则,可以继续添加更多的 @matcherroute 来实现不同域名的分流,参考:

{
    # 全局配置,指定 ACME 证书颁发机构为 Let's Encrypt
    cert_issuer acme {
        dir https://acme-v02.api.letsencrypt.org/directory
    }

    servers :443 {
        listener_wrappers {
            layer4 {
                # 匹配 SNI 为 yourdomain2.com 的流量,转发到 GOST 监听的 8443 端口
                @gost tls sni yourdomain2.com
                route @gost {
                    proxy tcp/127.0.0.1:8443
                }

                # 匹配 SNI 为 yourdomain.com 的流量,转发到 Trojan-Go 监听的 9443 端口
                @trojan tls sni yourdomain.com
                route @trojan {
                    proxy tcp/127.0.0.1:9443
                }

                route {
                }
            }
            tls
        }
    }
}

修改完后,验证文件有效性:

sudo caddy validate --config /etc/caddy/Caddyfile

没问题的话就重载配置:

sudo caddy reload --config /etc/caddy/Caddyfile

需要注意的是,这么设置后 Caddy 会根据 SNI 域名将 TLS 连接原样转发到 Trojan-Go,真正的 HTTPS/TLS 终止将只发生在 Trojan-Go 上。 造成的结果就是,再次尝试在浏览器上访问 https://yourdomain.com 时,不会得到 Caddy 的 “ok” 响应,而是会直接被转发到 Trojan-Go,于是你就看到了伪装的 httpforever.com 的页面内容。

最后就目前的情况进行总结:

  • Caddy 用 Let’s Encrypt 管理 TLS 证书,并自动续签
  • Trojan-Go 使用 Caddy 管理的 TLS 证书来提供 Trojan 服务
  • systemd.path 监控 TLS 证书的变化并自动重启 Trojan-Go 服务
  • Caddy 通过 caddy-l4 插件实现 TCP 分流,将 yourdomain.com 的 HTTPS 流量(443 端口)转发到 Trojan-Go 上(9443 端口)

五、开启 BBR 拥塞控制算法以提升网络性能

我的云服务器系统为 Ubuntu 22.04,默认内核版本是 6.80,已经内置了 BBR 拥塞控制算法,直接启用即可:

# BBR 需要 Linux 内核版本 4.9 或更高版本
uname -r

# 设置默认队列规则为 fq
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
# 设置 TCP 拥塞控制算法为 bbr
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
# 应用配置
sysctl -p

# 验证 BBR 是否启用成功
sysctl net.ipv4.tcp_congestion_control
sysctl net.core.default_qdisc
lsmod | grep bbr

详细的测速对比可以看我的另一篇文章:Trojan、Trojan-Go 和开启 BBR 后的测速对比

结束。


Edit page