1

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

蟒蛇服务器

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

密钥和证书的生成:我不确定我是否在“公用名”部分做错了,因为我在 localhost.localdomain 之后给出了来自文档的 Python SSL 示例给出了“对等连接重置”错误

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重新生成的密钥和证书,也作为 Common Name localhost。我得到了连接,但它的服务器卡住了,从不回复......读取部分可能有问题吗?

4

1 回答 1

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。

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

如果你想实现一个符合标准的 HTTP 服务器,你需要熟悉协议。您必须逐行阅读 HTTP 标头,注意Connection, 和Content-Length标头,并且一旦您到达标头的末尾,您应该只尝试读取最多Content-Length字节(如果请求标头包含Connection: keep-alive.

协议可能会稍微复杂一些,因此使用内置的 Python HTTP 服务器并包装套接字可能会更简单。一个快速的谷歌搜索python https server产生一个相当简单的例子作为第一个结果。

于 2013-05-23T13:16:40.600 回答