6

我正在尝试使用 Python 2.7 使用以下代码mechanize登录:Mint.com

import mechanize
br = mechanize.Browser()
br.open("https://wwws.mint.com/login.event")

这在 OSX 上工作得很好,但它在 debian 上。这个问题似乎与 ssl 相关;回溯以

File "/usr/lib/python2.7/ssl.py", line 305, in do_handshake
    self._sslobj.do_handshake()

编辑:问题在 Debian 上仍然存在,使用urllib2. 正如评论中所建议的,似乎这个问题实际上与 ssl 相关。为什么这会是 Debian 而不是 OSX 的问题?

4

2 回答 2

1

这是 OpenSSL 最新版本与某些 Web 服务器之间不兼容的表现。Apple 正在尽最大努力消除 OS X 上的 OpenSSL,因此他们只应用了安全补丁(OpenSSL 作为操作系统的一部分一直难以支持,更不用说引入此类问题的“次要”更新),而 Debian 正在使用更新的 OpenSSL 1.0.1。

@Brian Redbeard 建议使用openssl命令行进行检查是一个很好的建议——wwws.mint.com当我刚尝试它时,它就挂在我身上了。

ServerFault上的这个问题终于给出了答案。那里链接的 SSLLabs 测试将长时间握手不容忍确定为问题,这会影响 OpenSSL 1.0.1 及更高版本,并链接到具有一些潜在解决方法的OpenSSL 错误。

-no_tls1_2正如一位 OpenSSL 开发人员建议的那样,使用 ,或者使用-cipher参数减少密码列表,都会导致 OpenSSL 1.0.1 成功地与wwws.mint.com(以及我试图联系的另一台服务器)握手。

出于我的目的——一个不会被分发的脚本——我做ssl.wrap_socket了以下猴子补丁:

import ssl
old_wrap_socket = ssl.wrap_socket
def wrap_socket(sock, keyfile=None, certfile=None,
                server_side=False, cert_reqs=ssl.CERT_NONE,
                ssl_version=ssl.PROTOCOL_SSLv3, ca_certs=None,
                do_handshake_on_connect=True,
                suppress_ragged_eofs=True, ciphers=None):
    return old_wrap_socket(sock, keyfile, certfile,
                           server_side, cert_reqs, ssl_version,
                           ca_certs, do_handshake_on_connect,
                           suppress_ragged_eofs, ciphers)
ssl.wrap_socket = wrap_socket

import mechanize

ssl_version默认值为ssl.PROTOCOL_SSLv23; 通过将其更改为PROTOCOL_SSLv3成功连接。

您可以使用诸如ssl.OPENSSL_VERSION_INFO[:3] >= (1, 0, 1).

如果还没有的话,这很可能会被报告为 Debian OpenSSL 错误。

于 2013-12-18T00:05:24.110 回答
1

所以在 Fedora 上看起来一切正常:

[bharrington@leviathan ~]$ python
Python 2.7.5 (default, Aug 22 2013, 09:31:58) 
[GCC 4.8.1 20130603 (Red Hat 4.8.1-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mechanize
>>> br = mechanize.Browser()
>>> br.open("https://wwws.mint.com/login.event")
<response_seek_wrapper at 0x29b6440 whose wrapped object = <closeable_response at 0x29b6320 whose fp = <socket._fileobject object at 0x298d150>>>
>>> br.title()
'Mint > Start Here'
>>> 

这让我想知道正在使用的 SSL/OpenSSL 库。只是为了测试它,你可以从命令行运行:

$ openssl s_client -connect wwws.mint.com:443

您应该会看到 mint 的 SSL 证书,以及完整的证书链验证,以及最后一行:“验证返回码:0 (ok)”

虽然我非常怀疑这是一个 SSL 问题,但我认为值得一试。此外,验证 mechanize 的版本。Debian 以使用稳定版本的代码(不是新版本)而著称。我用 mechanize 验证的版本是 0.2.5

于 2013-09-15T06:20:06.073 回答