@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
)
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