Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python wrap_socket()获取了意外的关键字参数';服务器主机名';?_Python_Ssl_Sni - Fatal编程技术网

Python wrap_socket()获取了意外的关键字参数';服务器主机名';?

Python wrap_socket()获取了意外的关键字参数';服务器主机名';?,python,ssl,sni,Python,Ssl,Sni,我正在尝试使用Python测试web服务器。我几乎没有Python方面的经验,但我鼓励使用它,因为它很容易学习,而且使用起来也很简单(别人的意见,现在不是我的意见)。我使用的脚本是: s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s2 = ssl.wrap_socket(s1, ca_certs="./pki/signing-dss-cert.pem",

我正在尝试使用Python测试web服务器。我几乎没有Python方面的经验,但我鼓励使用它,因为它很容易学习,而且使用起来也很简单(别人的意见,现在不是我的意见)。我使用的脚本是:

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'
回溯(最近一次呼叫最后一次):
文件“/fetch.sh”,第10行,在
服务器\u hostname=“localhost”)
TypeError:wrap_socket()获得意外的关键字参数“server_hostname”
我也尝试过使用
servername
name
hostname
sni
,但毫无乐趣

Python文档没有提到SNI(和)。但我知道SNI和服务器主机名的补丁是4年前在2010年(,)合并的

我需要访问的等效OpenSSL调用是
SSL\u set\u tlsext\u host\u name


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

首先连接,然后包装套接字

import socket, ssl
sock = socket.create_connection( ('localhost', 443) )
sock = ssl.wrap_socket(sock, ca_certs="./pki/signing-dss-cert.pem", cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1)
在python2的情况下,我有时也会使用以下hack(因为
httplib.HTTPSConnection
文档说明它不会对https服务器证书执行任何类型的检查):

请注意,如果您想与服务器通信,那么使用http客户端通常比使用原始套接字容易得多。

这是针对Python 3.2的,您使用的是Python 2.7。似乎还表明没有计划支持Python 2.7的SNI端口支持

您可以用pyOpenSSL来包装套接字(它的
连接
类的版本为0.13(我不确定Debian 7.3附带了哪个版本,如果需要,您可能需要在本地设置virtualenv并升级到新版本)

pyOpenSSL存储库是一个重要的存储库

如果您想让
wrap_socket
的使用与技巧更兼容,如果您在
httplib
连接中替换
sock
的值,您可以看看如何使用。本质上,它从现有套接字创建
OpenSSL.SSL.connection
,但由于该连接与so不兼容在cket中,它将其包装到实现所需方法的类中

(顺便说一句,在Python2.7中,
urllib
urllib2
httpconnection
根本不进行任何证书验证,除非您自己通过包装它们的套接字来实现。)

编辑:

这是一个应该使用Python 3.2的代码版本。不幸的是,
server\u name
参数不在普通的
ssl.wrap\u socket
中,仅在
SSLContext.wrap\u socket
中,但您可以直接使用
SSLSocket

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)

我的环境是:requests==2.7.0,python-2.7.5-34.el7.x86_64,gevent==1.0.2

将python版本更改为python-2.7.5-18.el7_1.1.x86_64,问题就解决了

在CentOS:

sudo rpm -Uvh --oldpackage python-devel-2.7.5-18.el7_1.1.x86_64.rpm  python-libs-2.7.5-18.el7_1.1.x86_64.rpm  python-2.7.5-18.el7_1.1.x86_64.rpm

pakages可以在google上搜索。

@noloader我担心这个简单的ssl实现不会公开这样的选项。谢谢pasztorpisti。代码已经更改,但错误仍然存在。@noloader我在你的帖子中没有看到我的代码,所以我对它不起作用并不感到惊讶。谢谢pasztorpisti。请原谅我的无知……这里出现了代码above没有设置服务器名,这正是我试图实现的。在您的示例中,假设您希望连接到
google.com
,但将TLS服务器名扩展名设置为
example.com
,以进行测试。顺便说一句,我正在使用Python wiki中的代码。尝试将我的代码与您的代码合并,并尝试使用服务器创建连接时使用名称而不是“localhost”
。您使用的是哪一版本的Python?
sys.version\u info(major=2,minor=7,micro=3,releaselevel='final',serial=0)
。Debian 7.3(x64),已完全修补。感谢Bruno。“如果您希望使用wrap\u套接字更兼容…”-我只是想让它工作。我今天在上面浪费了大约4个小时,因为它应该更简单更快。我想我要回到C/C++。C/C++开发对我来说比试图解开你上面所说的一切都要快。我很困惑,最新的Debian使用的是一个旧的、未修补的库。我使用最新的发行版是有原因的,我这并不是因为我喜欢最前沿的bug。我不会以此来评判Python。如果你是Python新手,没有任何2.x遗留代码,你可以试试Python 3.2+解释器。如果你已经安装了包,那么应该可以使用
python3.2
调用它。再次感谢Bruno。这在我下载、构建和安装Python之后就起作用了3.4.奇怪的是,你必须获得python3.4并自己构建它。我通过安装
python3
包(并使用
python3.2
)在Debian系统上实现了这一点(以防你不知道,在Debian/Ubuntu上,Python版本可以一起安装(除了微级别的数字)默认情况下,
python
仍然是最新的2.x解释器,但您可以显式调用
python3.x
解释器。)
sudo rpm -Uvh --oldpackage python-devel-2.7.5-18.el7_1.1.x86_64.rpm  python-libs-2.7.5-18.el7_1.1.x86_64.rpm  python-2.7.5-18.el7_1.1.x86_64.rpm