使用pyopenssl连接到ipv6 ssl服务器

时间:2017-04-04 07:34:46

标签: python-2.7 ssl pyopenssl

我需要使用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重新协商?

1 个答案:

答案 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]