使用 Python2 作为带有 nginx 服务器和 SSL 证书链的 https 客户端时出错

使用 Python2 作为带有 nginx 服务器和 SSL 证书链的 https 客户端时出错

我无法让 Nginx 1.8 使用我的证书,因此我可以使用基于 python2 的 https 客户端。(requests.py、URLLib)

我尝试使用 Comodo 和 GlobalTrust 通配符证书并在设置 nginx 时将它们链接到服务器上,但从 python 收到此错误。

requests.exceptions.SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

在 Nginx 上,我使用以下指令来设置 SSL:

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA;
ssl_protocols TLSv1.2 TLSv1.1 SSLv3;
#ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;

ssl_certificate /etc/nginx/alphassl/cert_bundle.crt;
ssl_certificate_key /etc/nginx/newkey/key.key;

我已经在服务器上将证书链接在一起

cat server.crt intermediate.crt root.crt > cert_bundle.crt

对于 Comodo:

cat server.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl_bundled.crt

它可以很好地与 curl、chrome 和 python3 配合使用,但我需要能够使用类似以下请求从 python 2.7.6 访问它

import requests
requests.get('https://server.com/', verify=True)

我还可以请求https://store.ssl2buy.com/来自 python2,它是我的证书的供应商,所以我相信这是一个服务器的问题,而不是 python 客户端的问题。

另外这是我使用 openssl 调试时得到的结果

openssl s_client -connect g.peakdata.net:443 -CAfile /etc/ssl/certs/ca-certificates.crt

CONNECTED(00000003)
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.peakdata.net
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.peakdata.net
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.peakdata.net
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.peakdata.net
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUTCCBDmgAwIBAgIQYc2m4QZ+tkek2fUe/Y7+1jANBgkqhkiG9w0BAQsFADCB
kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV
BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD
QTAeFw0xNTA1MDUwMDAwMDBaFw0xNjA1MTIyMzU5NTlaMFsxITAfBgNVBAsTGERv
bWFpbiBDb250cm9sIFZhbGlkYXRlZDEdMBsGA1UECxMUUG9zaXRpdmVTU0wgV2ls
ZGNhcmQxFzAVBgNVBAMUDioucGVha2RhdGEubmV0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5Jor5AzXAxaUdc5e1Oim3Fmo5fpAv8Ug42r6mTM81JGV
lxi4ICQ/3FszeJARUs0KhaS4k6nnf0VsCudw2DDw0u3jfAstjhS5JCNLDFAY1D01
GzKp1EZ0iU9xsE8qa/6iPFQ9v9zVzQ72wimk00X32pPAGKrVr8L9w11JtfTrjP1Q
N6QygQBu7KcCtMRCA5eWinz3PnYdZL7analYasY2sY+/tp5iQJasiOfuXKO82of+
wBV5wsh1igR1BzwKOAhU8IYN1pKilvbhMb6qeMP3CAZMe205ACQavqfq4a2aK1pR
oqK9r9jiqzUj4sULbTVS+Kd6OqydtSJF8xaUU/Di7QIDAQABo4IB2TCCAdUwHwYD
VR0jBBgwFoAUkK9qOpRaC9iQ6hJWc99DtDoo2ucwHQYDVR0OBBYEFEifaFvh1SCN
ceI/gwjjeCiiW7ArMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBPBgNVHSAESDBGMDoGCysGAQQBsjEB
AgIHMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5jb20vQ1BT
MAgGBmeBDAECATBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vY3JsLmNvbW9kb2Nh
LmNvbS9DT01PRE9SU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3Js
MIGFBggrBgEFBQcBAQR5MHcwTwYIKwYBBQUHMAKGQ2h0dHA6Ly9jcnQuY29tb2Rv
Y2EuY29tL0NPTU9ET1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5j
cnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTAnBgNVHREE
IDAegg4qLnBlYWtkYXRhLm5ldIIMcGVha2RhdGEubmV0MA0GCSqGSIb3DQEBCwUA
A4IBAQB2m/qah9mHPUQn3yRd3LHRHIigxdDySh5Rb75255I2AuSPQ3HQoi7vt0TB
0oOgRbdZ2RuLtlZVd6nOfQ24dh0rJ5JOzXDAb4hpfsDimpvzEMoqPudJpJgbjLJc
Bhx30ny0MecheoS/In1t59bw8RKZUukyGRqWHsQDbRq5F2MUWc7WFokydmTY1o9o
EQBKdOykiYRS07M7oqFc5weyCnii/dE4WtT7g4gA5zQsvPzsEmeKqvxY5RI8eg1R
8cF/Mr5iov9xGyPelgHwgHroE34G9YclxXVeyDcUlSWUK2j30M28h/feGkVMj+U4
+SZk/Ek5WhfUJmgy+b6JTtB8/l67
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.peakdata.net
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
---
SSL handshake has read 2036 bytes and written 427 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-RC4-SHA
    Session-ID: 8ACFB450411BE9FF0B26CAA57047D80D9A146F41CDD093C8247698216BCF6FE1
    Session-ID-ctx: 
    Master-Key: 515A3952C76176757C51EA8B8FA35FC71C2CD496ABDE0D6E1870E04D1B020F786267D761C7A38051EFA14DE552D10F53
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 600 (seconds)
    TLS session ticket:
    0000 - d7 35 92 7d 59 5c ba 5c-9a 4d 79 c7 b5 b6 3e 1a   .5.}Y\.\.My...>.
    0010 - df 9a 5f de f4 af 9d 29-0e a8 d1 23 01 08 aa 64   .._....)...#...d
    0020 - 81 0f 4d 6f e2 a6 19 3e-ca 7e a9 9f d3 c8 a0 96   ..Mo...>.~......
    0030 - ce a1 37 a3 99 96 da 26-6f 83 ff 41 96 41 dc 17   ..7....&o..A.A..
    0040 - d7 11 6c be 50 1f 0c 7d-ad e5 0f 34 d8 fd db be   ..l.P..}...4....
    0050 - 87 3e fe 05 92 06 c8 0e-fc fc cc 8f f6 ae 08 a6   .>..............
    0060 - a3 3e c1 3e 61 4a fd 41-1f 5b 24 8d 97 6a aa e3   .>.>aJ.A.[$..j..
    0070 - 36 6b 68 1d f2 31 e7 da-05 29 59 1b 8f 21 38 25   6kh..1...)Y..!8%
    0080 - dc 67 8e bf 8e 02 63 26-43 f1 c3 9e 7c 78 e5 e3   .g....c&C...|x..
    0090 - cd ea 63 77 02 03 6a 01-10 45 84 c1 d9 73 c4 b0   ..cw..j..E...s..
    00a0 - e7 2d 86 a8 72 d8 ed b9-05 5c 2c a1 4b 66 8f 8a   .-..r....\,.Kf..

    Start Time: 1431626677
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

谢谢

答案1

这是服务器设置不佳和缺少支持造成的 SNI(服务器名称指示)在 python 2.7.6 中。需要 SNI 来支持同一 IP 地址上的多个证书。SNI 支持在 python3 中,并且也在版本 2.7.9 中添加,但在版本 2.7.6 中没有。

如果您连接到没有 SNI 的服务器,您将只会获得证书,而不会获得信任链:

$ openssl s_client -connect g.peakdata.net:443
...
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.peakdata.net
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA

相反,如果您使用 SNI 连接到服务器,您将获得完整的链,包括根 CA(您不需要包含它,客户端将忽略它):

$ openssl s_client -connect g.peakdata.net:443 -CAfile /etc/ssl/certs/ca-certificates.crt -servername g.peakdata.net
...
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.peakdata.net
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
 3 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root

由于 python3 和浏览器使用 SNI,因此它们会成功。Python 2.7.6 不会使用 SNI 并获得正确的证书,但缺少证书链。因此,它无法根据本地根 CA 验证证书。

相关内容