web-dev-qa-db-ja.com

NginX SSLはPythonリクエストでは機能しませんが、ブラウザでは機能します

Python(v3.6)、Flask(v1.1.1)&NginX(v1.16.1)の小さなWebサーバーがあります。 sslforfree.comからSSL証明書を設定します。ブラウザーを使用してページにアクセスすると、すべてが正常に機能しますが、Pythonスクリプトを使用してlibに要求することはできません。

import requests
print(requests.get('https://www.some-project.com'))
Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 441, in wrap_socket
    cnx.do_handshake()
  File "/anaconda3/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1907, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "/anaconda3/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1639, in _raise_ssl_error
    _raise_current_error()
  File "/anaconda3/lib/python3.6/site-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/anaconda3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 346, in _make_request
    self._validate_conn(conn)
  File "/anaconda3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn
    conn.connect()
  File "/anaconda3/lib/python3.6/site-packages/urllib3/connection.py", line 326, in connect
    ssl_context=context)
  File "/anaconda3/lib/python3.6/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/anaconda3/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 448, in wrap_socket
    raise ssl.SSLError('bad handshake: %r' % e)
ssl.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/anaconda3/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/anaconda3/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(Host='www.some-project.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/aivanf/Desktop/some-project/py-API/test.py", line 55, in <module>
    main()
  File "/Users/aivanf/Desktop/some-project/py-API/test.py", line 49, in main
    print(requests.get(MAIN_URL))
  File "/anaconda3/lib/python3.6/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/anaconda3/lib/python3.6/site-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/requests/adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(Host='www.some-project.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))

OpenSSL、ルート証明書を更新するために、別のコンピューターから同じことを実行しようとしましたが、何も役に立ちませんでした...問題は何ですか?すべてのブラウザがWebサイトで正常に機能するのに、なぜPythonが機能しないのですか?解決方法は?

また、https://sslforfree.com自体へのアクセスはうまく機能しますが、証明書は私のものと非常に似ています。したがって、問題は私のNginX構成にあると思います:

これが私のNginX設定です:

ssl_certificate /var/www/ssl/ca.crt;
ssl_certificate_key /var/www/ssl/private.key;

# Redirect @ to www
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name  some-project.com;
    rewrite ^ https://www.some-project.com$request_uri?;
}

# Redirect www HTTP to HTTPS
server {
    listen 80;
    server_name  www.some-project.com;
    rewrite ^ https://www.some-project.com$request_uri? permanent;
}

server {
    listen 443 ssl;
    server_name  www.some-project.com;

    include /etc/nginx/vhosts-includes/*.conf;

    # Static Content
    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /var/www/some-project/;
    }

    location / {
        default_type "text/html";
        alias /var/www/some-project/static/;
    }
}

server {
    listen 443 ssl;
    server_name  api.some-project.com;

    # Reverse Proxy
    location / {
        proxy_pass http://localhost:5926;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-Ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
2
AivanF.

Nginxは完全なチェーン+キーを必要とするため、「間違った」証明書が使用されました。ドメインとCAバンドルの証明書を組み合わせることによって解決されます。

1
Lenniey