[PYTHON] HTTPS with Django and Let's Encrypt

Introduction

I use Python, which is rare for me. I had to write a web app in Python at work and used Django. It was my first time with Django, but I found it to be an unexpectedly easy-to-use framework. With a good framework and kind tutorials, the differences in language specifications aren't too noticeable.

It was HTTP that I built at work, but I decided to try HTTPS with Let's Encrypt, so I launched this article.

Build a server

Create an AWS EC2 server

This time I chose Ubuntu. I think Amazon Linux is based on CentOS, but I can't start Django because the version of sqlite is low.

--Sign in to the AWS console and run "Create Instance".

django_https_1.PNG

--Select Ubuntu 18.04 LTS as the AMI type.

django_https_2.PNG

--Minimum instance type is OK

django_https_3.PNG

After that, there is a confirmation of the settings, and click "Start" to start.

--Create a key pair here and download the private key.

django_https_4.PNG

The private key can only be downloaded here and without it you will not be able to log in to the server.

--Select a security group for your instance's page.

django_https_5.PNG

--Click "Edit Inbound Rule".

django_https_6.PNG

--Click "Add Rule" to add HTTP and HTTPS so that they can be accessed from "anywhere" respectively. Also, add another "custom TCP" and add port number 8000.

django_https_7.PNG

--Log in to Tera Term with a public IP address. For SSH authentication, specify ** ubuntu ** for "Username". No passphrase required. Specify the private key file downloaded in step 4.

――After logging in, let's update the package.

sudo apt update
sudo apt -y upgrade

The grub menu will say that it's new, so select "install the package maintainer's version".

django_https_8.PNG

--Install Apache HTTP Server.

sudo apt -y install apache2
sudo systemctl start apache2

Set the server name.

sudo vi /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        ServerName my.domain.jp

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

Domain acquisition

You will need to get a domain because you will get a server certificate. In my case, I use a DDNS service called MyDNS. If you need information, please see below.

Private MyDNS.JP

Creating a server certificate with Let's Encrypt

Install certbot.

sudo apt -y install certbot python3-certbot-apache

Run Let's Encrypt's automated shell certbot.

sudo certbot --apache

The certificate is created by interactively entering the email address and server name as shown below.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: n

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: my.domain.jp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for my.domain.jp
Enabled Apache rewrite module
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/apache2/sites-available/000-default-le-ssl.conf
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Deploying Certificate to VirtualHost /etc/apache2/sites-available/000-default-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/000-default-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter](press 'c' to cancel): 2
Enabled Apache rewrite module
Redirecting vhost in /etc/apache2/sites-enabled/000-default.conf to ssl vhost in /etc/apache2/sites-available/000-default-le-ssl.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://my.domain.jp

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=my.domain.jp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/my.domain.jp/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/my.domain.jp/privkey.pem
   Your cert will expire on 2020-09-04. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Check with browser

When you access https://my.domain.jp/, the default screen of apache2 is displayed, and you can see that the server certificate issued by Let's Encrypt is installed.

django_https_9.PNG

Creating a Django application

Create a web application using Django.

Django installation

Since python is installed by default, install pip and sqlite3.

sudo apt -y install python-pip sqlite3

Install the OpenSSL python extension.

pip install pyOpenSSL

Then install Django.

sudo pip install Django

Django Extensions

Install Django Extensions to make your Django development server HTTPS-enabled.

pip install django-extensions

Install Werkzeug

pip install Werkzeug

Create a Django project

Create a project.

django-admin startproject letsencrypt
cd letsencrypt

Copy the Let's Encrypt server certificate and private key to your project folder.

sudo cp /etc/letsencrypt/live/my.domain.jp/fullchain.pem .
sudo cp /etc/letsencrypt/live/my.domain.jp/privkey.pem .
sudo chown ubuntu:ubuntu *.pem

Enable Django Extensions.

vi letsencrypt/settings.py

Add'django_extensions' to the end of INSTALLED_APPS. Also, add the host name to ALLOWED_HOSTS as you need to allow access by server name.

#Omission
ALLOWED_HOSTS = ['my.domain.jp']

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
]
#Omission

Server startup

Django's development server is usually started with runserver, but HTTPS servers are started with runserver_plus. Specify the server certificate file and private key file as arguments.

python manage.py runserver_plus --cert-file ./fullchain.pem --key-file ./privkey.pem 0:8000

Operation check

Please access https://my.domain.jp:8000/ with a browser and check that you can connect correctly with HTTPS.

django_https_10.PNG

Confirmation environment

Ubuntu 18.04.4 LTS (Amazon EC2) Python 2.7.17

Referenced site

Make Django development server Runserver SSL / HTTPS | CentOS 7 ( https://www.jacepark.com/how-to-setup-django-development-server-ssl-https-on-centos-7/)

Django Document Security in Django https://docs.djangoproject.com/en/3.0/topics/security/)

SECURE_PROXY_SSL_HEADER in Django Document

Recommended Posts

HTTPS with Django and Let's Encrypt
Django Project HTTPS Server Settings: Let's Encrypt
Make HTTPS for free with Amazon Linux2 + Freenom + Let's Encrypt
SSL-enable multiple sites on one server with nginx and Let's Encrypt
Let's try gRPC with Go and Docker
CentOS 6.4 with Python 2.7.3 with Apache with mod_wsgi and Django
Encrypt with Ruby (Rails) and decrypt with Python
Ramen map creation with Scrapy and Django
Internationalization with django
Domain registration and HTTPS conversion of Django application created with CodeStar with Route53
CRUD with Django
Generate and post dummy image data with Django
Django: Record User Agent and manage with Admin
Let's integrate Django and apache (httpd) on Mac! !!
Let's control EV3 motors and sensors with Python
Let's make a nervous breakdown app with Vue.js and Django-Rest-Framework [Part 1] ~ Django setup ~
Authenticate Google with Django
Let's transpose the matrix with numpy and multiply the matrices.
Django 1.11 started with Python3.6
Upload files with Django
Development digest with Django
Output PDF with Django
Markdown output with Django
Use Gentelella with django
Twitter OAuth with Django
Let's make a simple game with Python 3 and iPhone
Getting Started with Django 1
Send email with Django
File upload with django
Django --models.py and admin.py
Use LESS with Django
Let's make a Mac app with Tkinter and py2app
Pooling mechanize with Django
Use MySQL with Django
With and without WSGI
Start today with Django
Getting Started with Django 2
Let's create a PRML diagram with Python, Numpy and matplotlib.
[Let's play with Python] Image processing to monochrome and dots
Create an authentication feature with django-allauth and CustomUser in Django
Let's move word2vec with Chainer and see the learning progress
With me, cp, and Subprocess
Encryption and decryption with Python
Let's play with 4D 4th
Let's play with Amedas data-Part 1
Working with tkinter and mouse
Get started with Django! ~ Tutorial ⑤ ~
Python and hardware-Using RS232C with Python-
Create an API with Django
Let's run Excel with Python
Do Django with CodeStar (Python3.8, Django2.1.15)
Deploy Django serverless with Lambda
Python3 + Django ~ Mac ~ with Apache
Getting Started with Python Django (1)
Create a homepage with django
Let's make Othello with wxPython
Get started with Django! ~ Tutorial ④ ~
Let's play with Amedas data-Part 4
Getting Started with Python Django (4)
Web application creation with Django
Getting Started with Python Django (3)