Setting up an SSL certificate is nowadays a mandatory step for any web application in production. However during the development this step is sometimes postponed, for instance when running a demonstration flask web-server or a Jupyter notebook on a remote server. This can put sensitive data at risk as it is then transmitted unencrypted over the network.
In this post, we will illustrate how to quickly setup a free SSL certificate using Let's Encrypt. Here we focus mostly on Linux servers, but most of this guide is also applicable to other operating systems.
Obtaining a Let's Encrypt SSL certificate
The typical steps for obtaining a Let's Encrypt SSL certificate are,
Configure the DNS of your domain to point to the IP or hostname of the server, using either
Create a folder where certificates will be stored,
Start a web-server in this folder (this requires root access),
cd ~/certs/ sudo python3 -m http.server 80then press
bgto run this process in backround
Go to certbot.eff.org, and in the drop-down menu select
I'm using "None of the above" on <your OS>. Follow the installation instructions to install certbot, but not the "Getting started" section.
Once Certbot is installed, run,
sudo certbot certonly --webroot -w ~/certs/ -d example.comwhere
example.comshould be changed to your domain name.
Once certificate were issued and are stored in
~/certs/, the web server can be stopped, by entering
Ctrl+C. We also need to make sure that the current user can read these certificates,
sudo chown $USER ~/certs/*
Enabling SSL in Flask
Update your Flask application script with,
import os.path from flask import Flask app = Flask(__name__) ... if __name__ == '__main__': app.run( host="0.0.0.0", ssl_context=(os.path.expanduser('~/certs/cert.pem'), os.path.expanduser('~/certs/privkey.pem')) )
It is worth repeating that Flask built-in server should not be used in production, however it can be failry useful when running demonstration applications, such as for instance Dash PlotLy dashboards.
Enabling SSL in Jupyter
Simply start Jupyter with,
jupyter notebook --ip=example.com --certfile=$HOME/cert/cert.pem --keyfile $HOME/cert/privkey.pem
example.com should be replaced with your domain name.