शीर्षक वास्तव में प्रश्न है - HTTPS कनेक्शन बनाने का प्रयास करते समय मुझे दूरस्थ सर्वर से SSL प्रमाणपत्र डाउनलोड करने के लिए urllib3 कैसे मिलेगा?

पृष्ठभूमि ServerVault भूमि में, मैं AWS ऑटोस्केलिंग समूहों के साथ एक समस्या उनकी init प्रक्रिया के हिस्से के रूप में phpMyAdmin को डाउनलोड करने में सक्षम होने में विफल रही। इसका निदान करने की कोशिश के हिस्से के रूप में, मैं अब स्टैक ओवरफ्लो भूमि में खत्म हो गया हूं, पाइथन स्क्रिप्ट के साथ काम कर रहा हूं। यहां मैं हूं:

#! /usr/bin/python3
import cfnbootstrap
from cfnbootstrap.packages import requests
from requests import utils
from requests.utils import DEFAULT_CA_BUNDLE_PATH
from requests.packages import urllib3

conn = urllib3.connection_from_url("https://dev.mysql.com/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)

यह ठीक काम करता है:

$ ./urltest.py 
404

हालाँकि, अगर मैं इसे बदल देता हूँ

conn = urllib3.connection_from_url("https://www.phpmyadmin.net", retries=False)
response = conn.request("GET", "/downloads/")

मैं अपनी समस्या में भाग लेता हूं:

$ ./urltest.py 
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/connectionpool.py", line 544, in urlopen
    body=body, headers=headers)
  File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/connectionpool.py", line 341, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/connectionpool.py", line 762, in _validate_conn
    conn.connect()
  File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/connection.py", line 238, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/util/ssl_.py", line 265, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib64/python3.7/ssl.py", line 423, in wrap_socket
    session=session
  File "/usr/lib64/python3.7/ssl.py", line 870, in _create
    self.do_handshake()
  File "/usr/lib64/python3.7/ssl.py", line 1139, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1091)

यह बहुत कम लगता है कि प्रमाणपत्र की समय सीमा समाप्त हो गई है, जैसे कि मैं वेब ब्राउज़र का उपयोग करके मैन्युअल रूप से जांच करता हूं, दुनिया के साथ सब कुछ अच्छा है; हालांकि, मैं यह देखना चाहता हूं कि urllib3 किस प्रमाणपत्र की समय सीमा समाप्त हो गई है। मैं यह कैसे करु?

NB: मैं certify.where() को सीधे कॉल नहीं कर रहा हूं, क्योंकि मुझे यकीन नहीं है कि एडब्ल्यूएस पृष्ठभूमि में क्या प्रदर्शन कर रहा है, लेकिन चूंकि उनकी स्क्रिप्ट इंस्टेंस को बूट करने के हिस्से के रूप में ऑटो-इंस्टॉल हैं , मैं इसके बारे में बहुत कुछ नहीं कर सकता, इसलिए मैं उनकी आंतरिक प्रक्रियाओं का उपयोग करने का प्रयास कर रहा हूं।

0
philolegein 9 अक्टूबर 2021, 12:01
1
यह मेरे मैक पर ठीक काम करता है। मेरे लिनक्स बॉक्स पर इसका परीक्षण करते हुए, मुझे वही प्रमाणित त्रुटि मिल रही है जो आप हैं।
 – 
clockwatcher
9 अक्टूबर 2021, 12:27
हुह। मैं पूछने वाला था कि आप कौन सा कर्नेल और टूल संस्करण चला रहे थे। भविष्य के संदर्भ के लिए, अगर किसी और को आश्चर्य होता है, तो मैं Linux 4.14.243-185.433.amzn2.x86_64 और aws-cfn-bootstrap.noarch 2.0-6.amzn2 पर हूं
 – 
philolegein
9 अक्टूबर 2021, 12:28
मुझे लगता है कि इसका मतलब है, या तो लिनक्स पर प्रमाणपत्र डाउनलोड करने के तरीके में कुछ भ्रष्टाचार की समस्या है, इस मामले में मुझे अभी भी इस प्रश्न के उत्तर की आवश्यकता है; या मैक बनाम लिनक्स पर DEFAULT_CA_BUNDLE_PATH में कुछ अंतर है (हो सकता है कि प्रमाणपत्र स्वयं ठीक हो, लेकिन कहीं न कहीं श्रृंखला लिनक्स संस्करण पर समाप्त हो गई है और मैक संस्करण नहीं?)
 – 
philolegein
9 अक्टूबर 2021, 12:31
कोशिश करें: Opensl s_client -showcerts -connect www.phpmyadmin.net:443 | grep "प्रमाणपत्र समाप्त हो गया है"
 – 
clockwatcher
9 अक्टूबर 2021, 12:56
यह कहता है कनेक्टेड (00000003) गहराई = 2 सी = यूएस, ओ = इंटरनेट सुरक्षा अनुसंधान समूह, सीएन = आईएसआरजी रूट एक्स 1 वापसी सत्यापित करें: 1 गहराई = 1 सी = यूएस, ओ = चलो एन्क्रिप्ट करें, सीएन = आर 3 वापसी सत्यापित करें: 1 गहराई = 0 सीएन = www.cdn77.com वापसी सत्यापित करें: 1
 – 
philolegein
9 अक्टूबर 2021, 13:07

1 उत्तर

सबसे बढ़िया उत्तर

समस्या लेट्स एनक्रिप्ट डीएसटी रूट सीए एक्स3 की समाप्ति है जो 30 सितंबर को हुई - https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/। अनुरोध पैकेज ISRG रूट X1 प्रमाणपत्र पर भरोसा नहीं करता है और इसे समाप्त प्रमाणपत्र के साथ सत्यापित करने का प्रयास कर रहा है।

ISRG X1 PEM को https://letsencrypt.org/certificates/ से डाउनलोड करें और इसे cfnbootstrap लाइब्रेरी में जोड़ें cacert.pem फ़ाइल।

cat isgrootx1.pem >> /path/to/your/python/env/lib/python3.9/site-packages/cfnbootstrap/packages/requests/cacert.pem

आप निम्नलिखित के साथ अपने cacert.pem का स्थान ढूंढ सकते हैं:

from cfnbootstrap.packages.requests.certs import where
print(where())

साथ ही... मैं यह सुनिश्चित करने के लिए आपका कोड बदल दूंगा कि आप वास्तव में स्टैंडअलोन अनुरोधों के बजाय cfn पैकेज्ड अनुरोध मॉड्यूल का उपयोग कर रहे हैं। अन्यथा, आपको शायद इसे दोनों स्थानों पर अपडेट करना होगा।

from cfnbootstrap.packages.requests.utils import DEFAULT_CA_BUNDLE_PATH
from cfnbootstrap.packages.requests.packages import urllib3

conn = urllib3.connection_from_url("https://www.phpmyadmin.net/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)

यदि आप स्टैंडअलोन अनुरोधों और cfnbootstrap के साथ पैक किए गए अनुरोधों को अपडेट करना चाहते हैं, तो दोनों cacert पथों को खोजने और अपडेट करने के लिए निम्नलिखित का उपयोग करें:

import requests
import cfnbootstrap.packages.requests

print(requests.certs.where())
print(cfnbootstrap.packages.requests.certs.where())
1
clockwatcher 9 अक्टूबर 2021, 14:07