代码之家  ›  专栏  ›  技术社区  ›  Dan jezrael

Gunicorn双向SSL错误“SSL错误未知CA警告”

  •  0
  • Dan jezrael  · 技术社区  · 6 年前

    我正在通过运行Python3应用程序 Gunicorn 配置了双向SSL。这需要本地证书/密钥来验证应用程序,还需要ca证书文件来验证客户端。Gunicorn依赖于标准 ssl Python中的模块,特别是 wrap_socket 方法。

    当我使用自签名证书进行服务器和客户端身份验证时,该服务将启动并响应curl请求。但是,当我使用由另一个CA签名的证书时,会得到一个错误 SSL_ERROR_UNKNOWN_CA_ALERT .

    使用自签名证书的工作设置:

    # Server cert
    openssl req \
           -newkey rsa:2048 -nodes -keyout domain.key \
           -x509 -days 365 -out domain.crt
    
    # Client (CA) cert    
    openssl req \
           -newkey rsa:2048 -nodes -keyout twoway.key \
           -x509 -days 365 -out twoway.crt
    

    Gunicorn配置如下:

    keyfile = domain.key
    certfile = domain.crt
    cert_reqs = ssl.CERT_REQUIRED
    ca_certs=twoway.crt
    

    卷曲如下:

    curl -vk --key twoway.key --cert twoway.crt https://my.service
    

    产生成功的响应:

    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 5000 (#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.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Request CERT (13):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Certificate (11):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS handshake, CERT verify (15):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
    * ALPN, server did not agree to a protocol
    * Server certificate:
    *  subject: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd
    *  start date: Dec  7 18:35:54 2018 GMT
    *  expire date: Dec  7 18:35:54 2019 GMT
    *  issuer: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd
    *  SSL certificate verify result: self signed certificate (18), continuing anyway.
    > GET /manage/info HTTP/1.1
    > Host: localhost:5000
    > User-Agent: curl/7.58.0
    > Accept: */*
    > 
    < HTTP/1.1 200 OK
    < Server: gunicorn/19.9.0
    < Date: Tue, 11 Dec 2018 18:26:19 GMT
    < Connection: keep-alive
    < Content-Type: application/json
    < Content-Length: 73
    

    安装失败,具有不同系列的证书:

    Gunicorn配置如下:

    keyfile = my_service_key.key
    certfile = my_service_cert.crt
    cert_reqs = ssl.CERT_REQUIRED
    ca_certs = my_trusted_clients.crt
    

    卷曲如下:

    curl -vk --key my_trusted_key.key --cert my_trusted_clients.crt https://my.service
    

    产生错误:

    About to connect() to localhost port 5000 (#0)
    Initializing NSS with certpath: sql/etc/pki/nssdb
    warning: ignoring value of ssl.verifyhost
    skipping SSL peer certificate verification
    NSS: client certificate from file
        subject: CN=mycn,OU=abc,O=def,...
    NSS error -12195
    Closing connection #0
    SSL connect error
    curl: (35) SSL connect error
    

    有没有想过我是不是配置错了?为什么自签名证书有效而其他证书无效?

    注意,在使用 Stunnel ,我在那里设置 verify 级别为4(“忽略链,只验证对等证书。”)。如果Python中有类似的东西,我相信这会让我朝着正确的方向前进。

    1 回复  |  直到 6 年前
        1
  •  0
  •   javabrett    6 年前

    我不认为这是可能的,因为Gunicorn 19.9。

    除了在服务器上拥有完整的证书链之外,为了验证客户机/对等证书,我相信您还需要能够 configure the SSLContext ,尤其是能够 ssl.CERT_REQUIRED 在服务器模式下。

    Gunicorn 19.9(和编写时的master)当前不使用 SSLContext公司 -基于连接的包装,因此这是不可能的,请参见 https://github.com/benoitc/gunicorn/issues/1140 .