2011-12-01 77 views
15

我最近扩展了用于Windows Azure存储API(PyAzure)的Python API以包含对服务管理API的支持。见https://github.com/bmb/pyazure针对Azure服务管理API的Python HTTPS在Windows上失败

我使用的HTTPSClientAuthHandler与using pyOpenSSL to create urllib custom opener中建议的HTTPSClientAuthHandler类似。在Linux上,使用各种版本的Python 2.6和2.7,这很好。不过,Windows是另一回事。对Azure的管理主机地址的所有请求失败:

[错误10054]现有的连接被强行远程主机

这一点我觉得封闭,是socket错误号10054“连接重置对等“,在拖动。

这似乎不是我的API代码中的一个问题(除非我使用的客户端证书认证方法是虚假的),但是更低一层。我可以在没有urllib2或httplib的情况下通过简单地设置一个SSL套接字并且像urllib2一样向管道发送相同的HTTP请求来重现问题。列出有效的Azure数据中心位置:

>>> import socket, ssl, sys 
>>> sys.version 
'2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)]' 

>>> s = ssl.wrap_socket(socket.socket(), certfile='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem') 
>>> s.connect(('management.core.windows.net',443)) 
>>> s.send("GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nConnection: close\r\nUser-Agent: Python-urllib/2.6\r\n\r\n") 
202 

>>> s.read() 
Traceback (most recent call last): 
c:\Users\blair\research\clouds\azure\pyazure\<ipython-input-63-3306c981d8a7> 
in <module>() 
----> 1 s.read() 

C:\Python27\lib\ssl.pyc in read(self, len) 
    136 
    137   try: 
--> 138    return self._sslobj.read(len) 
    139   except SSLError, x: 
    140    if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: 


error: [Errno 10054] An existing connection was forcibly closed by the remote host 

用您的Azure订阅ID替换上面的SUBSCRIPTION_ID。在调用SSLSocket.read之后,异常提升〜45秒。该证书是既包括私钥和证书格式正确的PEM文件,将其从PFX(在Ubuntu 10.04)使用转化:

OpenSSL的PKCS12 -in pfxfile -out pemfile -nodes

我不认为它在这里很重要,但我也尝试unix2dos-PEM文件,但无济于事。即使我没有提供任何证书,我也会得到相同的行为,但在Linux上执行此操作会导致服务器出现适当的API错误:

'HTTP/1.1 403 Forbidden \ r \ nContent-Length:0 \ r \ n日期:2011年12月1日星期四13:59:29 GMT \ r \ n连接:关闭\ r \ n \ r \ n'

已经由另一个人使用Windows 7进行独立验证(与我一样)。这不是客户端防火墙问题 - 相同的代码在同一主机上运行的NAT-ed Linux VM中工作。

我很难过。真的很感谢所有帮助乡亲们在这里也许能提供...

更新: 这似乎与在Python底层SSL实现。 CPython的2.7.1具有如上所示的错误行为,但我因为测试,并取得了成功与ActiveState的Python的(包括2.7和2.6),例如:

>>> import sys, socket, ssl 
>>> sys.version 
'2.7.1 (r271:86832, Feb 7 2011, 11:30:38) [MSC v.1500 32 bit (Intel)]' 
>>> s = ssl.wrap_socket(socket.socket(), certfile='\\\\VBOXSVR\\azure\\BlairBethwaiteAzure1.pfx.pem') 
>>> s.connect(('management.core.windows.net',443)) 
>>> s.send('GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nUser-Agent: Python-urllib/2.6\r\n\r\n') 
183 

>>> s.read(4096) 
'HTTP/1.1 200 OK\r\nContent-Length: 908\r\nContent-Type: application/xml; charset=utf-8\r\nServer: Microsoft-HTTPAPI/2.0\r\nx-ms-request-id: 08ca048cda6b445da6b3a8f3e4890197\r\nDate: Fri, 02 Dec 2011 03:02:14 GMT\r\n\r\n<Locations xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Location><Name>Anywhere US</Name><DisplayName>Anywhere US</DisplayName></Location><Location><Name>South Central US</Name><DisplayName>South Central US</DisplayName></Location><Location><Name>North Central US</Name><DisplayName>North Central US</DisplayName></Location><Location><Name>Anywhere Europe</Name><DisplayName>Anywhere Europe</DisplayName></Location><Location><Name>North Europe</Name><DisplayName>North Europe</DisplayName></Location><Location><Name>West Europe</Name><DisplayName>West Europe</DisplayName></Location><Location><Name>Anywhere Asia</Name><DisplayName>Anywhere Asia</DisplayName></Location><Location><Name>Southeast Asia</Name><DisplayName>Southeast Asia</DisplayName></Location><Location><Name>East Asia</Name><DisplayName>East Asia</DisplayName></Location></Locations>' 

和预期的一样我的API也工作:

ActivePython 2.6.7.20 (ActiveState Software Inc.) based on 
Python 2.6.7 (r267:88850, Jun 27 2011, 13:20:48) [MSC v.1500 64 bit (AMD64)] on 
win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from pyazure import pyazure 
>>> pa = pyazure.PyAzure(subscription_id=SUBSCRIPTION_ID, management_cert_path='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem') 
>>> list(pa.wasm.list_locations()) 
['Anywhere US', 'South Central US', 'North Central US', 'Anywhere Europe', 'North Europe', 'West Europe', 'Anywhere Asia', 'Southeast Asia', 'East Asia'] 

的lib \ ssl.py在CPython2.7和ActivePython2.7文件是相同的,所以我想这一定是由于底层的C库差一些,也许在CPython的一个bug。那里有哪位大师?

+0

您是否有任何类似代理的过程,例如坐在您的机器上的Fiddler? –

+0

没有本地代理或嗅探器。 – Blairo

回答

2

我一直没能拖住这一个明确的解释,但有点试验和错误之后,我有信心在哪里的问题奠定了...

简短的回答:是的在Windows套件的http://www.python.org/中实现SSL。改用ActiveState Python。

龙答:可从http://www.python.org/download/束 在Windows CPython的分布很古老的版本的OpenSSL(0.9.8l)的,与基于CPython的,但ActiveState的Python发行(除其他事项外)相比,提供定期更新到第3如OpenSSL(目前为0.9.8r)。

我下载了OpenSSL的Windows二进制文件,并通过在OpenSSL的s_client.First接口测试,如:

的OpenSSL的s_client.First -connect management.core.windows.net:443 -cert /家庭/布莱尔/尼姆罗德-dev /目录BlairBethwaiteAzure1.pfx.pem

当前版本按预期工作。不幸的是,在Windows上使用旧的OpenSSL二进制文件似乎很难,因为它是一个安全库,这也许并不奇怪......但无论如何,我在Ubuntu 10.04下从源代码创建了0.9.8l,并发现它在发送HTTP请求后挂起沿管路,想必服务器直接丢弃由于某些原因,连接:

[email protected]:~/Downloads/openssl-0.9.8l/apps$ ./openssl s_client -connect management.core.windows.net:443 -cert ./BlairAzure.pem 
CONNECTED(00000003) 
depth=2 /CN=Microsoft Internet Authority 
verify error:num=20:unable to get local issuer certificate 
verify return:0 
--- 
Certificate chain 
0 s:/CN=management.core.windows.net 
    i:/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority 
1 s:/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority 
    i:/CN=Microsoft Internet Authority 
2 s:/CN=Microsoft Internet Authority 
    i:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root 
--- 
Server certificate 
-----BEGIN CERTIFICATE----- 
MIIGhDCCBWygAwIBAgIKFnL3ogAIAAIjlDANBgkqhkiG9w0BAQUFADCBizETMBEG 
CgmSJomT8ixkARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEUMBIG 
CgmSJomT8ixkARkWBGNvcnAxFzAVBgoJkiaJk/IsZAEZFgdyZWRtb25kMSowKAYD 
VQQDEyFNaWNyb3NvZnQgU2VjdXJlIFNlcnZlciBBdXRob3JpdHkwHhcNMTEwNjE2 
MDg0MjI3WhcNMTMwNjE1MDg0MjI3WjAmMSQwIgYDVQQDExttYW5hZ2VtZW50LmNv 
cmUud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCS 
Z9PTUqQLh5keX/IRJ6JxaQkVBIy/iyoCIx2Y0zy5F5tll8CRydGzFDjXMLWEG425 
EuuRDQrBgQnmVtlZ2t42QfIRBSvfJheZVh8k27g/tH5wpchZ47gxxatUKsVJ84P8 
Me2S0RP9xtk3P14dVqTDJIhUC3k8JYdBiTTtk64EB5Dbq8sxEtjVb/68XDgTZKek 
te/vqWSW/KcduKEjsfjOwNSM9UbYrFOTbelac+mf/L+CluAJpYAlIhOMUP2afy5e 
tYIg6zK04pDNjPjizpfN3xrGX7NRY16kaafrdqJQixfmEVlMDN8FsXLWDweXWfMM 
XRh4vuAVb6tA9wBkPDhZAgMBAAGjggNMMIIDSDALBgNVHQ8EBAMCBLAwHQYDVR0l 
BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZI 
hvcNAwICAgCAMA4GCCqGSIb3DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUD 
BAEtMAsGCWCGSAFlAwQBAjALBglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcN 
AwcwHQYDVR0OBBYEFEaKqx6Auvu3fvHS6KqQl8KXoOoAMB8GA1UdIwQYMBaAFAhC 
49tOEWbztQjFQNtVfDNGEYM4MIIBCgYDVR0fBIIBATCB/jCB+6CB+KCB9YZYaHR0 
cDovL21zY3JsLm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9jcmwvTWljcm9zb2Z0 
JTIwU2VjdXJlJTIwU2VydmVyJTIwQXV0aG9yaXR5KDgpLmNybIZWaHR0cDovL2Ny 
bC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL01pY3Jvc29mdCUyMFNlY3Vy 
ZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5jcmyGQWh0dHA6Ly9jb3JwcGtpL2Ny 
bC9NaWNyb3NvZnQlMjBTZWN1cmUlMjBTZXJ2ZXIlMjBBdXRob3JpdHkoOCkuY3Js 
MIG/BggrBgEFBQcBAQSBsjCBrzBeBggrBgEFBQcwAoZSaHR0cDovL3d3dy5taWNy 
b3NvZnQuY29tL3BraS9tc2NvcnAvTWljcm9zb2Z0JTIwU2VjdXJlJTIwU2VydmVy 
JTIwQXV0aG9yaXR5KDgpLmNydDBNBggrBgEFBQcwAoZBaHR0cDovL2NvcnBwa2kv 
YWlhL01pY3Jvc29mdCUyMFNlY3VyZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5j 
cnQwPwYJKwYBBAGCNxUHBDIwMAYoKwYBBAGCNxUIg8+JTa3yAoWhnwyC+sp9geH7 
dIFPg8LthQiOqdKFYwIBZAIBCjAnBgkrBgEEAYI3FQoEGjAYMAoGCCsGAQUFBwMC 
MAoGCCsGAQUFBwMBMCYGA1UdEQQfMB2CG21hbmFnZW1lbnQuY29yZS53aW5kb3dz 
Lm5ldDANBgkqhkiG9w0BAQUFAAOCAQEAsqHBR/JxRnGQMTXxJzCau49dDgeum1JH 
heA38lzsoUaRELHxxrQZskjSqc0HrI7cnJPSipWQseDDwKtLwXzukCdZNk84u7xo 
uHa7/dmxo1m+z353HSvEr85ZE2mzwF6qmwGMmvvVzIJ94M8fcN55yoF64vQsAWFF 
k2QJC9ccb8eDoTs5NX4ntpz02xf8eEBQ5yKZySfi3+oFJEUnLmXcvHTTMl/1N/NI 
fWiKIZ9PDTBlPxL5kNJ/aDGIgiqCi7Vm7KfjvWSFhopUPtVeeItgW9wMLEkuQsw6 
sViSbU50CMPWTJAslLZgCju6cxszgpLl19xrgNteHRw2HouwTTsJnA== 
-----END CERTIFICATE----- 
subject=/CN=management.core.windows.net 
issuer=/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority 
--- 
No client certificate CA names sent 
--- 
SSL handshake has read 4691 bytes and written 450 bytes 
--- 
New, TLSv1/SSLv3, Cipher is AES128-SHA 
Server public key is 2048 bit 
Compression: NONE 
Expansion: NONE 
SSL-Session: 
    Protocol : TLSv1 
    Cipher : AES128-SHA 
    Session-ID: <SNIP> 
    Session-ID-ctx: 
    Master-Key: <SNIP> 
    Key-Arg : None 
    Start Time: 1324443511 
    Timeout : 300 (sec) 
    Verify return code: 20 (unable to get local issuer certificate) 
--- 
GET /<SUBSCRIPTION_ID>/locations HTTP/1.1 
Accept-Encoding: identity 
X-Ms-Version: 2011-10-01 
Host: management.core.windows.net 
Connection: close 

在较新的,甚至年龄稍大(例如,Ubuntu10.04的0.9.8e)OpenSSLs服务器响应与预期的要求:

<Locations xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Location><Name>Anywhere US</Name><DisplayName>Anywhere US</DisplayName></Location><Location><Name>South Central US</Name><DisplayName>South Central US</DisplayName></Location><Location><Name>Anywhere Europe</Name><DisplayName>Anywhere Europe</DisplayName></Location><Location><Name>West Europe</Name><DisplayName>West Europe</DisplayName></Location><Location><Name>Anywhere Asia</Name><DisplayName>Anywhere Asia</DisplayName></Location><Location><Name>Southeast Asia</Name><DisplayName>Southeast Asia</DisplayName></Location><Location><Name>East Asia</Name><DisplayName>East Asia</DisplayName></Location><Location><Name>North Central US</Name><DisplayName>North Central US</DisplayName></Location><Location><Name>North Europe</Name><DisplayName>North Europe</DisplayName></Location></Locations> 

但是对于OpenSSL 0.9.8l,我什么也没得到。

0

我不是Python开发人员。但是在处理iPhone和Windows Phone的Azure服务时,我遇到了很多问题。请确保以下内容

+0

这不是证书或密钥的问题(除非它涉及由特定版本的OpenSSL读取的编码问题)。他们是PEM编码的,所以他们没有URL。没有证书存储需要担心,这是纯粹的跨平台Python使用文件,没有.NET纠缠。 – Blairo

2

下面的作品在OS X 10.6.8在Windows 7和CPython的2.6.6使用IronPython的2.7.1预期:

import socket, ssl, sys 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect(('management.core.windows.net',443)) 

s = ssl.wrap_socket(sock, certfile=sys.argv[1]) 
s.send('GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nUser-Agent: Python-urllib/2.6\r\n\r\n') 

print(s.read(4096)) 

[注:我传递MYKEYFILENAME.pem作为一个命令 - 线参数]

快乐天青黑客入侵!

相关问题