Search code examples
djangoubuntuhttpsdjango-dev-server

Django https with a dev server


I'm trying to use SpeechRecognition/ webkitSpeechRecognition in my website, and thus need to run a dev server in django using https.

I've taken the following steps:

  • install and configure runserver_plus from django-extensions
  • add the cert generated by this to my cas in ubuntu.

    # run server
    python3 manage.py runserver_plus --cert-file certs/localhost --reloader-interval 2 0.0.0.0:8000
    

    then

    # to copy certificates:
    sudo mkdir /usr/share/ca-certificates/extra
    sudo cp certs/localhost.crt /usr/share/ca-certificates/extra/localhost.crt
    sudo chmod -R 755 /usr/share/ca-certificates/extra/ 
    sudo chmod 644 /usr/share/ca-certificates/extra/localhost.crt 
    sudo dpkg-reconfigure ca-certificates
    sudo update-ca-certificates
    

    I then restart everything to ensure changes have been accouted for, but the website is still not trusted on https://127.0.0.1:8000 and https://localhost:8000

What am I doing wrong?

Note:

awk -v cmd='openssl x509 -noout -subject' '
    /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt

# gives:
...
subject=CN = localhost
subject=CN = *.localhost/CN=localhost, O = Dummy Certificate

This is my chrome certificate invlaid screenshot:

chrome screenshot

Note II: I am also having the same issue in Firefox

Note III:

I have enabled Allow invalid certificates for resources loaded from localhost. by copying the below into the browser and selecting enable:

chrome://flags/#allow-insecure-localhost

enter image description here


Solution

  • This was not a quick fix. I'll outline the steps here that I took to fix the issue. For reference, I am using:

    • Django 2.2.1
    • Ubuntu 18.04.02
    • Google Chrome 75.0.3770.142

    My solution was heavily influenced by this article.

    # in /System/Library/OpenSSL/openssl.cnf
    # comment
    # RANDFILE      = $ENV::HOME/.rnd
    
    # uncomment
    req_extensions = v3_req
    
    # your domain can be whatever for a local dev server, i chose company.dev
    [ v3_req ]
    subjectAltName = @alt_names
    
    [ alt_names ]
    DNS.1 = company.dev
    DNS.2 = *.company.dev
    
    [ v3_ca ]
    # update
    basicConstraints = critical, CA:TRUE, pathlen:3
    # uncomment
    keyUsage = critical, cRLSign, keyCertSign
    nsCertType = sslCA, emailCA
    
    
    # in your project root, make a dir for certs:
    mkdir certs
    
    # Create CA certificate
    openssl genrsa -aes256 -out certs/ca.key.pem 2048
    
    # gen key
    openssl req -new -x509 -subj "/CN=companydev" -extensions v3_ca -days 3650 -key certs/ca.key.pem -sha256 -out certs/ca.pem -config /usr/lib/ssl/openssl.cnf
    
    # Create Server certificate signed by CA
    openssl genrsa -out certs/local.key.pem 2048
    
    openssl req -subj "/CN=local" -extensions v3_req -sha256 -new -key certs/local.key.pem -out certs/local.csr
    
    openssl x509 -req -extensions v3_req -days 3650 -sha256 -in certs/local.csr -CA certs/ca.pem -CAkey certs/ca.key.pem -CAcreateserial -out certs/local.crt -extfile /usr/lib/ssl/openssl.cnf
    
    cat certs/local.crt certs/local.key.pem > certs/local-ca-full.pem
    
    # move certificate to ca certs
    sudo cp certs/local.crt /usr/share/ca-certificates/extra/local.crt
    sudo chmod -R 755 /usr/share/ca-certificates/extra/ 
    sudo chmod 644 /usr/share/ca-certificates/extra/local.crt
    sudo dpkg-reconfigure ca-certificates
    sudo update-ca-certificates
    
    # update /etc/hosts
    127.0.0.1       localhost local.company.dev
    

    Add certificate to chrome:

    • Go to settings
    • Search HTTPS/SSL
    • Go to Authorities tab
    • Import certs/ca.pem
    # Finally run server with
    python3 manage.py runserver_plus --cert-file certs/local.crt --key-file certs/local.key.pem --reloader-interval 2 0.0.0.0:8000
    

    open your browser at https://local.company.dev:8000/ and have a well deserved coffee

    If I have missed anything please don't hesitate to comment and I'll update the answer