暮光博客

小心你讨厌的东西,因为你很可能被它塑造成某种形状

Docker + Trojan + Caddy 部署

技术 36 条评论

关于 Trojan,不要多问,问就是代理工具。它先进的地方在于,数据传输使用 TLS 协议,伪装成 HTTPS 请求。Trojan 服务端监听 443 端口,对于普通来路的请求,会交由 Web 服务器处理,返回 Web 网站;而对于 Trojan 客户端来的请求,则由 Trojan 服务端进行代理。这跟 某2ray + Websocket + TLS 原理是一样的,都是通过伪装流量,避免被提取特征或是被检测。

这篇文章里,我将使用 Ubuntu 18.04 操作系统,使用 Caddy 作为 Web 服务器,将 Trojan 服务端和 Caddy 部署到 Docker 中。

0、准备

  • 域名 x1
  • 国外服务器 x1

部署前先给域名设置一条 A 记录,并指向你的服务器 IP。

1、安装 Docker & Docker-Compose

  • 添加 Docker 软件源

    sudo apt-get update
    sudo apt-get install apt-transport-https ca-certificates  curl software-properties-common
    curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
    
  • 安装 Docker CE(社区版)

    sudo apt-get update -y
    sudo apt-get install docker-ce -y
  • 安装 Docker-compose 容器编排工具

    sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    docker-compose --version

2、构建 Trojan + Caddy 镜像

我已经写好了 Docker compose 的构建脚本,直接克隆下来用即可。

  • 下载 Trojan + Caddy 构建配置,见 GitHub
    git clone git@github.com:FaithPatrick/trojan-caddy-docker-compose.git trojan-caddy-docker-compose && cd trojan-caddy-docker-compose
  • 编辑 ./caddy/Caddyfile

    www.yourdomain.com:80 {
        root /usr/src/trojan
        log /usr/src/caddy.log
        index index.html
    }
    
    www.yourdomain.com:443 {
        root /usr/src/trojan
        log /usr/src/caddy.log
        index index.html
    }

    www.yourdomain.com 替换成事先准备的域名。

  • 编辑 ./trojan/config/config.json
    config:json:8 位置,将 your_password 替换成要设置的密码,这是客户端需要用到的密码,妥善保管。

    config:json:12-13 位置将 your_domain_name 替换成自己的域名, 这个路径是 Caddy 自动调用 Let's encrypt 生成的证书路径。

    • 执行 docker-compose build 构建镜像,如果没什么报错就代表成功了。

3、运行 Trojan + Caddy 容器

执行 docker-compose up 命令启动容器,正常启动的日志应该看起来是这样的:

➜ docker-compose up

Starting test_caddy_1 ... done
Attaching to test_caddy_1
caddy_1  | Activating privacy features...
caddy_1  |
caddy_1  | Your sites will be served over HTTPS automatically using Let's Encrypt.
caddy_1  | By continuing, you agree to the Let's Encrypt Subscriber Agreement at:
caddy_1  |   https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
caddy_1  | Please enter your email address to signify agreement and to be notified
caddy_1  | in case of issues. You can leave it blank, but we don't recommend it.
caddy_1  |   Email address: 2020/01/10 13:54:58 [INFO] acme: Registering account for
caddy_1  | 2020/01/10 13:54:58 [INFO][xx.xx.xx] acme: Obtaining bundled SAN certificate
caddy_1  | 2020/01/10 13:54:58 [INFO][xx.xx.xx] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/xxxxxx
caddy_1  | 2020/01/10 13:54:58 [INFO][xx.xx.xx] acme: Trying to solve HTTP-01
caddy_1  | 2020/01/10 13:54:58 [INFO][xx.xx.xx] Served key authentication
caddy_1  | 2020/01/10 13:54:58 [INFO][xx.xx.xx] Served key authentication
caddy_1  | 2020/01/10 13:55:03 [INFO][xx.xx.xx] The server validated our request
caddy_1  | 2020/01/10 13:55:03 [INFO][xx.xx.xx] acme: Validations succeeded; requesting certificates
caddy_1  | 2020/01/10 13:55:04 [INFO][xx.xx.xx] Server responded with a certificate.
caddy_1  | 2020/01/10 13:55:04 [INFO][xx.xx.xx] Certificate written to disk: /root/.caddy/acme/acme-v02.api.letsencrypt.org/sites/xx.xx.xx/xx.xx.xx.crt
caddy_1  | done.

Starting test_trojan_1 ... done
Attaching to test_caddy_1, test_trojan_1
trojan_1  | ssl certs is empty - checking...
trojan_1  | ssl certs is empty - checking...
trojan_1  | Welcome to trojan 1.14.0
trojan_1  | [2020-01-10 15:40:58] [WARN] trojan service (server) started at 0.0.0.0:443

如果想常驻进程,启动容器时执行 docker-compose up -d

用浏览器访问 https://域名 看一下返回,我的构建脚本默认会返回 Bootstrap 的起始页面:

20200111012712.png

网站存放在 ./wwwroot/trojan/ 目录下面 ,可以随便放点什么,尽可能像一个正常网站就好。

至此,Docker + Trojan + Caddy 服务端部署完成。

4、Trojan 客户端

不多提了,Windows 和 macOS 客户端官方仓库都有:https://url.cn/5r6mb9J
当然,你也可以去寻找更易用的支持 Trojan 的第三方客户端或路由器固件。

2020 年的愿景
评论区
选择表情选择表情
  1. liyan

    大佬请教一下,运行这条命令git clone git@github.com:FaithPatrick/trojan-caddy-docker-compose.git trojan-caddy-docker-compose && cd trojan-caddy-docker-compose 报错 Cloning into 'trojan-caddy-docker-compose'...
    The authenticity of host 'github.com (140.82.118.3)' can't be established.
    RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
    Are you sure you want to continue connecting (yes/no/[fingerprint])?
    Host key verification failed.
    fatal: Could not read from remote repository. 怎么解决?

    回复
    1. 突然
      @liyan

      git clone https://github.com/FaithPatrick/trojan-caddy-docker-compose.git trojan-caddy-docker-compose && cd trojan-caddy-docker-compose

      回复
  2. 》》》

    我那内存只有512M的服务器,死在了编译Trojan那一步。建议博主做一个Trojan镜像上传到DockerHub,吼吼

    回复
    1. trojan
      @》》》

      free -h #see your memory
      you can add some virtual memory , then:

      free -h
      ....
      Swap: 4.0Gi 0.0Ki 4.0Gi

      回复
      1. kkk
        @trojan

        Now has trojan images in docker hub, you can search trojan at github,this project at github now, I used it ago.

        回复
  3. te

    一直出现这样的错误:
    Sending telemetry (attempt 2): Post https://telemetry.caddyserver.com/v1/update/bf83e9bc-88b6-4d7f-9a99-ba28c007315a: dial tcp: lookup telemetry.caddyserver.com on 127.0.0.11:53: no such host - backing off and retrying
    是什么原因呢?

    回复
  4. Tyebile

    failed to obtain certificate: acme: error: 429 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rateLimited :: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/, url: (attempt 1/3; challenge=tls-alpn-01)

    这是官方限制了么?

    回复
    1. @Tyebile

      是的,换个域名或者过段时间再尝试。

      回复
      1. Tyebile
        @大袋鼠

        那是因为域名提供商还是域名后缀的问题。或者随机限制

        回复
        1. @Tyebile

          和域名提供商和后缀都没有关系,是你向 letsencrypt 提交太多次证书申请了,caddy 容器每次跑 443 端口发现域名没证书的话就会自动去申请。

          回复
  5. 哈哈 我发现你这篇文章 0、准备 H3标题会自动排序 我就想 为什么我的不会!

    我百度了 说是 css 计数 自动添加的

    等我搞定了 icon_cry.gif ,发现你是自己添加的。。。其他篇文章没有

    回复
  6. cutepan

    单独启动创建的两个容器,发现 Trojan 能有效的转发443网页请求 给caddy,导致https://访问不了网站,

    "remote_addr": "__DOCKER_CADDY__", "remote_port": 80,

    估计是这里问题,求修复

    回复
    1. @cutepan

      我的方案就是要用 docker-compose 来编排容器的,单独启动确实会有问题。

      回复
  7. tempoy

    你好,运行 下载 Trojan + Caddy 构建配置 的命令,提示:

    Cloning into 'trojan-caddy-docker-compose'...
    Permission denied (publickey).
    fatal: Could not read from remote repository.

    Please make sure you have the correct access rights
    and the repository exists.

    请问后面怎么操作?

    回复
    1. tempoy
      @tempoy

      用的是debian9系统

      回复
      1. @tempoy

        换这个命令 git clone https://github.com/FaithPatrick/trojan-caddy-docker-compose.git

        回复
        1. tempoy
          @大袋鼠

          你好,上面改用新给的代码已经通过了,配置完config.json后,运行docker-compose build构建镜像出错,提示:
          root@debian:~# docker-compose build
          ERROR:
          Can't find a suitable configuration file in this directory or any
          parent. Are you in the right directory?

          Supported filenames: docker-compose.yml, docker-compose.yaml

          我看了下,docker-compose.yml文件是在/root/trojan-caddy-docker-compose目录下,请问后面怎么操作呢?

          另外,我用acme.sh脚本申请了证书,我在config.json中把12.--13行的目录指定到我保存证书的路径,是可以的吧?

          回复
          1. @tempoy

            1、自己申请证书可以,但需要拷贝到 ./ssl 目录下,因为 config.json 里的证书路径指的是容器里的证书路径,宿主机的证书如果没映射到容器里,是访问不到的,我建议还是用 caddy 生成的证书,因为 caddy 也是用 acme.sh 生成的,也能自动续签。
            2、你需要进到 /root/trojan-caddy-docker-compose 目录下再执行 docker-compose build 命令。

            回复
            1. tempoy
              @大袋鼠

              你好,可以运行了,不过后面运行还是提示出错了,我换了域名也仍然一样,请看一下
              ---> Running in cb300b95864e
              fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
              WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz: network error (check Internet connection and firewall)
              fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
              WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz: network error (check Internet connection and firewall)
              ERROR: unsatisfiable constraints:
              build-base (missing):
              required by: .build-deps-0[build-base]
              cmake (missing):
              required by: .build-deps-0[cmake]
              boost-dev (missing):
              required by: .build-deps-0[boost-dev]
              openssl-dev (missing):
              required by: .build-deps-0[openssl-dev]
              mariadb-connector-c-dev (missing):
              required by: .build-deps-0[mariadb-connector-c-dev]
              git (missing):
              required by: .build-deps-0[git]
              ERROR: Service 'trojan' failed to build: The command '/bin/sh -c apk add --no-cache --virtual .build-deps build-base cmake boost-dev openssl-dev mariadb-connector-c-dev git && git clone --branch=${VERSION} https://github.com/trojan-gfw/trojan.git && (cd trojan && cmake . && make -j $(nproc) && strip -s trojan && mv trojan /usr/local/bin) && rm -rf trojan && apk del .build-deps && apk add --no-cache --virtual .trojan-rundeps libstdc++ boost-system boost-program_options mariadb-connector-c' returned a non-zero code: 7

              回复
              1. @tempoy

                构建容器时拉镜像失败了,可能 docker hub 在你的服务器上被墙了。。考虑把镜像源换成国内的,参考:https://lug.ustc.edu.cn/wiki/mirrors/help/docker

                换好后再执行 docker-compose build

                有条件的话可以联系我的 telegram:@FaithPatrick 直接在这上面问会方便一点。

                回复
  8. 咦?我可以考虑体验一下。不知道效率和v2比起来如何?我现在主要用v2。

    回复
    1. @姜辰

      理论上效率会比 v2 强些,实际上差别不大。

      回复
  9. ffrank

    博主docker增加wait_for_caddy.sh用来延迟启动Trojan,让caddy优先占用443
    申请证书,这种情况证书到期后没有办法caddy自动申请吧,443端口被Trojan占用,手动
    docker-compose down后 docker-compose up -d 重启容器再次让caddy申请证书?

    回复
    1. @ffrank

      wait_for_caddy.sh 延时启动 Trojan 不是为了让 caddy 优先占用 443 端口,而是在初次启动时,保证 caddy 先把证书申请下来,有了证书才能启动 Trojan。

      证书续期的问题,caddy 容器里有计划任务来进行证书自动续期,不用重启容器。

      回复
  10. 你好 请问那个网站的证书在哪里啊?

    回复
    1. @cutepan

      由 Caddy 容器生成,映射在 ./ssl 目录下

      回复
  11. 请问 debian 也是这样的执行思路吗?

    回复
    1. @cutepan

      一样。

      回复
  12. Musk

    有没有办法将caddy配置成强制https, 而不是分别有https和http?
    我试过在:80配置下面做redir, 但是网站会变得无法运行, 只显示 too many redirect ...

    回复
    1. @Musk

      文章里给出的配置,443 端口是由 Trojan 监听的,对于正常的 https 请求,Trojan 会转发(反向代理)到 Caddy 的 80 端口。这就是你在 80 端口下做 redir 到 443,会出现「太多重定向」的原因,无限循环了。

      你的问题可以这样解决:
      Caddyfile 里写 3 条,分别是 80、8080、443 端口(443端口不对外监听,只用来生成 https 证书),80 做 redir 到 443,8080 放网站内容。Trojan 里配置将 https 请求转发给 8080 端口。如果不想对外网暴露 8080,在 iptables 里写一下规则。

      以上操作需要变更这三个配置文件:Caddyfile、docker-compose.yml、torjan/config/config.json

      回复
  13. 不错呀,终于更新了。哈哈。我的友链帮忙改下呀,以前是frank2019.info。现在是frank2019.me

    回复
    1. @Frank

      已修改 icon_redface.gif

      回复
  14. 这工具名起的,我第一道眼球防火墙就给拦下了。

    回复
    1. @大致

      这名字起得很有灵性,把通往国外的流量装进木马里。

      回复
  15. 换主题了呀,很简洁大方。 icon_redface.gif

    回复
    1. @大大的小熊

      icon_redface.gif 好久不打理,难得改头换面一次。

      回复