Принудительное закрытие соединения сервером при попытке подключения по протоколу SSL



Я пытаюсь создать ssl-соединение между сервером и клиентом, но постоянно получаю ошибку ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine.



Client.py



class Client(object):
def __init__(self):
threading.Thread(target=self.init_sock).start()
def init_sock(self):
host = 'localhost'
port = 49374
baresock = socket(AF_INET6, SOCK_STREAM)
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
self.servsock = context.wrap_socket(baresock, server_hostname=host)
try:
self.servsock.connect((host, port)) #<--- Line error is being thrown at
logging.info("Connection Successful")
except:
logging.info("Connection Problem")
return
threading.Thread(target=self.listen_loop).start()


И server.py :



class ClientHandler(socketserver.BaseRequestHandler):
def handle(self):
pass

class Server(socketserver.ThreadingTCPServer):
srvhost = ''
srvport = 49374

def __init__(self,
request_handler_class=ClientHandler,
certfile="../scache/cert.pem",
keyfile="../scache/key.pem",
ssl_version=ssl.PROTOCOL_TLSv1_2,
bind_and_activate=True):
self.address_family = socket.AF_INET6
self.certfile = certfile
self.keyfile = keyfile
self.ssl_version = ssl_version
server_address = (self.srvhost, self.srvport)
super(Server, self).__init__(server_address, request_handler_class, bind_and_activate)

def get_request(self):
newsocket, fromaddr = self.socket.accept()
context = ssl.create_default_context()
context.load_cert_chain(certfile=self.certfile, keyfile=self.keyfile) # <------ Hanging Here
logging.info("New Request from " + fromaddr[0])
connstream = context.wrap_socket(newsocket, server_side=True)
logging.info("Socket Wrapped")
return connstream, fromaddr


Когда я пытаюсь подключиться к серверу из клиента, клиент выдает WinError 10054, как было отмечено выше. Когда я пытаюсь использовать отладчик на стороне сервера, я могу следовать за ошибкой в метод socketserver.py S _handle_request_noblock, где request, client_address = self.get_request() вызывает ошибку OSError. Полная Обратная Связь:



Traceback (most recent call last):
File "C:Program FilesAnaconda3libthreading.py", line 916, in _bootstrap_inner
self.run()
File "C:Program FilesAnaconda3libthreading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "C:/Project/src/client.py", line 36, in init_sock
self.servsock.connect((host, port))
File "C:Program FilesAnaconda3libssl.py", line 1093, in connect
self._real_connect(addr, False)
File "C:Program FilesAnaconda3libssl.py", line 1084, in _real_connect
self.do_handshake()
File "C:Program FilesAnaconda3libssl.py", line 1061, in do_handshake
self._sslobj.do_handshake()
File "C:Program FilesAnaconda3libssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host


Что такое причина этой ошибки и как ее устранить? Спасибо.

576   1  

1 ответ:

В попытке повторить это, я использовал ваш код и имел ту же проблему, а затем понял, что мне не хватает certfile и keyfile, на которые ссылаются в конструкторе. Я сгенерировал файлы и поместил их в относительный путь, используя следующий код:

from OpenSSL import SSL, crypto

CRT_PATH = "../scache/cert.pem"  # self-signed certificate
KEY_PATH = "../scache/key.pem"  # private key used to sign the certificate


def generate_key():
    """
    Generate a private key and dump it to the key file.
    :return: key
    """
    key = crypto.PKey()
    key.generate_key(crypto.TYPE_RSA, 4096)
    with open(KEY_PATH, "w") as keyfile:
        keyfile.write(bytes.decode(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)))
    return key


def generate_crt(key):
    """
    Generate a self-signed certificate.
    :return: certificate
    """
    crt = crypto.X509()
    crt.get_subject().C = "US"
    crt.get_subject().ST = "New York"
    crt.get_subject().L = "New York"
    crt.get_subject().O = "CompanyName"
    crt.get_subject().OU = "UnitName"
    crt.get_subject().CN = "localhost"
    crt.set_pubkey(key)
    crt.set_serial_number(101010)
    crt.gmtime_adj_notBefore(0)
    crt.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
    crt.sign(key, 'sha256')  # Self-sign
    with open(CRT_PATH, "w") as crtfile:
        crtfile.write(bytes.decode(crypto.dump_certificate(crypto.FILETYPE_PEM, crt)))
    return crt


if __name__ == "__main__":
    generate_crt(generate_key())

Как только я сгенерировал certfile и keyfile, которые вы отметили, OSError больше не бросал, и приложение могло продолжать рукопожатие. Это наводит меня на мысль, что вероятным виновником проблемы является неверный путь к файлу certfile / keyfile, или файл является недопустимым.

Вы можете настроить пути, чтобы они были такими, какими вам нужно (я предполагал, что этот скрипт будет находиться в том же месте, что и ваш client.py и еще server.py) и вы, вероятно, должны настроить параметры сертификата на все, что вам нужно для вашего конкретного приложения.

Comments

    Ничего не найдено.