python - Gunicorn 双向 SSL 错误“SSL_ERROR_UNKNOWN_CA_ALERT”
问题描述
我正在通过 Gunicorn 运行 Python3 应用程序,并配置了双向 SSL。这需要一个本地证书/密钥来验证应用程序以及一个 ca_certs 文件来验证客户端。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 中有类似的东西,我相信这会让我朝着正确的方向前进。
解决方案
我认为从 Gunicorn 19.9 开始这是不可能的。
除了在服务器上拥有完整的证书链外,为了验证客户端/对等证书,我相信您需要能够配置SSLContext
,尤其是能够ssl.CERT_REQUIRED
在服务器模式下进行设置。
Gunicorn 19.9(和撰写本文时的主版本)当前未SSLContext
在连接上使用基于 - 的包装器,因此这是不可能的,请参阅https://github.com/benoitc/gunicorn/issues/1140。
推荐阅读
- r - Igraph 错误中的 Mark.groups:选择了未知的 vertex.names
- reactjs - react如何在打印页面中显示自定义的页码
- java - 如何使Horizontal Recyclerview无限滚动而不滚动回第一项
- ios - swift 5,如何在collectionView中加载超过7000〜图像?
- python - 高斯拟合函数异常
- javascript - 如何进入从 json 获得的数组?
- k3s - 0/1 个节点可用:1 个节点没有用于请求的 pod 端口的空闲端口
- javascript - Javascript链接分配变量
- angular - 从动态表中获取表单数组
- c++ - 为什么我不能在函数中没有移动构造的情况下返回对象?