Docker+Taskserver+Nginx反向代理下task sync失败求助
我目前采用 Docker + Taskserver + Nginx反向代理 的配置,执行task sync时同步失败,错误信息如下:
$ task sync c: 1 Received record packet of unknown type 72 Syncing with task.reggi.com:80 Handshake failed. An unexpected TLS packet was received. Sync failed. Could not connect to the Taskserver.
我推测问题出在Taskserver和Nginx的证书配置冲突上——两者都在处理TLS相关配置。我已经完成以下操作:
- 为域名
task.reggi.com申请了Let's Encrypt证书 - 执行
pki/generate.ca生成Taskserver的CA证书 - 执行
pki/generate.client reggi生成客户端证书 - 客户端已正确指向这些证书文件
- 尝试将Let's Encrypt证书与Taskserver的CA证书组合使用
当组合证书时,还会出现额外错误:
$ task sync c: 1 There was a non-CA certificate in the trusted list: CN=task.reggi.com. c: 1 Received record packet of unknown type 72 Syncing with task.reggi.com:80 Handshake failed. An unexpected TLS packet was received. Sync failed. Could not connect to the Taskserver.
相关配置文件
客户端配置(.taskrc)
taskd.certificate=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.cert.pem taskd.key=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.key.pem taskd.ca=~/.task/both.pem taskd.server=task.reggi.com:80 taskd.credentials=Private/Thomas Reggi/2f397682-40d8-4b83-a7f4-de2bda1a31f1
Taskserver PKI配置(vars)
BITS=4096 EXPIRATION_DAYS=365 ORGANIZATION="REGGI CORP" CN=task.reggi.com COUNTRY=US STATE="NEW YORK" LOCALITY="NEW YORK"
Taskserver主配置(config)
confirmation=1 extensions=/usr/local/libexec/taskd ip.log=on log=/var/log/taskd.log pid.file=/tmp/taskd.pid queue.size=10 request.limit=1048576 root=/var/taskd server=0.0.0.0:53589 trust=strict verbose=1 ca.cert=/var/taskd/pki/ca.cert.pem server.cert=/etc/nginx/certs/task.reggi.com/fullchain.pem server.key=/etc/nginx/certs/task.reggi.com/key.pem client.key=/var/taskd/pki/client.key.pem client.cert=/var/taskd/pki/client.cert.pem
Taskserver启动日志
taskserver_1 | 20180511T072403Z 1.2.0 info ==== taskd 1.2.0 6f5929c ==== taskserver_1 | 20180511T072403Z 1.2.0 info Serving from /var/taskd taskserver_1 | 20180511T072403Z 1.2.0 info Using address 0.0.0.0 taskserver_1 | 20180511T072403Z 1.2.0 info Using port 53589 taskserver_1 | 20180511T072403Z 1.2.0 info Using family taskserver_1 | 20180511T072403Z 1.2.0 info Queue size 10 requests taskserver_1 | 20180511T072403Z 1.2.0 info Request size limit 1048576 bytes taskserver_1 | 20180511T072403Z 1.2.0 info IP logging on taskserver_1 | 20180511T072403Z 1.2.0 info CA /var/taskd/pki/ca.cert.pem taskserver_1 | 20180511T072403Z 1.2.0 info Certificate /etc/nginx/certs/task.reggi.com/fullchain.pem taskserver_1 | 20180511T072403Z 1.2.0 info Private Key /etc/nginx/certs/task.reggi.com/key.pem taskserver_1 | 20180511T072403Z 1.2.0 info Server starting taskserver_1 | 20180511T072403Z 1.2.0 info Using dh_bits: 0
Nginx反向代理配置片段
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the # server port the client connected to map $http_x_forwarded_port $proxy_x_forwarded_port { default $http_x_forwarded_port; '' $server_port; } # If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any # Connection header that may have been passed to this server map $http_upgrade $proxy_connection { default upgrade; '' close; } # Apply fix for very long server names server_names_hash_bucket_size 128; # Default dhparam # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl { default off; https on; } gzip_types text/plain text/css application/javascript application/json application
我已经参考官方教程配置但未解决问题,线索指向端口转发规则可能存在问题,希望得到问题排查及解决的帮助。
先理清楚核心问题:你现在的TLS处理层级混乱了——Nginx和Taskserver同时在处理TLS握手,导致客户端发送的TLS请求被Nginx转发给已经启用TLS的Taskserver,出现了嵌套TLS包的冲突,这就是你看到“意外TLS包”错误的原因。另外,证书信任链也混了,导致出现“非CA证书在信任列表”的问题。咱们一步步来解决:
1. 选对TLS终止的模式,二选一!
你必须明确:是让Nginx处理外部的公网TLS(用Let's Encrypt证书),还是让Taskserver直接处理所有TLS逻辑?两者不能同时在同一条连接路径上处理TLS。
模式A:Nginx做TLS终止(推荐,更灵活)
这是反向代理的常规玩法:公网用户连Nginx的443端口(走Let's Encrypt的HTTPS),Nginx验证客户端证书后,用明文把请求转发给Taskserver。
配置步骤:
- 修改Taskserver的config文件:
注释掉server.cert和server.key这两行,让Taskserver监听明文端口(保持server=0.0.0.0:53589不变)。这样Taskserver就不再处理TLS,只处理明文的Taskserver协议。 - 补全Nginx的server配置:
你之前的Nginx配置只有片段,需要添加完整的server块,同时启用客户端证书验证(因为Taskserver需要验证客户端身份):server { listen 443 ssl; server_name task.reggi.com; # 公网用的Let's Encrypt证书 ssl_certificate /etc/nginx/certs/task.reggi.com/fullchain.pem; ssl_certificate_key /etc/nginx/certs/task.reggi.com/key.pem; # 验证客户端证书:用你生成的Taskserver CA证书 ssl_client_certificate /var/taskd/pki/ca.cert.pem; ssl_verify_client on; location / { # 转发到Taskserver的明文端口(这里假设Docker容器的主机名是taskserver,根据你的实际情况调整) proxy_pass http://taskserver:53589; # 把客户端IP和证书DN转发给Taskserver,Taskserver需要这个来验证身份 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Taskd-Client-DN $ssl_client_s_dn; } } # 可选:把80端口重定向到443,避免用户连错端口 server { listen 80; server_name task.reggi.com; return 301 https://$host$request_uri; } - 修改客户端的.taskrc:
# 连接Nginx的443端口,而不是80 taskd.server=task.reggi.com:443 # 信任Let's Encrypt的CA证书,直接用fullchain.pem就行 taskd.ca=/Users/thomas/Desktop/cloud/taskserver/pki/fullchain.pem # 保留客户端的证书和key,因为要给Nginx验证用 taskd.certificate=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.cert.pem taskd.key=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.key.pem
模式B:Nginx仅做TCP端口转发,Taskserver处理所有TLS
如果你想让Taskserver直接处理双向TLS(自己验证客户端证书,同时用Let's Encrypt证书给客户端验证),那Nginx只需要做透明的TCP转发,不处理HTTP逻辑:
配置步骤:
- 修改Nginx配置:
确保Nginx编译时包含stream模块,然后添加stream配置:stream { server { listen 443; # 直接转发到Taskserver的TLS端口 proxy_pass taskserver:53589; } } - 检查Taskserver配置:
确保server.cert和server.key用的是Let's Encrypt的fullchain.pem和key.pem,ca.cert用你自己生成的CA证书(用于验证客户端证书),trust=strict保持不变。 - 修改客户端的.taskrc:
taskd.server=task.reggi.com:443 # 信任Let's Encrypt的CA证书,因为Taskserver的证书是它签发的 taskd.ca=/Users/thomas/Desktop/cloud/taskserver/pki/fullchain.pem # 客户端证书和key不变,给Taskserver验证用 taskd.certificate=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.cert.pem taskd.key=/Users/thomas/Desktop/cloud/taskserver/pki/reggi.key.pem
2. 修复证书信任链错误
你之前遇到的There was a non-CA certificate in the trusted list错误,是因为你把Let's Encrypt的服务器证书(不是CA证书)放进了taskd.ca里。记住:
taskd.ca只能放CA证书(根证书或中间证书),不能放服务器证书- 客户端需要信任的是服务器的CA(也就是Let's Encrypt的fullchain.pem),而Taskserver需要信任的是客户端的CA(你自己生成的ca.cert.pem),这两者不要混在一起!
3. 验证连接是否正常
做完配置后,先做几个测试:
- 测试Nginx监听:执行
netstat -tulpn | grep nginx,看443端口是否在监听 - 测试客户端到Nginx的握手:
如果握手成功,会显示openssl s_client -connect task.reggi.com:443 -cert /Users/thomas/Desktop/cloud/taskserver/pki/reggi.cert.pem -key /Users/thomas/Desktop/cloud/taskserver/pki/reggi.key.pemVerify return code: 0 (ok) - 再执行
task sync测试同步
4. 检查Taskserver的客户端身份配置
确保你已经把客户端的证书DN添加到Taskserver的用户里了,执行:
taskd user add Private "Thomas Reggi" <客户端证书的DN>
可以用openssl x509 -in reggi.cert.pem -noout -subject查看客户端证书的DN。
内容的提问来源于stack exchange,提问作者ThomasReggi

