Python SSL 套接字服务器 [英] Python SSL Socket Server

查看:41
本文介绍了Python SSL 套接字服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想设置一个基本的 ssl-authenticated socket 服务器来进行一些网络通信.我收到以下错误.它似乎来自 SSLIOStream 未在阅读前握手:

I want to set up a basic ssl-authenticated socket server to do some network communication. I'm getting the error below. It seems to be coming from the SSLIOStream not handshaking before reading:

  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()

我使用以下命令创建了密钥文件和证书:

I created the keyfile and certificate with the following command:

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem

推荐答案

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

Tornado is able to maintain an SSL connection itself using python 2.6+ and OpenSSL. Why are you attempting to manually build out the SSL socket connection?

查看:http://www.tornadoweb.org/documentation/httpserver.html#http-server

关键说明:

HTTPServer 可以使用 Python 2.6+ 和 OpenSSL 提供 SSL 流量.使此服务器提供 SSL 流量,发送 ssl_options 字典带有 ssl.wrap_socket 方法所需参数的参数,包括证书文件"和密钥文件":

HTTPServer can serve SSL traffic with Python 2.6+ and OpenSSL. To make this server serve SSL traffic, send the ssl_options dictionary argument with the arguments required for the ssl.wrap_socket method, including "certfile" and "keyfile":

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

这篇关于Python SSL 套接字服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆