logo-letsencrypt

Free SSL/TLS On Linux Apache With Flask

This article is going to make Flask site served with Apache secured with SSL/TLS using Let’s encrypt.

Reference: https://console.cloud.google.com/marketplace/product/bitnami-launchpad/wordpress?hl=zh-TWhttps://docs.bitnami.com/google/apps/wordpress/https://certbot.eff.org

Introduction

I’m using Apache serving my WordPress, which was install with bitnami stack, and Flask. The Flask is running on port 5000 using Gunicorn and is hosting with Apache reverse Proxy.

The OS is Linux Debian 11 hosting on Google Cloud Platform Compute Engine, creating with WordPress Certified by Bitnami and Automattic.

What I’m doing in this article

I’m going to make my flask available with SSL/TLS certificate, by running the given instruction on certbot. For those not familiar it is a tool made Let’s encrypt certificate automatic and feasible.

Most of the steps are executed on shell, so please feel comfortable with terminals.

Connect to your server

You could connect to your server using SSH either straight by GCP, VSCode, or any method you’re familiar.

Go to /opt/bitnami/apache2/conf/vhosts. By default, this is where bitnami save additional virtual hosts apache configurations. On the other hand /opt/bitnami/apache/conf/bitnami/bitnami.conf and /opt/bitnami/apache/conf/bitnami/bitnami-ssl.conf defines the main virtual host response to non-SSL and SSL respectively.

My target is bs_web.conf, where I put my Flask app configurations. If you’re using a new server, please create a new .conf file.

# bs_web.conf
<VirtualHost *:80>
    ServerName bs.mysite.com

    ProxyRequests Off
    ProxyPreserveHost On

    # 排除Let's Encrypt驗證
    ProxyPass /.well-known/acme-challenge !

    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>

Run your Certbot

First time using certbot, you’ll have to install snap.

# Snap installation process
# https://snapcraft.io/docs/installing-snap-on-debian
sudo apt update
sudo apt install snapd
sudo snap install core

Now you could install Certbot and run it.

# Certbot installation
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Getting SSL/TLS certificate

I’m using both bn-cert and certbot. In order to prevent interaction, I’m going to configure the certificate myself instead of letting cerbot altering the conf files.

In addition, I’m using reverse proxy, so the request will be passed to Flask, thus adding webroot to define the root and leading http://mysite.com/.well-known/acme-challenge can be access.

You could find your webroot by checking DocumentRoot section in /opt/bitnami/apache2/conf/bitnami/bitnami.conf. Where I found that mine is /opt/bitnami/apache/htdocs.

# test with dry-run and the root will be /opt/bitnami/apache/htdocs where the bitnami 
sudo certbot certonly --dry-run --webroot -w /opt/bitnami/apache/htdocs -d bs.mysite.com

# Later if successful, you could run the real one to get certificate
sudo certbot certonly --apache --webroot -w /opt/bitnami/apache/htdocs -d bs.mysite.com

Configuring Apache with your SSL/TLS

After getting the certificate, you’ll know where you’re .pem is, put them in the configuration

# bs_web.conf
<VirtualHost *:80>
    ServerName bs.mysite.com
    Redirect permanent / https://bs.mysite.com/ # redirect all 80 port (http) to 443 port (https)
</VirtualHost>

<VirtualHost *:443>
    ServerName bs.mysite.com

    SSLEngine on
    SSLCertificateFile "/etc/letsencrypt/live/bs.mysite.com-0001/fullchain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/bs.mysite.com-0001/privkey.pem"

    ProxyRequests Off
    ProxyPreserveHost On

    # Excluding Let's Encrypt challenge
    ProxyPass /.well-known/acme-challenge !

    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>

Restart your Apache and all done!

sudo /opt/bitnami/ctlscript.sh restart apache