wrap_socket()收到了意外的关键字参数"server_hostname"? [英] wrap_socket() got an unexpected keyword argument 'server_hostname'?

查看:501
本文介绍了wrap_socket()收到了意外的关键字参数"server_hostname"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python测试Web服务器.我几乎没有使用Python的经验,但是鼓励使用它,因为它易于学习且易于操作(其他人的观点,目前还不是我的观点).我正在使用的脚本是:

I'm trying to use Python to test a web server. I have nearly no experience with Python, but encouraged to use it because its easy to learn and simple to do things with (someone else's opinion, not mine at the moment). The script I am using is:

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = ssl.wrap_socket(s1,
                     ca_certs="./pki/signing-dss-cert.pem",
                     cert_reqs=ssl.CERT_REQUIRED,
                     ssl_version=ssl.PROTOCOL_TLSv1,
                     server_hostname="localhost")

s2.connect( ("localhost", 8443) )

s2.send("GET / ")
time.sleep(1)
s2.send("HTTP/1.1")

错误是:

Traceback (most recent call last):
  File "./fetch.sh", line 10, in <module>
    server_hostname="localhost")
TypeError: wrap_socket() got an unexpected keyword argument 'server_hostname'

我也曾尝试使用servernamenamehostnamesni,但没有任何乐趣.

I've also tried using servername, name, hostname and sni with no joy.

Python文档未提及SNI(套接字对象的TLS/SSL包装器 SSL Wiki页面).但是我知道SNI和server_hostname的补丁是4年前在2010年合并的(添加* SSLContext.wrap_socket 的server_hostname *参数,更改集65593:846c0e1342d0 ).

The Python docs don't mention SNI (TLS/SSL wrapper for socket objects and SSL wiki page). But I know the patch for SNI and server_hostname was incorporated 4 years ago in 2010 (Add a *server_hostname* argument to SSLContext.wrap_socket, changeset 65593:846c0e1342d0).

我需要访问的等效OpenSSL调用是SSL_set_tlsext_host_name.

The equivalent OpenSSL call I need access to is SSL_set_tlsext_host_name.

如何指定SNI主机名? (最终,由于我正在测试代理服务器,因此我需要将其设置为任意名称).

How do I specify the SNI hostname? (Eventually, I'll need to set it to an arbitrary name because I am testing a proxy).

推荐答案

向您修补提及是针对Python 3.2的,而您使用的是Python 2.7. 问题5639 似乎也表明没有计划向后移植SNI对Python 2.7的支持.

The patch you're mentioning is for Python 3.2, and you're using Python 2.7. Issue 5639 also seems to indicate there is no plan to back-port SNI support for Python 2.7.

您可以改为使用pyOpenSSL包装套接字(其Connection类具有 set_tlsext_host_name 从0.13版开始.(我不确定Debian 7.3随附哪个版本,如果需要,您可能需要设置virtualenv并在本地升级到较新的版本.)

You could wrap the socket with pyOpenSSL instead (its Connection class has a set_tlsext_host_name since version 0.13. (I'm not sure which version comes with Debian 7.3, you might want to set up a virtualenv and upgrade to a newer version locally, if needed.)

有一个 SNI示例是pyOpenSSL存储库.

There is an SNI example is the pyOpenSSL repository.

如果要替换httplib连接中的sock值为wrap_socket,则使wrap_socket的用法与该技巧更加兼容,那么可以看看

If you want your usage of wrap_socket to be more compatible with the trick were you replace the value of sock in an httplib connection, you could have a look at how urllib3 does this with pyOpenSSL. Essentially, it creates an OpenSSL.SSL.Connection from an existing socket, but since that connection isn't compatible with a socket, it wraps it into a class that implements the required method.

(顺便说一句,在Python 2.7中,urlliburllib2httpconnection根本不执行任何证书验证,除非您通过包装它们的套接字来实现它.)

(By the way, in Python 2.7, urllib, urllib2 and httpconnection don't do any certificate verification at all, unless you implement it yourself by wrapping their sockets.)

这是您的代码版本,应与Python 3.2一起使用.不幸的是,server_name参数不是在普通的ssl.wrap_socket中,而是在SSLContext.wrap_socket中,但是您可以直接使用SSLSocket.

Here is a version of your code that should work with Python 3.2. Unfortunately, the server_name parameter isn't in the plain ssl.wrap_socket, only in SSLContext.wrap_socket, but you can use SSLSocket directly.

import socket
import ssl

CA_BUNDLE_FILE="/etc/ssl/certs/ca-certificates.crt"


HOST = "sni.velox.ch"
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = ssl.SSLSocket(sock=s1, ca_certs=CA_BUNDLE_FILE,
                     cert_reqs=ssl.CERT_REQUIRED,
                     ssl_version=ssl.PROTOCOL_TLSv1,
                     server_hostname=HOST)

s2.connect((HOST, 443))

s2.send(bytes("GET / HTTP/1.1\n", "UTF-8"))
# This might need to be modified when using another port
s2.send(bytes("Host: %s\n" % (HOST,), "UTF-8"))
s2.send(bytes("\n", "UTF-8"))

# Certainly not the best way to read the response, but it works.
while True:
    x = s2.read()
    if not x:
        break
    print(x)

这篇关于wrap_socket()收到了意外的关键字参数"server_hostname"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆