我想设置一个基本的ssl认证的套接字服务器来进行一些网络通信。我得到了下面的错误。它似乎是来自SSLIOStream,而不是在阅读之前握手:
File "simple_ssl_server.py", line 70, in connection_ready
node_io_stream.read_until("OK", on_ok)
File "/home/tombrown/skyhook/lib/python2.7/site-packages/tornado-2.1.1-py2.7.egg/tornado/iostream.py", line 161, in read_until
if self._read_to_buffer() == 0:
File "/home/tombrown/skyhook/lib/python2.7/site-packages/tornado-2.1.1-py2.7.egg/tornado/iostream.py", line 375, in _read_to_buffer
chunk = self._read_from_socket()
File "/home/tombrown/skyhook/lib/python2.7/site-packages/tornado-2.1.1-py2.7.egg/tornado/iostream.py", line 635, in _read_from_socket
chunk = self.socket.read(self.read_chunk_size)
File "/usr/lib/python2.7/ssl.py", line 151, in read
return self._sslobj.read(len)
SSLError: [Errno 1] _ssl.c:1354: error:1408F044:SSL routines:SSL3_GET_RECORD:internal error
下面是我的服务器代码:
import tornado.web
import tornado.httpserver
import select
import socket
import tornado.iostream
import random
import logging
import ssl
import functools
class SSLSocketServer(object):
def __init__(self, io_loop=None, config_file=None, debug=False):
if io_loop is None: io_loop = tornado.ioloop.IOLoop.instance()
# Set up our node-accepting socket on port 8013
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8013 # Arbitrary non-privileged port
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_sock.setblocking(0)
server_sock.bind((HOST, PORT))
# We allow a backlog of up to 128 pending connections.
server_sock.listen(128)
callback = functools.partial(self.connection_ready, server_sock)
io_loop.add_handler(server_sock.fileno(),
callback, io_loop.READ)
def connection_ready(self, sock, fd, events):
# In part from: https://github.com/saucelabs/monocle/blob/7bd978f1c6a2ad3d78dd3da0b5b73c3e215ebbf3/monocle/tornado_stack/network/__init__.py
while True:
# Wait for the basic socket to be available.
try:
node_sock, address = sock.accept()
except socket.error, e:
if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
return
# Wait for the ssl socket to be available.
try:
node_sock = ssl.wrap_socket(node_sock,
do_handshake_on_connect=False,
server_side=True,
certfile="cert.pem",
ssl_version=ssl.PROTOCOL_TLSv1)
except ssl.SSLError, err:
if err.args[0] == ssl.SSL_ERROR_EOF:
s.close()
return
else:
raise
except socket.error, err:
if err.args[0] == errno.ECONNABORTED:
s.close()
return
else:
raise
node_io_stream = tornado.iostream.SSLIOStream(node_sock)
def on_ok():
print "recieved OK!"
node_io_stream.read_until("OK", on_ok)
if __name__ == '__main__':
# Get a handle to the instance of IOLoop
io_loop = tornado.ioloop.IOLoop.instance()
worker = SSLSocketServer(io_loop)
# Start the IOLoop
io_loop.start()
下面是客户端代码:
import sys
import logging
import socket
from tornado import iostream
from tornado import ioloop
import uuid
from tornado.options import define, options
import json
import ssl
def main():
delim = '\r\n\r\n'
def send_request():
print "sending OK"
stream.write("OK")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
# stream = iostream.IOStream(s)
stream = iostream.SSLIOStream(s,
ssl_options= dict(
ca_certs="fake_auth/server_certfile.pems",
cert_reqs=ssl.CERT_NONE))
print "about to connect"
stream.connect(('', 8013), send_request)
ioloop.IOLoop.instance().start()
if __name__ == '__main__':
main()
我使用以下命令创建了密钥文件和证书:
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
发布于 2012-01-19 17:48:18
Tornado能够使用python 2.6+和OpenSSL自己维护SSL连接。为什么要尝试手动构建SSL套接字连接?
查看:http://www.tornadoweb.org/documentation/httpserver.html#http-server
关键标题:
Python HTTPServer可以通过
2.6+和OpenSSL服务SSL流量。要使此服务器提供SSL流量,请发送带有ssl.wrap_socket方法所需参数的ssl_options字典参数,包括“certfile”和“keyfile”:
HTTPServer(applicaton, ssl_options={
"certfile": os.path.join(data_dir, "mydomain.crt"),
"keyfile": os.path.join(data_dir, "mydomain.key"),
})
发布于 2012-08-24 10:48:00
pems?这不应该是pem
吗?
ca_certs="fake_auth/server_certfile.pems",
你让它起作用了吗?
https://stackoverflow.com/questions/8767757
复制