Traefik仅安全连接返回404问题排查求助
问题描述
出于安全考虑从Nginx Proxy Manager迁移到Traefik,完成初始配置后出现以下异常:
- 启动服务栈后,以下访问均返回404:
https://traefik.example.comhttps://serverip:443http://serverip:80https://whoami.example.com
- 仅能通过
http://serverip:8080(因设置insecure=true)以非安全方式访问Traefik仪表盘 - 移除whoami服务标签中的
- traefik.http.routers.whoami-https.entrypoints=websecure后,http://whoami.example.com和https://whoami.example.com均可正常访问 - 需求:仅通过
websecure入口访问Traefik仪表盘及服务,日志无报错
配置文件
docker-compose.yml
services: traefik: image: traefik:v2.10 container_name: traefik restart: always networks: - proxy ports: - 80:80 - 8080:8080 - 443:443 volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/configs:/configs:ro - ./data/acme.json:/acme.json:rw - ./data/logs:/logs:rw environment: - CF_DNS_API_TOKEN=${CFAPI} read_only: true security_opt: - no-new-privileges=true labels: - traefik.enable=true - traefik.http.routers.traefik-https.entrypoints=websecure - traefik.http.routers.traefik-https.rule=Host(`traefik.example.com`) - traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIKADMIN} - traefik.http.routers.traefik-https.middlewares=traefik-auth - traefik.http.routers.traefik-https.service=api@internal - traefik.http.routers.traefik-https.tls=true - traefik.http.routers.traefik-https.tls.certresolver=letsencrypt - traefik.http.routers.traefik-https.tls.domains[0].main=example.com - traefik.http.routers.traefik-https.tls.domains[0].sans=*.example.com whoami: image: containous/whoami:latest container_name: whoami hostname: whoami restart: unless-stopped networks: - proxy labels: - traefik.enable=true - traefik.http.routers.whoami-https.entrypoints=websecure - traefik.http.routers.whoami-https.rule=Host(`whoami.example.com`) #- traefik.http.routers.whoami-https.service=whoami - traefik.http.services.whoami-https.loadbalancer.server.port=80 - traefik.http.routers.whoami-https.tls=true - traefik.http.routers.whoami-https.tls.certresolver=letsencrypt networks: proxy: external: {}
traefik.yml
api: dashboard: true insecure: true debug: true entryPoints: web: address: ":80" websecure: address: ":443" http: tls: {} providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false defaultRule: "Host(`{{ index .Labels \"com.docker.compose.service\"}}.example.com`)" network: proxy file: directory: "/configs" watch: true certificatesResolvers: http: acme: email: cert@example.com storage: acme.json httpChallenge: entryPoint: web letsencrypt: acme: email: cert@example.com storage: acme.json dnsChallenge: provider: cloudflare resolvers: - "1.1.1.1:53" - "8.8.8.8:53" #serversTransport: # insecureSkipVerify: false accessLog: filePath: "/logs/access.log" fields: headers: names: User-Agent: keep log: filePath: "/logs/traefik.log" level: INFO
排查与修复步骤
1. 修复whoami路由与服务的关联
你注释了traefik.http.routers.whoami-https.service=whoami,但自定义了服务名为whoami-https(通过traefik.http.services.whoami-https.loadbalancer.server.port=80),导致路由找不到对应的服务,必须显式指定服务名:
# 在whoami的labels中取消注释并修改服务名 - traefik.http.routers.whoami-https.service=whoami-https
2. 检查acme.json文件权限
Traefik要求acme.json的权限必须为600,否则无法写入证书,执行以下命令修复:
chmod 600 ./data/acme.json
3. 移除websecure入口的默认TLS配置
你在traefik.yml的websecure入口中配置了http.tls: {},这会让Traefik尝试使用默认证书,干扰指定的certresolver=letsencrypt证书生成流程,删除该部分:
# 修改后的entryPoints配置 entryPoints: web: address: ":80" websecure: address: ":443"
4. 验证Cloudflare API Token权限
确保CF_DNS_API_TOKEN拥有Zone:DNS:Edit权限,且关联了目标域名,否则DNS挑战无法完成,证书无法生成。
5. 可选:添加web入口到websecure的重定向
若希望所有HTTP请求自动重定向到HTTPS,在traefik的labels中添加以下配置:
# 新增重定向中间件 - traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https # 给web入口添加路由,应用重定向 - traefik.http.routers.traefik-web.entrypoints=web - traefik.http.routers.traefik-web.rule=Host(`traefik.example.com`) - traefik.http.routers.traefik-web.middlewares=redirect-to-https
6. 重启服务栈
修改配置后,重启Traefik和whoami服务:
docker-compose down && docker-compose up -d
验证
完成以上步骤后,https://traefik.example.com和https://whoami.example.com应可正常访问;若配置了重定向,HTTP请求会自动跳转至HTTPS;http://serverip:8080仍可访问非安全仪表盘(若不需要可将insecure: true改为false)。
内容的提问来源于stack exchange,提问作者AdhityaRavi

