Ssl
無法從某些設備訪問具有自簽名 SSL 證書的伺服器
我正在努力連接到似乎可以通過其他電腦/網際網路連接工作的 SSL 站點(自簽名證書)。我嘗試使用 wget 訪問該站點:
wget https://example.com --no-check-certificate --2018-02-06 17:07:50-- https://example.com Resolving example.com... xx.xx.xx.xx Connecting to example.com|xx.xx.xx.xx|:443... connected. Unable to establish SSL connection.
然後我在另一次嘗試中使用了 Python3 和requests 模組:
>>> r = requests.get("https://example.com", verify=False) Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 601, in urlopen chunked=chunked) File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 346, in _make_request self._validate_conn(conn) File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn conn.connect() File "/usr/lib/python3.5/site-packages/urllib3/connection.py", line 326, in connect ssl_context=context) File "/usr/lib/python3.5/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket return context.wrap_socket(sock, server_hostname=server_hostname) File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 377, in wrap_socket File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 752, in __init__ File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 988, in do_handshake File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 633, in do_handshake ConnectionResetError: [Errno 104] Connection reset by peer During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/requests/adapters.py", line 440, in send timeout=timeout File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 639, in urlopen _stacktrace=sys.exc_info()[2]) File "/usr/lib/python3.5/site-packages/urllib3/util/retry.py", line 357, in increment raise six.reraise(type(error), error, _stacktrace) File "/usr/lib/python3.5/site-packages/urllib3/packages/six.py", line 685, in reraise raise value.with_traceback(tb) File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 601, in urlopen chunked=chunked) File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 346, in _make_request self._validate_conn(conn) File "/usr/lib/python3.5/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn conn.connect() File "/usr/lib/python3.5/site-packages/urllib3/connection.py", line 326, in connect ssl_context=context) File "/usr/lib/python3.5/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket return context.wrap_socket(sock, server_hostname=server_hostname) File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 377, in wrap_socket File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 752, in __init__ File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 988, in do_handshake File "/home/linux-dev/target/usr/lib/python3.5/ssl.py", line 633, in do_handshake urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/site-packages/requests/api.py", line 72, in get return request('get', url, params=params, **kwargs) File "/usr/lib/python3.5/site-packages/requests/api.py", line 58, in request return session.request(method=method, url=url, **kwargs) File "/usr/lib/python3.5/site-packages/requests/sessions.py", line 508, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3.5/site-packages/requests/sessions.py", line 618, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3.5/site-packages/requests/adapters.py", line 490, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) >>>
然後我嘗試使用 openssl 查看更多詳細資訊:
# openssl s_client -connect example.com:443 -servername example.com CONNECTED(00000003) write:errno=104 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 330 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1517926190 Timeout : 300 (sec) Verify return code: 0 (ok) ---
從不同的電腦(具有不同的 Internet 連接)執行相同的 openssl 命令,會產生以下輸出:
# openssl s_client -connect example.com:443 -servername example.com CONNECTED(00000003) depth=0 CN = example.com verify error:num=18:self signed certificate verify return:1 depth=0 CN = example.com verify return:1 --- Certificate chain 0 s:/CN=example.com i:/CN=example.com --- Server certificate -----BEGIN CERTIFICATE----- . . . -----END CERTIFICATE----- subject=/CN=example.com issuer=/CN=example.com --- No client certificate CA names sent Peer signing digest: SHA512 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 706 bytes and written 456 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384 Server public key is 256 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-ECDSA-AES256-GCM-SHA384 Session-ID: xxxxxx Session-ID-ctx: Master-Key: xxxxxx Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1517926278 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) --- closed
什麼可能導致連接失敗?
事實證明,問題在於 ISP 阻止了某些頂級域。當訪問該域時,他們的防火牆返回 HTTP 響應 503 和一個 HTML 頁面,指示該站點已被阻止。這個問題很難診斷,因為我嘗試連接的原始站點使用 SSL,並且任何錯誤消息都很簡短:“無法建立 SSL 連接”、“對等方重置連接”等。使用 wget 訪問頁面也無濟於事,因為一旦收到 503 錯誤,它就會直接退出而不保存響應 HTML。
我最終通過在有問題的伺服器上使用 Python 3 的http.server 模組設置一個簡單的非 SSL HTTP Web 伺服器來解決問題,然後嘗試使用 Python requests 模組從有問題的設備連接到它。這讓我可以看到響應的內容並看到 ISP 的“頁面被阻止”HTML 頁面。
由於來自兩個完全不同的連接的兩個完全不同的結果,我認為問題出在 DNS 上,請確保您在兩台主機上獲得相同的 IP。您可能在其中一個上也有一個主機文件條目,因此請檢查它。