我需要使用pyopenssl连接到ipv6服务器。即使可能吗?对于ipv4我没有任何问题。这是我为ipv6尝试过的:
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_NONE, verify_cb)
ctx.use_privatekey_file (os.path.join(dir, 'client.pkey'))
ctx.use_certificate_file(os.path.join(dir, 'client.cert'))
ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
#Set up client
sock = SSL.Connection(ctx, socket.socket(socket.AF_INET6, socket.SOCK_STREAM))
sock.connect(('fe80::3a63:bbff:fe31:3013%ens32',443,0,0))
但是我收到以下错误:
sock.connect(('fe80::3a63:bbff:fe31:3013%ens32',443,0,0))
File "/root/Desktop/PY/ilodos2/venv/lib/python2.7/site-packages/OpenSSL/SSL.py", line 1455, in connect
return self._socket.connect(addr)
File "/usr/lib64/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 22] Invalid argument
pyopenssl的文档根本没有谈到ipv6。如果pyopenssl不能用于ipv6,是否还有其他模块用于我可以进行ssl重新协商?
答案 0 :(得分:1)
问题本身并不与PyOpenSSL真正相关,当你使用范围(链接本地)ipv6地址时,你需要传递正确的scopeid
as the fourth item of the address
tuple:
...
对于AF_INET6地址族,使用四元组(host,port,flowinfo,scopeid),其中flowinfo和scopeid表示C中struct sockaddr_in6中的sin6_flowinfo和sin6_scope_id成员。对于套接字模块方法,可以省略flowinfo和scopeid向后兼容性。 但请注意,省略scopeid可能会导致操作范围内的IPv6地址出现问题。
咨询ip addr
以显示正确的数字范围ID,例如对于ens32的scopeid 2,以下应该有效:
sock.connect(('fe80::3a63:bbff:fe31:3013%ens32', 443, 0, 2))
或使用getaddrinfo()
获取正确的地址:
ainfo = socket.getaddrinfo('fe80::3a63:bbff:fe31:3013%ens32', 443, socket.AF_INET6, socket.SOCK_STREAM)
address = ainfo[0][4]