Firefox disconnects websockets connection for a self signed certificate
Asked Answered
L

3

8

I am trying to make websocket connection to a backend server that uses a self-signed certificate. In firefox I've added an exception for the self-signed cert.

However my websocket connection wss:// fails to connect. I get a close event with code 1006 which is a catch all code.

Chrome and IE websockets work. Since I am using windows, I've installed the cert using certmgr.exe as a trusted cert.

My guess right now is that firefox websockets do not work with certificate exceptions and need to be trusted.

Has this scenario worked for anyone else?

Leyba answered 31/12, 2014 at 20:20 Comment(0)
O
14

Just in case it could help anyone, what is mentioned in OP's answer is not true at this time of writing (v61.0.1).

I navigated to the address of my WS server using https, as any WS server is practically an HTTP server, then the usual invalid certificate screen appeared and allowed me to add an exception. After that any wss connection made to the same host and port is successful.

Openhearted answered 23/8, 2018 at 11:51 Comment(1)
OMG , been stuck on this for hours ! thanksPraise
L
7

Firefox works with secure websockets (wss://) only when the certificate of the site is trusted.

With a self-signed certificate I was able to browse the site by adding an exception to the certificate. The exception is not used for websockets and the connection was dropped during the ssl handshake.

Instead I created my own Root CA cert and then another signed cert for the webserver. In Options > View Certificates > Authorities I imported the Root cert. Now firefox is able to connect over secure websockets without any issue.

Firefox does not allow for importing of self-signed certs as Authorities. Windows Certificate manager allows importing of self signed certs into the "Trusted Root Certificate Authorities" list.

Leyba answered 2/1, 2015 at 22:57 Comment(0)
I
0

@rrevo's answer is correct; however, the problem is more complicated when your wss://localhost:8001 endpoint is on a different port than the https://localhost:8000. Clicking Accepting The Risk And Continue when visiting https://localhost:8000 for the first time is insufficient.

If that's your case, then you have to explicitly add the exception to Firefox by clicking Settings > Privacy & Security > View Certificates... > Add Exception... > Servers and add https://localhost:8001 (not wss://localhost:8001)

enter image description here enter image description here

For me, generating a self-signed certificate without Root CA was enough. Nevertheless, I tested both methods by creating self-signed certificates with my own custom Root CA, and both worked.

Generate Self-signed Certificates Without Root CA

app.ssl.conf

[req]
default_bits        = 4096
distinguished_name  = req_distinguished_name
prompt              = no
req_extensions      = req_ext

[ca]
default_ca  = CA_default

[CA_default]

default_days      = 365
default_crl_days  = 30
default_md        = sha1

[req_distinguished_name]
commonName                  = example.com
countryName                 = DK
localityName                = Copenhagen
organizationName            = Example Inc.
organizationalUnitName      = IT
stateOrProvinceName         = Denmark

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1  = 0.0.0.0
IP.2  = 127.0.0.1
# Generate self-signed 
openssl req \
  -config app.ssl.conf \
  -keyout /etc/app/certs/app.key \
  -newkey rsa:4096 \
  -out /etc/app/certs/app.crt \
  -passout pass:foobar \
  -x509

# Fix permissions
chmod 600 /etc/app/certs/app.crt /etc/app/certs/app.key

Generate Self-signed Certificates With Root CA

root.ssl.conf

[req]
default_bits        = 4096
distinguished_name  = req_distinguished_name
prompt              = no
req_extensions      = req_ext

[ca]
default_ca  = CA_default

[CA_default]

default_days      = 365
default_crl_days  = 30
default_md        = sha1

[req_distinguished_name]
commonName                  = example.org
countryName                 = DK
localityName                = Copenhagen
organizationName            = Example Inc.
organizationalUnitName      = IT
stateOrProvinceName         = Denmark

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1  = 0.0.0.0
IP.2  = 127.0.0.1
# Generate the root key for CA
openssl ecparam -out /tmp/root.key -name prime256v1 -genkey

# Generate the certificate signing request for the root CA
openssl req -new -sha256 -key /tmp/root.key -out /tmp/root.csr -config /usr/src/config/root.ssl.conf

# Generate self-signed certificate for root CA
openssl x509 -req -sha256 -days 365 -in /tmp/root.csr -signkey /tmp/root.key -out /tmp/root.crt

# Generate the key for the app
openssl ecparam -out /etc/app/certs/app.key -name prime256v1 -genkey

# Generate the certificate signing request for the app
openssl req -new -sha256 -key /etc/app/certs/app.key -out /etc/app/certs/app.csr -config /usr/src/config/app.ssl.conf

# Generate self-signed certificate for the app
openssl x509 -req -in /etc/app/certs/app.csr -CA  /tmp/root.crt -CAkey /tmp/root.key -CAcreateserial -out /etc/app/certs/app.crt

# Fix permissions
chmod 600 /etc/app/certs/app.key /etc/app/certs/app.crt

What's left was to point my apps (https on port 8000 and wss on port 8001) to the generated certificates.

uvicorn config.asgi:application_starlette \
  --host 0.0.0.0 \
  --port 8001 \
  --ssl-certfile /etc/app/certs/app.crt \
  --ssl-keyfile /etc/app/certs/app.key \
  --ssl-keyfile-password foobar \
  --workers 4 \
  &
uvicorn config.asgi:application_django \
  --host 0.0.0.0 \
  --port 8000 \
  --ssl-certfile /etc/app/certs/app.crt \
  --ssl-keyfile /etc/app/certs/app.key \
  --ssl-keyfile-password foobar \
  --workers 4
Inconsistent answered 7/6 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.