Docker环境下Traefik+Cloudflared全严格隧道安全配置咨询
方案一:分离容器的安全通信(推荐)
无需合并Traefik与cloudflared容器,利用Docker网络服务发现+自定义SAN证书即可解决TLS验证问题,符合容器单一职责原则。
1. 重新生成Cloudflare Origin CA证书
在Cloudflare控制台的SSL/TLS > Origin Server页面,重新生成证书,添加以下SAN(Subject Alternative Name):
- 你的公网域名/泛域名(如
*.example.com) - Docker服务名
traefik(容器间通信的解析名称) - VM私有IP
172.16.10.11 - 可选:
localhost(后续调试用)
下载生成的证书(cert.pem)和私钥(key.pem),上传到Traefik的traefik-data卷中。
2. 配置Traefik加载证书
修改Traefik的动态配置文件dynamic_conf.yml,添加TLS证书配置:
tls: certificates: - certFile: /etc/traefik/cert.pem keyFile: /etc/traefik/key.pem
3. 调整Cloudflare隧道目标
在Cloudflare隧道的Public Hostname配置中,将服务目标改为https://traefik:443(Docker网络中可通过服务名直接解析到Traefik容器)。
4. 清理Traefik不安全配置
移除Traefik命令中的--serverstransport.insecureskipverify参数(若无需跳过其他后端服务的TLS验证)。
此时cloudflared通过Docker网络访问Traefik,使用包含服务名SAN的Cloudflare证书完成TLS验证,无需禁用安全检查。
方案二:合并cloudflared到Traefik容器(可行但不推荐)
自托管场景下技术上可行,但违背容器单一职责原则,不利于维护和升级。实现步骤如下:
1. 自定义Traefik镜像
创建Dockerfile,基于官方Traefik镜像安装cloudflared:
FROM traefik:latest # 安装cloudflared RUN apt-get update && apt-get install -y wget && \ wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 && \ chmod +x cloudflared-linux-amd64 && \ mv cloudflared-linux-amd64 /usr/local/bin/cloudflared && \ apt-get remove -y wget && apt-get clean && rm -rf /var/lib/apt/lists/*
2. 编写双服务启动脚本
创建start.sh脚本,同时启动Traefik和cloudflared:
#!/bin/bash # 启动Traefik后台运行 traefik & # 启动cloudflared后台运行 cloudflared tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN} & # 等待所有进程防止容器退出 wait
给脚本添加执行权限:chmod +x start.sh
3. 修改Docker Compose配置
替换Traefik镜像为自定义构建版本,挂载启动脚本并传入cloudflared token:
traefik: build: . # 使用当前目录的Dockerfile构建镜像 command: /start.sh ports: - "8080:8080" - "443:443" - "80:80" networks: - proxy_network volumes: - /var/run/docker.sock:/var/run/docker.sock - traefik-data:/etc/traefik - ./start.sh:/start.sh # 挂载启动脚本 environment: - CLOUDFLARED_TOKEN=${CLOUDFLARED_TOKEN} # 传入cloudflared隧道token labels: - traefik.enable=true - traefik.docker.network=proxy_network - traefik.http.routers.traefik.rule=Host(`${DOMAINNAME_TRAEFIK}`) - traefik.http.routers.traefik.entrypoints=web - traefik.http.routers.traefik.service=traefik - traefik.http.services.traefik.loadbalancer.server.port=8080 # 移除原有的tunnel服务
4. 配置隧道与证书
在Cloudflare隧道中,将服务目标改为https://localhost:443;同时确保之前生成的Origin CA证书包含localhost作为SAN,这样cloudflared在容器内访问Traefik时能通过TLS验证。
自托管场景可行性分析
- 方案一(分离容器):完全可行,是生产环境的最佳实践。容器分离便于单独升级、监控和故障排查,Docker网络的服务发现机制天然支持安全的容器间通信。
- 方案二(合并容器):技术上可实现,但会增加容器复杂度,比如日志混合、资源隔离性差、升级时需兼顾两个服务的兼容性,仅适合测试场景或特殊需求。
内容的提问来源于stack exchange,提问作者Bernd Verhofstadt

