2012-01-07 72 views
3

我想建立一个基本的SSL验证套接字服务器来做一些网络通信。我收到下面的错误。这似乎是从SSLIOStream不握手来阅读前:Python SSL套接字服务器

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 
+0

看来,将“do_handshake_on_connect = False”更改为True会导致其正常工作。但是,这可能会导致握手期间的阻塞行为,这是不可取的。 – nottombrown 2012-01-07 18:43:27

回答

3

Tornado能够使用python 2.6+和OpenSSL自行维护SSL连接。你为什么试图手动构建SSL套接字连接?

退房:http://www.tornadoweb.org/documentation/httpserver.html#http-server

重点说明:

的httpserver可以起到与Python 2.6+和OpenSSL SSL流量。为了使 该服务器提供SSL流量,发送的ssl_options字典 大吵了ssl.wrap_socket方法, 所需的参数包括“certFile中”和“密钥文件”:

HTTPServer(applicaton, ssl_options={ 
    "certfile": os.path.join(data_dir, "mydomain.crt"), 
    "keyfile": os.path.join(data_dir, "mydomain.key"), 
}) 
+0

我可以确认这是一个插入式解决方案。我刚刚添加了ssl_options kwargs,并在循环中添加了另一个HTTPServer实例 - bam,HTTP和HTTPS – 2012-09-23 23:29:43

0

PEMS?这不应该是pem

ca_certs="fake_auth/server_certfile.pems", 

你是否得到它的工作?