he-sb / tech

My blog related to technique.
MIT License
9 stars 2 forks source link

docker compose 一条龙配置 TUIC 代理 #53

Closed he-sb closed 1 year ago

he-sb commented 1 year ago

配置服务端

目录结构:

tuic
├── config-server.json
├── docker-compose.yml
├── gen_cert.yml
└── ssl
   ├── example.com.k8s.conf
   ├── example.com.k8s.crt
   └── example.com.k8s.key

其中需要手动准备的只有三个文件,复制粘贴后文内容即可。

文件内容

  1. config-server.json 服务端配置文件(TUIC 是区分服务端和客户端的,配置不通用,程序也不通用,不要搞错了):
    {
    "server": "0.0.0.0:443",
    "users": {
        "xxxxxxx-yyyyyyy-zzzzzzzzzzzz": "password"
    },
    "certificate": "/root/ssl/example.com.k8s.crt",
    "private_key": "/root/ssl/example.com.k8s.key",
    "congestion_control": "bbr",
    "log_level": "info"
    }
    • 字段释义
    • server 监听地址和端口
      • 地址部分,因为本文使用 docker 部署服务,对于容器内的 tuic 进程来说,需要监听 0.0.0.0 地址才可以
      • 如果是直接在宿主机上运行 tuic 程序,那么一般来说也是要监听 0.0.0.0 ,除非有前置的分流 / 伪装措施,比如 caddy,nginx 之类的,不过有这种操作的大佬一般也不需要看这篇教程了。。
      • 端口部分,因为本文使用 docker 的 host 网络模式来部署,所以这里的端口就是宿主机端口
      • 如果不使用 host 网络模式,比如默认的 bridge 模式,那么这里定义的端口其实是【容器内】的 tuic 进程监听的端口,随便填写一个就行,只需要确保映射到宿主机的端口是 443 就可以了
      • 其实也可以不是 443 ,但是因为 TUIC 协议的流量特征是 QUIC 协议,如果不是跑在 443 端口上,目标会比较明显
    • users 用户
      • 可以定义多个,不过自用的服务一般定义一个就行
      • xxxxxxx-yyyyyyy-zzzzzzzzzzzz 需要替换为一个合法的 UUID
      • 可以在这个网站在线生成: https://www.uuidgenerator.net/
      • password 需要替换为一个自定义密码
    • certificate 证书文件路径
      • 证书文件所在的目录,下文 docker compose 编排文件中会将它映射出来
    • private_key 私钥文件路径
      • 私钥文件所在的目录,下文 docker compose 编排文件中会将它映射出来
    • congestion_control 拥塞控制算法
      • 没有特殊需求的话, bbr 就可以
    • log_level 日志等级
      • 没有特殊需求的话, info 就可以
      • 可以在 tuic 目录下执行 docker compose logs -f 来查看日志
  2. docker-compose.yml tuic 服务端运行使用的 docker compose 编排文件:
    
    version: '3'

x-common: &default restart: unless-stopped logging: driver: 'json-file' options: max-size: '10m' environment: &default-environment TZ: Asia/Shanghai

services: tuic-server: <<: *default container_name: tuic-server

https://github.com/kilvn/tuic-server-docker

image: kilvn/tuic-server:1.0.0
network_mode: host
volumes:
  - ./config-server.json:/etc/tuic/config.json:ro
  - ./ssl:/root/ssl:ro
  - 字段释义
    - `./config-server.json:/etc/tuic/config.json:ro`
      - 将 tuic 服务端配置文件映射至容器内
      - 第一个冒号左边是宿主机路径,可按需修改
    - `./ssl:/root/ssl:ro`
      - 将证书和私钥所在的文件夹映射至容器内
      - 第一个冒号左边是宿主机路径,可按需修改
3. `gen_cert.yml` 生成自签名证书使用的 docker compose 编排文件(仅用于生成自签名证书,执行完毕后会自行退出):
```yaml
version: '3'

services:
  certs-maker:
      # https://soulteary.com/2022/10/22/make-docker-tools-image-with-only-3md-self-signed-certificate-certs-maker.html
      image: soulteary/certs-maker:v3.1.0
      environment:
        CERT_DNS: 'example.com'
        USER: he-sb
        UID: '1000'
        GID: '1000'
        FOR_K8S: 'on'
      volumes:
        - ./ssl:/ssl

启动服务

以下命令均需在 tuic 目录下执行:

  1. 首先执行 docker compose -f gen_cert.yml up ,执行完毕后容器会自行退出。查看 ssl 路径下应该出现生成好的证书文件(参考本文开头的【目录结构】部分)
  2. 执行 docker compose up -d ,此时不出意外的话 tuic 服务应该已经跑起来了

最后防火墙记得放行一下 443 端口(注意是 UDP 协议,不是 TCP)

he-sb commented 1 year ago

配置客户端

1. Linux

和服务端几乎一样(废话,反正都是 docker compose 一把梭),先简单看下目录结构:

tuic
├── config_client.json
├── docker-compose.yml
└── ssl
   ├── example.com.k8s.crt

准备文件:

  1. config_client.json 客户端配置文件
    {
    "relay": {
        "server": "example.com:443",
        "uuid": "xxxxxxx-yyyyyyy-zzzzzzzzzzzz",
        "password": "password",
        "ip": "xxx.xxx.xxx.xxx",
        "certificates": [
            "/root/ssl/example.com.k8s.crt"
        ],
        "congestion_control": "bbr"
    },
    "local": {
        "server": "0.0.0.0:50000"
    },
    "log_level": "info"
    }
    • 字段释义
    • server 服务端域名和端口
      • example.com 替换为证书对应的域名
      • 端口默认保持 443 不需要改,如果服务端监听了其他端口,这里需要和服务端一致
    • uuid 用户名
      • xxxxxxx-yyyyyyy-zzzzzzzzzzzz 替换为和服务端配置中相同的 UUID
    • password 密码
      • password (冒号右侧的部分)替换为和服务端配置中相同的密码
    • ip 服务器 IP
      • 不同于域名(不一定要真实域名),此处的 IP 必须是真实的服务器 IP
      • 这项配置的作用是,当【使用自签名证书,且自签名证书对应的域名无法在公网解析至服务器 IP】的时候,手动指定服务端所在的 IP,使客户端能正确连接上服务端
      • 如果域名(无论证书是不是自签名的)能够在公网解析到服务器 IP,那么 ip 这一行配置可以直接删掉,使用系统 DNS 解析域名
    • certificates 证书文件路径
      • 证书文件所在的目录,下文 docker compose 编排文件中会将它映射出来
    • congestion_control 拥塞控制算法
      • 没有特殊需求的话, bbr 就可以
    • local 本地监听配置
      • server 本地监听的地址和端口
      • 客户端启动后,会在本地启动一个 socks5 协议的代理服务,供其他客户端连接使用,此处定义的是这个本地的 socks5 监听的地址和端口
      • 地址部分,因为本文使用 docker 部署,对于容器内的 tuic 进程来说,需要监听 0.0.0.0 ,否则局域网其他机器无法链接这个 sock5 代理(包括宿主机本身)
      • 端口部分,因为本文使用 docker 的 host 网络模式来部署,所以这里的端口就是宿主机端口
        • 如果不使用 host 网络模式,比如默认的 bridge 模式,那么这里定义的端口其实是【容器内】的 tuic 进程监听的端口,随便填写一个就行,只需要注意映射到宿主机的端口是其他程序连接的 socks5 端口就可以了
    • log_level 日志等级
      • 没有特殊需求的话, info 就可以
      • 可以在 tuic 目录下执行 docker compose logs -f 来查看日志
  2. docker-compose.yml 客户端 docker compose 编排文件
    
    version: '3'

x-common: &default restart: unless-stopped logging: driver: 'json-file' options: max-size: '10m' environment: &default-environment TZ: Asia/Shanghai

services: tuic-client: <<: *default container_name: tuic-client

https://github.com/kilvn/tuic-client-docker

image: kilvn/tuic-client:1.0.0
network_mode: host
volumes:
  - ./config_client.json:/etc/tuic/config.json:ro
  - ./ssl:/root/ssl:ro

  - 字段释义
    - `./config_client.json:/etc/tuic/config.json:ro`
      - 将 tuic 客户端配置文件映射至容器内
      - 第一个冒号左边是宿主机路径,可按需修改
    - `./ssl:/root/ssl:ro`
      - 将证书所在的文件夹映射至容器内
      - 第一个冒号左边是宿主机路径,可按需修改
3. `ssl/example.com.k8s.crt` 服务端证书文件
  - 直接将服务端的证书文件复制过来即可

### 2. Android(以 [NekoBoxForAndroid](https://github.com/MatsuriDayo/NekoBoxForAndroid) 为例)

首先安装 APP,安装包在项目 [Releases](https://github.com/MatsuriDayo/NekoBoxForAndroid/releases) 内自取

然后安装 [tuic 插件](https://github.com/MatsuriDayo/plugins/releases?q=tuic)

完毕后打开手机上的 NekoBox,点击右上角的加号,选择“手动输入 -> TUIC”:
- `配置名称`
  - 随便起一个名字
- `协议版本`
  - 保持默认的 `5` 不用修改
- `服务器`
  - 如果服务端是按照本文使用自签名证书搭建的,此处填写服务器 IP
  - 如果服务端证书对应的域名可以在公网解析至服务器 IP,此处可以填写服务端域名
- `服务器端口`
  - 和服务端配置保持一致(一般为 `443` )
- `用户 ID`
  - 服务端配置中的 UUID
- `密码`
  - 服务端配置中的密码
- `应用层协议协商`
  - 留空(默认)即可
- `证书(链)`
  - 如果服务端是按照本文使用自签名证书搭建的,那么使用文本编辑器打开服务端的证书文件(后缀名为 `crt` 的文件),将其中的内容完整粘贴至此处
  - 如果服务端的证书是通过别的途径自动申请的(此场景下域名应该也是公网可解析的真实域名),那么此处不需要配置
- `UDP 转发模式`
  - 没有特殊需求的话,保持默认的 `NATIVE` 即可
- `拥塞控制`
  - 没有特殊需求的话, `BBR` 就可以
- `禁用 SNI`
  - 没有特殊需求的话,保持默认的关闭状态即可
- `服务器名称指示`
  - 填写服务端证书对应的域名(无论证书是不是自签名的)
- `启用 0-RTT QUIC 握手`
  - 没有特殊需求的话,保持默认的关闭状态即可
- `允许不安全的连接`
  - 无论任何情况,都建议保持默认的关闭状态
- `自定义配置`
  - 没有特殊需求的话,留空即可

编辑完成后点击右上角的对号,保存即可使用了

还有一个小问题: TUIC 协议的代理,在使用 `连接测试` 功能时,会无法获取测试结果
- `TCPing` 会直接不显示延迟(这是当然的,因为 TUIC 协议是基于 UDP 的)
- `URL Test` 会显示 `连接重置`

目前暂不清楚是 NB4A 的 bug,还是是 TUIC 协议的原理限制导致的

不过这个问题不影响使用,实际开启代理后,点击界面下方的 `已连接,点击此处测试连接` 这里,是能正常显示 HTTP 握手耗时的,代理本身也能正常工作

---

其他平台,以及其他客户端的配置方法请自行摸索~