3

I am using python socketio for communication and it works well for http. Have a problem when upgraded it to work with SSL.

I made a self-signed root certificate (CA), and issued server.cert and server.key. I told the computer to trust the CA. After that, I added the server.cert and server.key on the flask-socketio server side. And the code looks like this:

from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_socketio import Namespace

app = Flask(__name__, template_folder="templates")

app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

# Create a URL route in our application for "/"
@app.route('/')
def home():
    """
    This function loads the homepage
    """
    return render_template('index.html')


class MyCustomNamespace(Namespace):
    def on_connect(self):
        print("Client just connected")

    def on_disconnect(self):
        print("Client just left")

    def on_messages(self, data):                     
        print(f"\nReceived data from client: \n {data}\n")
        return data

socketio.on_namespace(MyCustomNamespace('/channel_A'))

if __name__ == "__main__":
    socketio.run(app, host="192.168.0.28", port=2000, certfile="server.crt", keyfile="server.key", server_side=True, debug=True)    
    #socketio.run(app, host="192.168.0.28", port=2000, debug=True)

The code for client connection is simply:

import socketio

sio = socketio.Client()

def message_received(data):
    print(f"Message {data} received")

@sio.on('connect', namespace="/channel_A")
def on_connect():
    print("Connect...")

@sio.on('disconnect', namespace="/channel_A")
def on_disconnect():
    print(f"Disconnected from server")

if __name__ == '__main__':
    sio.connect('https://192.168.0.28:2000', namespaces="/channel_A")
    emit_times = 0
    is_emit = True
    data = '{"data": "foobar"}'
    while is_emit:        
        sio.emit("messages", data, namespace="/channel_A", callback=message_received)
        emit_times += 1                                
        if emit_times > 1:
            is_emit = False                 
    sio.disconnect()  

I am using python-socketio (https://python-socketio.readthedocs.io/en/latest/client.html#disconnecting-from-the-server) for client end.

When the server gets started, the website works well and the connection is secure. The command line looks like this:

 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 142-782-563
(3484) wsgi starting up on https://192.168.0.28:2000

When SocketIO client tries to connect with the server, the connection is refused and on the server end, the error is finally thrown like this:

ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:2488)

I think I probably miss something. Any ideas? Thanks in advance!

Tyrion
  • 405
  • 8
  • 22
  • What do you mean exactly by "I told the computer to trust the CA"? You probably configure your browser to trust it, which is separate from using a Python client. You can provide a trusted CA for python requests through the REQUESTS_CA_BUNDLE environment variable, but there is currently no similar option for the websocket request. – Miguel Grinberg Sep 13 '19 at 18:15
  • Hi, thanks for the response. I created a self-signed root ssl certificate and added it to my Mac's KeyChains. That's how I told the computer to trust the CA. – Tyrion Sep 13 '19 at 18:26
  • 1
    Your code is using its own truststore, and not the OS one... – Patrick Mevzek Sep 13 '19 at 18:56
  • Hi Patrick, thanks for the response! Would you please explain it a bit more? – Tyrion Sep 16 '19 at 12:03
  • 1
    Firefox for example does not use by default the OS truststore, but its own. See https://support.mozilla.org/en-US/kb/setting-certificate-authorities-firefox for details. Same for your Python code it is probably using its own truststore, not the OS one. So you have to add your specific certificate at the proper place. – Patrick Mevzek Jan 15 '20 at 22:36
  • Hi Patrick, thank you for the feedback! – Tyrion Jan 16 '20 at 16:10

1 Answers1

0

It seems that this is a bug in a newer SocketIO version. You can try to downgrade to 2.x.x:

pip install python-socketio<3.0.0  --force-reinstall
Rene B.
  • 6,557
  • 7
  • 46
  • 72