You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TLS 1.2及以下版本时OpenSSL握手后卡住问题求助

TLS 1.2握手后阻塞,TLS 1.3正常的问题排查方案

结合你描述的现象(Yocto构建系统上TLS1.2握手卡住,TLS1.3正常,甚至无法用CTRL+C终止进程),以及提供的调试日志,我整理了几个核心排查方向和具体操作步骤:

1. 加密套件协商不兼容

TLS 1.2依赖客户端与服务器协商双方都支持的加密套件,而TLS 1.3的套件列表是标准化的,不容易出现不兼容问题。你的系统默认的TLS1.2套件可能和目标服务器(比如files.pythonhosted.org背后的Fastly服务)不匹配,导致握手卡在密钥交换阶段。

排查操作:

  • 先查看当前OpenSSL支持的TLS1.2套件:
    openssl ciphers -v 'TLSv1.2'
    
  • 尝试强制指定服务器大概率支持的套件,比如ECDHE系列:
    # 用curl测试
    curl -vvv --tlsv1.2 --tls-max 1.2 --ciphers ECDHE-RSA-AES256-GCM-SHA384 --ipv4 https://google.com:443
    
    # 用openssl测试
    openssl s_client -connect files.pythonhosted.org:443 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384 -showcerts
    

如果指定套件后能完成握手,就说明是默认套件列表的问题,需要调整OpenSSL配置文件(/etc/ssl/openssl.cnf)中的CipherString参数。

2. Yocto构建时的组件裁剪问题

Yocto在构建系统时经常会裁剪不必要的功能,可能你的OpenSSL或curl配方中禁用了TLS1.2相关的关键组件,比如ECDHE密钥交换支持、某些加密算法库(如libcrypto的部分模块)。从调试日志看,服务器已经发送了密钥交换消息,但客户端没有回应,大概率是客户端无法处理这些参数。

排查操作:

  • 检查OpenSSL的构建配置:
    openssl version -a
    
    看输出中是否有ENABLE_TLS1_2相关的启用标记,或者有没有禁用ECDHE的选项。
  • 查看Yocto中OpenSSL的配方文件(比如recipes-connectivity/openssl/openssl_*.bb),确认是否有类似EXTRA_OECONF += "no-ecdhe"这样的禁用配置,如果有,去掉后重新构建系统。
  • 同样检查curl的配方,确认它链接的是完整的OpenSSL库,而不是裁剪后的版本。

3. 系统熵池不足导致阻塞

TLS握手需要生成随机密钥,OpenSSL默认可能使用/dev/random作为随机数源,当系统熵池不足时,进程会阻塞等待足够的随机数据。TLS1.3可能使用了更高效的随机数生成机制,或者你的系统中TLS1.3配置使用了/dev/urandom(非阻塞源),所以没有这个问题。

排查操作:

  • 查看当前熵池可用量:
    cat /proc/sys/kernel/random/entropy_avail
    
    如果数值低于1000,说明熵不足。
  • 临时解决:安装rng-tools(Yocto中有对应的配方),它可以利用硬件随机数生成器或者其他方式补充熵池:
    # 启动rngd服务
    rngd -r /dev/urandom
    
  • 永久解决:修改OpenSSL配置文件,将随机数源改为/dev/urandom:
    在/etc/ssl/openssl.cnf中添加或修改:
    RANDFILE = /dev/urandom
    

4. 内核网络栈异常

某些定制的Yocto内核可能对TLS1.2握手的数据包处理有问题,比如TCP窗口大小设置不合理、MTU过大导致分片失败,或者缺少必要的网络模块。进程无法被CTRL+C终止,说明可能在内核态阻塞了。

排查操作:

  • 抓包分析握手流程:
    tcpdump -w tls12_handshake.pcap -i any host files.pythonhosted.org and port 443
    
    运行卡住的openssl命令,等待10秒后停止tcpdump,用Wireshark打开抓包文件,查看:
    • 客户端是否发送了Client Key Exchange和Finished消息?
    • 服务器是否回应了这些消息?
      如果客户端根本没发这些消息,说明问题在用户态的OpenSSL/curl;如果发了但没收到回应,再排查网络路由或防火墙(但TLS1.3正常的话这个可能性较低)。
  • 尝试调整MTU值:
    ifconfig eth0 mtu 1400  # 替换成你的网卡名
    
    再测试TLS1.2连接。

总结

结合你的场景,最可能的原因是Yocto构建时裁剪了TLS1.2的关键组件,或者加密套件不兼容。建议先从指定加密套件测试入手,再检查OpenSSL的构建配置,最后用抓包确认具体的握手阻塞点。

内容的提问来源于stack exchange,提问作者Abagnale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:32:38