Can't get SSL to work for a Secure Websocket connection

Viewed 4103

I'm new to Python but have to build a Websocket API for work. The website of the websockets module says that this code should work for secure websocket connections (https://websockets.readthedocs.io/en/stable/intro.html)

However, I cannot get the provided code to work..

import websockets
import asyncio
import pathlib
import ssl

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.load_verify_locations(pathlib.Path(__file__).with_name('localhost.pem'))

I get the error:

Traceback (most recent call last):

File "/Applications/Python 3.7/apii.py", line 7, in module> ssl_context.load_verify_locations(pathlib.Path(__ file__).with_name('localhost.pem'))

FileNotFoundError: [Errno 2] No such file or directory

Could you help me out?

PS. I do not get the idea of this ssl_context code at all. Could somebody explain the logic behind it, please?

2 Answers

I test websockets from docker containers. where I have NAT ips (cant use LetsEncrypt), and no * domain certificate. If I test directly in Firefox it works fine without any certificate. So disabling the SSL for testing purpose inside a firewall should be allowed.

Extract:

import asyncio
import websockets
import ssl
:    
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

async def logIn(uri, myjson):
    async with websockets.connect(uri) as websocket:
        await websocket.send(myjson)

async def logIn(uri, myjson):
    async with websockets.connect(uri, ssl=ssl_context) as websocket:
        await websocket.send(myjson)
        resp = await websocket.recv()
        print(resp)

myurl = f"wss://{args.server}:{args.port}"
print("connection url:{}".format(myurl))

# logdef is the json string I send in
asyncio.get_event_loop().run_until_complete(
    logIn(myurl, logdef)
)

Late answer but maybe still interesting for others. The documentation (1) for this specific example says:

This client needs a context because the server uses a self-signed certificate. A client connecting to a secure WebSocket server with a valid certificate (i.e. signed by a CA that your Python installation trusts) can simply pass ssl=True to connect() instead of building a context.

So if the server-certificate from the server you want to access has a valid certificate just do the following:

uri = "wss://server_you_want_to_connect_to_endpoint"
async with websockets.connect(uri, ssl=True) as websocket:
    and so on ...
Related