zoukankan      html  css  js  c++  java
  • nginx ingress controller配置默认SSL证书

    故障现象

    线上某kubernetes集群环境,使用nginx-ingress-controller暴露了一个service,为一个API服务,其中在ingress对象中使用了TLS证书,使用浏览器输入ingress对应的域名访问这个API service,请求正常,但是某程序使用SDK调用此service,始终无法拿到结果。

    ingress的yaml文件类似如下

    image-20200606184834598

    排查

    1. sdk调用ingress时nginx-ingress-controller的日志信息,发现有如下报错

      2020/04/01 04:49:01 [error] 12173#12173: *6506108 [lua] cert.lua:58: no cert found for 443, context: ssl_certificate_by_lua*, client: x.x.x.x, server: 0.0.0.0:443
      2020/04/01 04:49:01 [crit] 12173#12173: *6506107 SSL_do_handshake() failed (SSL: error:1417A179:SSL routines:tls_post_process_client_hello:cert cb error) while SSL handshaking, client: x.x.x.1x6, server: 0.0.0.0:443

      google上述信息,没有找到相关case。

    2. 使用tcpdump对nginx-ingress-controller抓包,分析sdk请求时候的数据流,拿到抓包文件后用wireshark打开,发现如下错误信息。

      image-20200606184040298

    image-20200606184203738分析此数据包,可以看出SDK客户端发出client_hello请求后,服务器端立马返回了报错,SSL握手未完成。

         3. 正常SSL握手过程如下图,结合抓包结果,可以发现服务器端nginx-ingress-controller没有返回server_hello信息给客户端,而是直接报错,日志信息则是提示未发现证书。

        4. 分析此ingress对应的yaml文件一切正常,同时从现象看,浏览器请求正常的,只是sdk调用异常,问题应该和客户端关联,于是对sdk请求时和浏览器请求时分别抓包的client_hello包进行对比,发现不同,sdk的client_hello包,extension字段未传递server_name.在openresty也搜到如下信息

        5. 综上,SDK客户端为非标准客户端,访问不带sni及server_name信息,导致nginx-ingress-controller无法通过sni和server_name找到对应的证书。

    解决

    长远看,需要SDK客户端解决请求不带server_name的问题。在nginx-ingress-controller无法通过sni和server_name找到对应的证书时,其会使用默认的端口证书,临时通过配置默认端口证书解决。在nginx-ingress-controller的启动参数,增加default-ssl-certificate指向此ingress引用的证书。

    image-20200606214742276

    参考:HTTPS 之 SSL/TLS 握手协议(Handshake Protocol)全过程解析

  • 相关阅读:
    手写一个类django框架
    Django基础知识
    JQuery知识点总结
    javascript知识点整理
    html知识点一
    mysql之sql语句
    通过非IO阻塞模型实现ftp并发的小代码
    python学习第三十三节(IO模型)
    python学习第三十二节(进程间通信、进程池、协程)
    IntelliJ IDEA For Mac 快捷键
  • 原文地址:https://www.cnblogs.com/360linux/p/13062044.html
Copyright © 2011-2022 走看看