Traefik与Let's Encrypt证书TLS握手失败求助
Traefik在HAProxy后配置HTTPS出现TLS握手失败问题
我在Docker环境中用Traefik做反向代理,已按官方文档配置小型Docker Compose环境,HTTP服务可正常对外提供数据。Traefik部署在HAProxy之后,HAProxy以TCP模式将互联网数据包转发至Traefik。
但新增HTTPS路由器后,执行curl https://my.domain.tld/时收到错误:error:1408F10B:SSL routines:ssl3_get_record:wrong version number
完整curl输出
curl -v https://my.domain.tld/ * Trying <IP Address of Domain>... * TCP_NODELAY set * Connected to my.domain.tld (<IP Address of Domain>) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * error:1408F10B:SSL routines:ssl3_get_record:wrong version number * Closing connection 0
Firefox访问时会收到错误码SSL_ERROR_RX_RECORD_TOO_LONG,搜索相关错误未找到匹配场景的解决方案。
Docker Compose配置
version: "3.9" secrets: cloudflare_dns_token: file: ./secrets/cf_dns_api_token.txt networks: socket_proxy: name: socket_proxy driver: bridge ipam: config: - subnet: 192.168.0.0/24 container_bridge: name: container_bridge driver: bridge ipam: config: - subnet: 192.168.1.0/24 services: socket-proxy: image: tecnativa/docker-socket-proxy container_name: socket-proxy restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: socket_proxy: ipv4_address: 192.168.0.2 # Static IP address environment: EVENTS: 1 PING: 1 VERSION: 1 CONTAINERS: 1 NETWORKS: 1 traefik: # 官方v2 Traefik镜像 image: traefik:v2.8.1 container_name: traefik-proxy command: # Traefik日志级别 - "--log.level=DEBUG" # 启用Web UI - "--api.insecure=true" # 启用Docker服务发现 - "--providers.docker=true" # 通过Docker Socket代理连接Docker socket - "--providers.docker.endpoint=tcp://192.168.0.2:2375" # 默认不暴露未标记的服务 - "--providers.docker.exposedByDefault=false" # HTTP流量监听端口 - "--entrypoints.web.address=:80" # HTTPS流量监听端口 - "--entrypoints.websecure.address=:443" # 信任指定IP的Proxy Protocol数据包(HTTP入口) - "--entryPoints.web.proxyProtocol.trustedIPs=10.0.8.1/32" # 信任指定IP的Proxy Protocol数据包(HTTPS入口) - "--entryPoints.websecure.proxyProtocol.trustedIPs=10.0.8.1/32" # 启用名为letsencrypt的ACME DNS挑战 - "--certificatesresolvers.letsencrypt.acme.dnschallenge=true" # 指定DNS挑战提供商为Cloudflare - "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" # 使用Let's Encrypt预发布环境测试 - "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # 提供给Let's Encrypt的邮箱 - "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}" # 证书存储路径 - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" networks: # 连接到socket代理网络和容器桥接网络 socket_proxy: container_bridge: ports: # HTTP端口映射 - "80:80" # HTTPS端口映射 - "443:443" # Web UI端口映射 - "8080:8080" secrets: - "cloudflare_dns_token" environment: # 临时配置,后续需改为读取secret - "CF_DNS_API_TOKEN=${CF_DNS_TOKEN}" #- "CF_DNS_API_TOKEN=/run/secrets/cloudflare_dns_token" volumes: # 挂载证书存储目录 - "./letsencrypt:/letsencrypt" whoami: image: traefik/whoami container_name: whoami-server networks: container_bridge: labels: # 启用Traefik代理 - "traefik.enable=true" ##################################################################### # HTTPS代理配置 ##################################################################### # 标记该路由使用HTTPS - "traefik.http.routers.whoami-secure.tls=true" # HTTPS路由规则 - "traefik.http.routers.whoami-secure.rule=Host(`whoami.${FQDN}`)" # HTTPS路由入口点 - "traefik.http.routers.whoami-secure.entrypoints=websecure" # 指定证书解析器 - "traefik.http.routers.whoami-secure.tls.certresolver=letsencrypt" ##################################################################### # HTTP代理配置 ##################################################################### # HTTP路由规则 - "traefik.http.routers.whoami.rule=Host(`whoami.${FQDN}`)" # HTTP路由入口点 - "traefik.http.routers.whoami.entrypoints=web"
我预期Traefik能正常处理HTTPS请求并完成TLS握手,且已确认Traefik可通过Let's Encrypt的Cloudflare DNS挑战成功生成证书。当前使用Let's Encrypt预发布环境,原本预期会收到证书无效的错误,但实际TLS握手在验证证书前就已失败。
补充排查:OpenSSL与Wireshark结果
OpenSSL命令输出
CONNECTED(00000003) 140330304906560:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:331: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 5 bytes and written 315 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok)
Wireshark日志
- TLSv1 Client Hello前有3个TCP数据包
- 服务器确认Client Hello
- 服务器返回HTTP 400错误 - Bad Request
- 5个数据包后连接被重置
Wireshark错误报文
Transmission Control Protocol, Src Port: 443, Dst Port: 50085, Seq: 1, Ack: 518, Len: 207 Source Port: 443 Destination Port: 50085 [Stream index: 0] [Conversation completeness: Complete, WITH_DATA (63)] [TCP Segment Len: 207] Sequence Number: 1 (relative sequence number) Sequence Number (raw): 1488204866 [Next Sequence Number: 208 (relative sequence number)] Acknowledgment Number: 518 (relative ack number) Acknowledgment number (raw): 500352812 0101 .... = Header Length: 20 bytes (5) Flags: 0x018 (PSH, ACK) 000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set .... .0.. .... = ECN-Echo: Not set .... ..0. .... = Urgent: Not set .... ...1 .... = Acknowledgment: Set .... .... 1... = Push: Set .... .... .0.. = Reset: Not set .... .... ..0. = Syn: Not set .... .... ...0 = Fin: Not set [TCP Flags: ·······AP···] Window: 501 [Calculated window size: 64128] [Window size scaling factor: 128] Checksum: 0x1155 [unverified] [Checksum Status: Unverified] Urgent Pointer: 0 [Timestamps] [SEQ/ACK analysis] TCP payload (207 bytes) Hypertext Transfer Protocol [Expert Info (Warning/Security): Unencrypted HTTP protocol detected over encrypted port, could indicate a dangerous misconfiguration.] [Unencrypted HTTP protocol detected over encrypted port, could indicate a dangerous misconfiguration.] [Severity level: Warning] [Group: Security] HTTP/1.1 400 Bad request\r\n [Expert Info (Chat/Sequence): HTTP/1.1 400 Bad request\r\n] [HTTP/1.1 400 Bad request\r\n] [Severity level: Chat] [Group: Sequence] Response Version: HTTP/1.1 Status Code: 400 [Status Code Description: Bad Request] Response Phrase: Bad request Content-length: 90\r\n Cache-Control: no-cache\r\n Connection: close\r\n Content-Type: text/html\r\n \r\n [HTTP response 1/1] File Data: 90 bytes
连接重置报文
Transmission Control Protocol, Src Port: 443, Dst Port: 50085, Seq: 208, Len: 0 Source Port: 443 Destination Port: 50085 [Stream index: 0] [Conversation completeness: Complete, WITH_DATA (63)] [TCP Segment Len: 0] Sequence Number: 208 (relative sequence number) Sequence Number (raw): 1488205073 [Next Sequence Number: 208 (relative sequence number)] Acknowledgment Number: 0 Acknowledgment number (raw): 0 0101 .... = Header Length: 20 bytes (5) Flags: 0x004 (RST) 000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set .... .0.. .... = ECN-Echo: Not set .... ..0. .... = Urgent: Not set .... ...0 .... = Acknowledgment: Not set .... .... 0... = Push: Not set .... .... .1.. = Reset: Set [Expert Info (Warning/Sequence): Connection reset (RST)] [Connection reset (RST)] [Severity level: Warning] [Group: Sequence] .... .... ..0. = Syn: Not set .... .... ...0 = Fin: Not set [TCP Flags: ·········R··] Window: 0 [Calculated window size: 0] [Window size scaling factor: 128] Checksum: 0x6dc9 [unverified] [Checksum Status: Unverified] Urgent Pointer: 0 [Timestamps]
内容的提问来源于stack exchange,提问作者deadsix
相关产品推荐
相关产品推荐

