Ssl

無法從某些設備訪問具有自簽名 SSL 證書的伺服器

  • February 7, 2018

我正在努力連接到似乎可以通過其他電腦/網際網路連接工作的 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。您可能在其中一個上也有一個主機文件條目,因此請檢查它。

引用自:https://serverfault.com/questions/895900