canonical/pylxd

Websocket fails to use client certificate

Closed this issue · 0 comments

When connecting to a remote LXD with a client certificate, the websocket client fails to connect:

import pylxd

# Don't mind the "localhost", I am using an SSH tunnel to a remote system
client = pylxd.Client(endpoint="https://localhost:8443",
                      cert=("/home/anton/snap/lxd/current/.config/lxc/client.crt",
                            "/home/anton/snap/lxd/current/.config/lxc/client.key"),
                      verify=False)

events = client.events()
events.connect()

This fails with:

Traceback (most recent call last):
  File "fails.py", line 11, in <module>
    events.connect()
  File "/home/anton/repos/my-home/controller/.venv/lib/python3.7/site-packages/ws4py/client/__init__.py", line 239, in connect
    self.process_response_line(response_line)
  File "/home/anton/repos/my-home/controller/.venv/lib/python3.7/site-packages/ws4py/client/__init__.py", line 307, in process_response_line
    raise HandshakeError("Invalid response status: %s %s" % (code, status))
ws4py.exc.HandshakeError: Invalid response status: b'403' b'Forbidden'

I believe this is because the certificate and key are not passed to the websocket client, since the following code works:

import pylxd

client = pylxd.Client(endpoint="https://localhost:8443",
                      cert=("/home/anton/snap/lxd/current/.config/lxc/client.crt",
                            "/home/anton/snap/lxd/current/.config/lxc/client.key"),
                      verify=False)


class ModifiedClient(pylxd.client._WebsocketClient):

    def __init__(self, *args, **kwargs):
        super().__init__(
            *args, **kwargs, ssl_options={"certfile": "/home/anton/snap/lxd/current/.config/lxc/client.crt",
                                          "keyfile": "/home/anton/snap/lxd/current/.config/lxc/client.key"})


events = client.events(websocket_client=ModifiedClient)
events.connect()

Thanks,

/Anton