Python SSL Socket Server - PullRequest
       15

Python SSL Socket Server

3 голосов
/ 07 января 2012

Я хочу настроить базовый сервер сокетов с аутентификацией 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

Ответы [ 2 ]

3 голосов
/ 19 января 2012

Tornado может самостоятельно поддерживать соединение SSL, используя python 2.6+ и OpenSSL.Почему вы пытаетесь вручную установить соединение через сокет SSL?

Проверьте: http://www.tornadoweb.org/documentation/httpserver.html#http-server

Подпись ключа:

HTTPServer может обслуживать трафик SSL с Python2.6+ и OpenSSL.Чтобы этот сервер обслуживал трафик SSL, отправьте аргумент словаря ssl_options с аргументами, необходимыми для метода ssl.wrap_socket, включая «certfile» и «keyfile»:

HTTPServer(applicaton, ssl_options={
    "certfile": os.path.join(data_dir, "mydomain.crt"),
    "keyfile": os.path.join(data_dir, "mydomain.key"),
})
0 голосов
/ 24 августа 2012

PEMS? Разве это не должно быть pem?

    ca_certs="fake_auth/server_certfile.pems",

Ты заставил его работать?

...