Python openSSL服务器连接崩溃 - SSL上的奇怪错误

时间:2013-05-23 12:07:10

标签: python ssl python-2.7 openssl

我正在尝试运行SSL服务器,因此它可以接受JSON对象并使用其他JSON对象进行回复。但是,在做JSON对象之前,我决定做一个简化版本,我遇到了这个奇怪的错误,我找不到任何关于SSL的错误。除非我做错了,否则证书生成的解决方案似乎不起作用。所以这就是我所做的一切:

Python服务器

import socket
import re
import ssl

# Standard socket stuff:
host = ''  # do we need socket.gethostname() ?
port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1)  # don't queue up any requests

# Loop forever, listening for requests:
while True:
    csock, caddr = sock.accept()
    connstream = ssl.wrap_socket(csock,
                                 server_side=True,
                                 certfile="cert.pem",
                                 keyfile="cert.pem",
                                 ssl_version=ssl.PROTOCOL_SSLv23)
    print "Connection from: " + `caddr`

    dataBuf = connstream.recv(4096) # read what is there to read
    extraData = connstream.recv(4096) #see if there is more
    while len(extraData) != 0: #if something extra was read
        dataBuf += extraData
        extraData = connstream.recv(4096) #check again



    print '--------'
    print len(dataBuf), dataBuf
    # Look in the first line of the request for a move command
    # A move command should be e.g. 'http://server/move?a=90'
    match = re.match('GET /move\?a=(\d+)\sHTTP/1', dataBuf)
    if match:
        angle = match.group(1)
        print "ANGLE: " + angle + "\n"
        connstream.sendall("HTTP/1.0 200 OK\r\n"+
                             "Content-Type: text/html\r\n"+
                             "Connection: close\r\n"+
                             "\r\n"+
        """<!DOCTYPE html>
        <head>
        <title>Success</title>
        </head>
        <body>
        Boo!
        </body>
        </html>\r\n
        """)
    else:
        # If there was no recognised command then return a 404 (page not found)
        print "Returning 404"
        connstream.sendall("HTTP/1.0 404 Not Found\r\n")
    #connstream.shutdown(socket.SHUT_RDWR)
    connstream.close()

密钥和证书的生成:我不确定我在“公共名称”部分是否做错了,因为我在帖子Python SSL example from docs gives "Connection reset by peer" error后面给了localhost.localdomain

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

我如何填写字段:

Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:C
Locality Name (eg, city) []:C
Organization Name (eg, company) [Internet Widgits Pty Ltd]:U of C
Organizational Unit Name (eg, section) []:CL
Common Name (e.g. server FQDN or YOUR name) []:localhost.localdomain
Email Address []:unis

Errors: after going to https://localhost:8080/move?a=77 on a browser (Firefox and Chrome)

Connection from: ('127.0.0.1', 39107)
Traceback (most recent call last):
  File "ser.py", line 29, in <module>
    dataBuf = connstream.recv(44096) # read what is there to read
  File "/usr/lib/python2.7/ssl.py", line 241, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 160, in read
    return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

帮助表示感谢!谢谢!

ps:我尝试过TLSv1和PROTOCOL_SSLv23,同样的错误......

///关注:

我上了Firefox并手动添加了证书。

现在我明白了:

Connection from: ('127.0.0.1', 39220)
Traceback (most recent call last):
  File "ser.py", line 29, in <module>
    dataBuf = connstream.recv(44096) # read what is there to read
  File "/usr/lib/python2.7/ssl.py", line 241, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 160, in read
    return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094419:SSL routines:SSL3_READ_BYTES:tlsv1 alert access denied

任何想法?

//再试一次:

我告诉Firefox相信证书,现在我得到了

Connection from: ('127.0.0.1', 39248)
Traceback (most recent call last):
  File "ser.py", line 29, in <module>
    dataBuf = connstream.recv(44096) # read what is there to read
  File "/usr/lib/python2.7/ssl.py", line 241, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 160, in read
    return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate

搜索这个什么都没有!

//跟进:

使用http://devsec.org/info/ssl-cert.html重新生成密钥和证书,也作为公用名localhost。我得到连接,但服务器卡住了,从不回复......读取部分有问题吗?

1 个答案:

答案 0 :(得分:1)

关于后续问题,我怀疑问题出在这个代码上......

dataBuf = connstream.recv(4096) # read what is there to read
extraData = connstream.recv(4096) #see if there is more
while len(extraData) != 0: #if something extra was read
    dataBuf += extraData
    extraData = connstream.recv(4096) #check again

...将尝试从套接字读取,直到它到达EOF。

但是,大多数浏览器默认使用persistent HTTP connection,这意味着它们在发送请求后不会关闭其套接字的出站一半,因此EOF不会发生,并且您的代码将被阻止其中一个recv()来电。

如果要实现符合要求的HTTP服务器,则需要熟悉the protocol。你必须逐行阅读HTTP标题,注意ConnectionContent-Length标题,一旦你到达标题的末尾,你应该只尝试阅读如果请求标头包含Content-Length,则Connection: keep-alive个字节。

协议可能会变得更复杂,因此使用内置的Python HTTP服务器并包装套接字可能更简单。 python https server的快速Google会产生fairly simple example作为第一个结果。