Securing A Containerized Django Application with Let's Encrypt

How do I set up an SSL Certificate for a Django application?

In this tutorial, we'll look at how to secure a containerized Django app running behind an HTTPS Nginx proxy with Let's Encrypt SSL certificates.

This tutorial builds on Dockerizing Django with Postgres, Gunicorn, and Nginx. It assumes you understand how to containerize a Django app along with Postgres, Nginx, and Gunicorn.

Nowadays you simply can't go to production with your application running over HTTP. Without HTTPS, your site is less secure and trustworthy. With Let's Encrypt, which simplifies the process of obtaining and installing SSL certificates, there's simply no excuse anymore not to have HTTPS.

Prerequisites

To follow this tutorial you will need:

Need a cheap domain to practice with? Several domain registrars have specials on '.xyz' domains. Alternatively, you can create a free domain at Freenom.

Approach

There are a number of different ways to secure a containerized Django app with HTTPS. Arguably, the most popular approach is to add a new service to your Docker Compose file that utilizes Certbot for issuing and renewing SSL certificates. While this is perfectly valid, we'll take a slightly different approach and use the following projects:

  1. nginx-proxy - used to automatically build your Nginx proxy configuration for running containers where each container is treated as a single virtual host
  2. letsencrypt-nginx-proxy-companion - used to issue and renew Let's Encrypt SSL certificates for each of the containers proxied by nginx-proxy

Together, these projects simplify the management of your Nginx configuration and SSL certificates.

Another option is to use Traefik instead of Nginx. In short, Traefik works with Let's Encrypt to issue and renew certificates. For more, check out Dockerizing Django with Postgres, Gunicorn, and Traefik.

Let's Encrypt

When the app is deployed for the first time, you should follow these two steps to avoid issues with certificates:

  1. Start by issuing the certificates from Let's Encrypt's staging environment
  2. Then, when all is running as expected, switch to Let's Encrypt's production environment

Why?

To protect their servers, Let's Encrypt enforces rate limitations on their production validation system:

  1. 5 validation failures per account, per hostname, per hour
  2. 50 certificates may be created per domain per week

If you make a typo in your domain name or in a DNS entry or anything similar, your request will fail, which will count against your rate limit, and you'll have to attempt to issue a new certificate.

To avoid being rate limited, during development and testing, you should use Let's Encrypt's staging environment for testing their validation system. The rate limits are much higher on the staging environment, which is better for testing. Just be aware that the issued certificates in staging are not trusted publicly, so once everything is working, you should switch over to their production environment.

Project Setup

First, clone down the contents from the GitHub project repo:

$ git clone https://github.com/testdrivenio/django-on-docker django-on-docker-letsencrypt
$ cd django-on-docker-letsencrypt

This repository contains everything that you need to deploy a Dockerized Django app minus the SSL certificates, which we'll be adding in this tutorial.

Django Configuration

First, to run the Django app behind an HTTPS proxy you'll need to add the SECURE_PROXY_SSL_HEADER setting to settings.py:

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

In this tuple, when X-Forwarded-Proto is set to https the request is secure.

Docker Compose

It's time to configure Docker Compose.

Let's add a new Docker Compose file for testing purposes called docker-compose.staging.yml:

version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.staging
    depends_on:
      - db
  db:
    image: postgres:13.0-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    env_file:
      - ./.env.staging.db
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.staging.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  postgres_data:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

Add a .env.staging.db file for the db container:

POSTGRES_USER=hello_django
POSTGRES_PASSWORD=hello_django
POSTGRES_DB=hello_django_prod

Change the values of POSTGRES_USER and POSTGRES_PASSWORD to match your user and password.

We already looked at the web and db services in the previous tutorial, so let's dive into the nginx-proxy and nginx-proxy-letsencrypt services.

Databases are critical services. Adding additional layers, such us Docker, adds unnecessary risk in production. To simplify tasks such as minor version updates, regular backups, and scaling, it's recommended to use a managed service like AWS RDS, Google Cloud SQL, or DigitalOcean's Managed Database.

Nginx Proxy Service

For this service, the nginx-proxy project is used for generating a reverse proxy configuration for the web container using virtual hosts for routing.

Be sure to review the README on the nginx-proxy repo.

Once up, the container associated with nginx-proxy automatically detects containers (in the same network) that have the VIRTUAL_HOST environment variable set and dynamically updates its virtual hosts configuration.

Go ahead and add a .env.staging file for the web container:

DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=hello_django_prod
SQL_USER=hello_django
SQL_PASSWORD=hello_django
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>

Notes:

  1. Change <YOUR_DOMAIN.COM> to your actual domain, and change the default values of SQL_USER and SQL_PASSWORD to match POSTGRES_USER and POSTGRES_PASSWORD (from .env.staging.db).
  2. As mentioned, VIRTUAL_HOST (and VIRTUAL_PORT) are needed by nginx-proxy to auto create the reverse proxy configuration.
  3. LETSENCRYPT_HOST is there so the nginx-proxy-companion can issue Let's Encrypt certificate for your domain.
  4. Since the Django app will be listening on port 8000, we also set the VIRTUAL_PORT environment variable.
  5. The /var/run/docker.sock:/tmp/docker.sock:ro volume in docker-compose.staging.yml is used to listen for newly registered/de-registered containers.

For testing/debugging purposes you may want to use a * for DJANGO_ALLOWED_HOSTS the first time you deploy to simplify things. Just don't forget to limit the allowed hosts once testing is complete.

So, requests made to the specified domain will be proxied to the container that has the domain set as the VIRTUAL_HOST environment variable.

Next, let's update the Nginx configuration in the "nginx" folder.

First, add directory called "vhost.d". Then, add a file called default inside that directory to serve static and media files:

location /static/ {
  alias /home/app/web/staticfiles/;
  add_header Access-Control-Allow-Origin *;
}

location /media/ {
  alias /home/app/web/mediafiles/;
  add_header Access-Control-Allow-Origin *;
}

Requests that match any of these patterns will be served from static or media folders. They won't be proxied to other containers. The web and nginx-proxy containers share the volumes in which the static and media files are located:

static_volume:/home/app/web/staticfiles
media_volume:/home/app/web/mediafiles

Add a custom.conf file to the "nginx" folder to hold custom proxy-wide configuration:

client_max_body_size 10M;

Update nginx/Dockerfile:

FROM jwilder/nginx-proxy:0.9
COPY vhost.d/default /etc/nginx/vhost.d/default
COPY custom.conf /etc/nginx/conf.d/custom.conf

Remove nginx.conf.

Your "nginx" directory should now look like this:

└── nginx
    ├── Dockerfile
    ├── custom.conf
    └── vhost.d
        └── default

Let's Encrypt Nginx Proxy Companion Service

While the nginx-proxy service handles routing, nginx-proxy-letsencrypt (via letsencrypt-nginx-proxy-companion) handles the creation, renewal, and use of Let's Encrypt certificates for proxied Docker containers.

To issue and renew certificates for proxied containers, the LETSENCRYPT_HOST environment variable needs to be added to each of them (which we've already done). It must also have the same value as VIRTUAL_HOST.

This container must share the following volumes with nginx-proxy:

  1. certs:/etc/nginx/certs stores certificates, private keys, and ACME account keys
  2. html:/usr/share/nginx/html writes http-01 challenge files
  3. vhost:/etc/nginx/vhost.d changes the configuration of vhosts

For more, review the official documentation.

Add a .env.staging.proxy-companion file:

DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy

Notes:

  1. DEFAULT_EMAIL is the email that Let's Encrypt will use to send you notifications about your certificates (including renewals).
  2. ACME_CA_URI is the URL used to issue certificates. Again, use staging until you're 100% sure that everything works.
  3. NGINX_PROXY_CONTAINER is the name of nginx-proxy container.

Running the Containers

Everything is ready to go for deployment.

It's time to move to your Linux instance.

Assuming you have a project directory created on your instance, like /home/myuser/django-on-docker, copy the files and folders over with SCP:

$ scp -r $(pwd)/{app,nginx,.env.staging,.env.staging.db,.env.staging.proxy-companion,docker-compose.staging.yml} user@your-ip-or-domain:/path/to/django-on-docker

Connect to your instance via SSH and move to the project directory:

$ ssh user@your-ip-or-domain
$ cd /path/to/django-on-docker

When that, you're ready to build the images and spin up the containers:

$ docker-compose -f docker-compose.staging.yml up -d --build

Once the containers are up and running, navigate to your domain in your browser. You should see something like:

HTTPS certificate not secure

This is expected. This screen is shown because the certificate was issued from a staging environment, which, again, doesn't have the same rate limits as a production environment. It's similar to a self-signed HTTPS certificate. Always use a staging environment until you're sure that everything is working as expected.

How do you know if everything works?

Click on "Advanced" and then on "Proceed". You should now see your app. Upload an image, and then make sure you can view the image at https://yourdomain.com/mediafiles/IMAGE_FILE_NAME.

Issue the Production Certificate

Now, that everything works as expected, we can switch over to Let's Encrypt's production environment.

Bring down the existing containers and exit your instance:

$ docker-compose -f docker-compose.staging.yml down -v
$ exit

Back on your local machine, update docker-compose.prod.yml:

version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.prod
    depends_on:
      - db
  db:
    image: postgres:13.0-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    env_file:
      - ./.env.prod.db
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.prod.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  postgres_data:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

The only difference here, compared to docker-compose.staging.yml, is that we used different environment files.

.env.prod:

DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=hello_django_prod
SQL_USER=hello_django
SQL_PASSWORD=hello_django
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>

.env.prod.db:

POSTGRES_USER=hello_django
POSTGRES_PASSWORD=hello_django
POSTGRES_DB=hello_django_prod

.env.prod.proxy-companion:

DEFAULT_EMAIL=youremail@yourdomain.co
NGINX_PROXY_CONTAINER=nginx-proxy

Update them appropriately.

Did you spot the difference, from the staging versions? The ACME_CA_URI environment variable is not set since the letsencrypt-nginx-proxy-companion image uses Let's Encrypt's production environment by default.

Copy the new files and folders to your instance with SCP:

$ scp $(pwd)/{.env.prod,.env.prod.db,.env.prod.proxy-companion,docker-compose.prod.yml} user@your-ip-or-domain:/path/to/django-on-docker

Like before, connect to your instance via SSH and move to the project directory:

$ ssh user@your-ip-or-domain
$ cd /path/to/django-on-docker

Build the images and spin up the containers:

$ docker-compose -f docker-compose.prod.yml up -d --build

Navigate to your domain again. You should no longer see a warning.

Congrats! You're now using a production Let's Encrypt certificate.

Want to see the certificate creation process in action, check out the logs:

$ docker-compose -f docker-compose.prod.yml logs nginx-proxy-letsencrypt

Conclusion

In conclusion, once you have Docker Compose configured to run Django, to set up HTTPS, you need to add (and configure) the nginx-proxy and nginx-proxy-letsencrypt services in your Docker Compose file. You can now add more containers by configuring the VIRTUAL_HOST (routing) and LETSENCRYPT_HOST (certificate) environment variables. As always, be sure to test with Let's Encrypt's staging environment first.

You can find the code in the django-on-docker-letsencrypt repo.

Django on Docker Series:

  1. Dockerizing Django with Postgres, Gunicorn, and Nginx
  2. Securing a Containerized Django Application with Let's Encrypt (this article!)
  3. Deploying Django to AWS with Docker and Let's Encrypt

Original article source at: https://testdriven.io/

#django #encrypt 

What is GEEK

Buddha Community

Securing A Containerized Django Application with Let's Encrypt
Ahebwe  Oscar

Ahebwe Oscar

1620177818

Django admin full Customization step by step

Welcome to my blog , hey everyone in this article you learn how to customize the Django app and view in the article you will know how to register  and unregister  models from the admin view how to add filtering how to add a custom input field, and a button that triggers an action on all objects and even how to change the look of your app and page using the Django suit package let’s get started.

Database

Custom Titles of Django Admin

Exclude in Django Admin

Fields in Django Admin

#django #create super user django #customize django admin dashboard #django admin #django admin custom field display #django admin customization #django admin full customization #django admin interface #django admin register all models #django customization

Zoom Rolls Out End-to-End Encryption After Setbacks

Video-conferencing giant Zoom is rolling out a technical preview of its end-to-end encryption (E2EE) next week.

Zoom has faced various controversies around its encryption policies over the past year, including several lawsuits alleging that the company falsely told users that it offers full encryption. Then, the platform came under fire in May when it announced that it would indeed offer E2EE — but to paid users only. The company later backtracked after backlash from privacy advocates, who argued that security measures should be available to all. Zoom will now offer the feature to free/”Basic” users.

The first phase of the E2EE rollout aims to solicit feedback when it comes to its policies. Users will be able to weigh in during the first 30 days. Of note, users will need to turn on the feature manually (see below for details).

“We’re pleased to roll out Phase 1 of 4 of our E2EE offering, which provides robust protections to help prevent the interception of decryption keys that could be used to monitor meeting content,” said Max Krohn, head of security engineering with Zoom, in a Wednesday post.

End-To-End Encryption Errors

The topic of encryption is critical for Zoom as it ramps up its security and privacy measures – particularly after various security flaws and privacy issues exposed weaknesses in the online meeting platform, as its user base spiked during the coronavirus pandemic.

Zoom previously said that it offered E2EE, but that marketing claim came into question after a March report from The Intercept said that Zoom’s platform actually uses transport layer security (TLS) encryption, providing only encryption between individual users and service providers, instead of directly between the users of a system.

While “encryption” means that in-transit messages are encrypted, true E2EE occurs when the message is encrypted at the source user’s device, stays encrypted while its routed through servers, and then is decrypted only at the destination user’s device.

On the heels of this backlash, Zoom in May acquired a small startup called Keybase, with the aim of providing more robust encryption for Zoom calls.

In the case of next week’s rollout, Zoom’s E2EE offering will use public-key cryptography, meaning that the keys for each Zoom meeting are generated by participants’ machines (as opposed to Zoom’s servers).

#cloud security #vulnerabilities #web security #coronavirus #covid-19 #e2ee #encryption #end to end encryption #pandemic #remote work #security #transport layer security encryption #video conferencing security #zoom #zoom meeting #zoom-bombing

Wilford  Pagac

Wilford Pagac

1596789120

Best Custom Web & Mobile App Development Company

Everything around us has become smart, like smart infrastructures, smart cities, autonomous vehicles, to name a few. The innovation of smart devices makes it possible to achieve these heights in science and technology. But, data is vulnerable, there is a risk of attack by cybercriminals. To get started, let’s know about IoT devices.

What are IoT devices?

The Internet Of Things(IoT) is a system that interrelates computer devices like sensors, software, and actuators, digital machines, etc. They are linked together with particular objects that work through the internet and transfer data over devices without humans interference.

Famous examples are Amazon Alexa, Apple SIRI, Interconnected baby monitors, video doorbells, and smart thermostats.

How could your IoT devices be vulnerable?

When technologies grow and evolve, risks are also on the high stakes. Ransomware attacks are on the continuous increase; securing data has become the top priority.

When you think your smart home won’t fudge a thing against cybercriminals, you should also know that they are vulnerable. When cybercriminals access our smart voice speakers like Amazon Alexa or Apple Siri, it becomes easy for them to steal your data.

Cybersecurity report 2020 says popular hacking forums expose 770 million email addresses and 21 million unique passwords, 620 million accounts have been compromised from 16 hacked websites.

The attacks are likely to increase every year. To help you secure your data of IoT devices, here are some best tips you can implement.

Tips to secure your IoT devices

1. Change Default Router Name

Your router has the default name of make and model. When we stick with the manufacturer name, attackers can quickly identify our make and model. So give the router name different from your addresses, without giving away personal information.

2. Know your connected network and connected devices

If your devices are connected to the internet, these connections are vulnerable to cyber attacks when your devices don’t have the proper security. Almost every web interface is equipped with multiple devices, so it’s hard to track the device. But, it’s crucial to stay aware of them.

3. Change default usernames and passwords

When we use the default usernames and passwords, it is attackable. Because the cybercriminals possibly know the default passwords come with IoT devices. So use strong passwords to access our IoT devices.

4. Manage strong, Unique passwords for your IoT devices and accounts

Use strong or unique passwords that are easily assumed, such as ‘123456’ or ‘password1234’ to protect your accounts. Give strong and complex passwords formed by combinations of alphabets, numeric, and not easily bypassed symbols.

Also, change passwords for multiple accounts and change them regularly to avoid attacks. We can also set several attempts to wrong passwords to set locking the account to safeguard from the hackers.

5. Do not use Public WI-FI Networks

Are you try to keep an eye on your IoT devices through your mobile devices in different locations. I recommend you not to use the public WI-FI network to access them. Because they are easily accessible through for everyone, you are still in a hurry to access, use VPN that gives them protection against cyber-attacks, giving them privacy and security features, for example, using Express VPN.

6. Establish firewalls to discover the vulnerabilities

There are software and firewalls like intrusion detection system/intrusion prevention system in the market. This will be useful to screen and analyze the wire traffic of a network. You can identify the security weakness by the firewall scanners within the network structure. Use these firewalls to get rid of unwanted security issues and vulnerabilities.

7. Reconfigure your device settings

Every smart device comes with the insecure default settings, and sometimes we are not able to change these default settings configurations. These conditions need to be assessed and need to reconfigure the default settings.

8. Authenticate the IoT applications

Nowadays, every smart app offers authentication to secure the accounts. There are many types of authentication methods like single-factor authentication, two-step authentication, and multi-factor authentication. Use any one of these to send a one time password (OTP) to verify the user who logs in the smart device to keep our accounts from falling into the wrong hands.

9. Update the device software up to date

Every smart device manufacturer releases updates to fix bugs in their software. These security patches help us to improve our protection of the device. Also, update the software on the smartphone, which we are used to monitoring the IoT devices to avoid vulnerabilities.

10. Track the smartphones and keep them safe

When we connect the smart home to the smartphone and control them via smartphone, you need to keep them safe. If you miss the phone almost, every personal information is at risk to the cybercriminals. But sometimes it happens by accident, makes sure that you can clear all the data remotely.

However, securing smart devices is essential in the world of data. There are still cybercriminals bypassing the securities. So make sure to do the safety measures to avoid our accounts falling out into the wrong hands. I hope these steps will help you all to secure your IoT devices.

If you have any, feel free to share them in the comments! I’d love to know them.

Are you looking for more? Subscribe to weekly newsletters that can help your stay updated IoT application developments.

#iot #enterprise iot security #how iot can be used to enhance security #how to improve iot security #how to protect iot devices from hackers #how to secure iot devices #iot security #iot security devices #iot security offerings #iot security technologies iot security plus #iot vulnerable devices #risk based iot security program

Ahebwe  Oscar

Ahebwe Oscar

1620185280

How model queries work in Django

How model queries work in Django

Welcome to my blog, hey everyone in this article we are going to be working with queries in Django so for any web app that you build your going to want to write a query so you can retrieve information from your database so in this article I’ll be showing you all the different ways that you can write queries and it should cover about 90% of the cases that you’ll have when you’re writing your code the other 10% depend on your specific use case you may have to get more complicated but for the most part what I cover in this article should be able to help you so let’s start with the model that I have I’ve already created it.

**Read More : **How to make Chatbot in Python.

Read More : Django Admin Full Customization step by step

let’s just get into this diagram that I made so in here:

django queries aboutDescribe each parameter in Django querset

we’re making a simple query for the myModel table so we want to pull out all the information in the database so we have this variable which is gonna hold a return value and we have our myModel models so this is simply the myModel model name so whatever you named your model just make sure you specify that and we’re gonna access the objects attribute once we get that object’s attribute we can simply use the all method and this will return all the information in the database so we’re gonna start with all and then we will go into getting single items filtering that data and go to our command prompt.

Here and we’ll actually start making our queries from here to do this let’s just go ahead and run** Python manage.py shell** and I am in my project file so make sure you’re in there when you start and what this does is it gives us an interactive shell to actually start working with our data so this is a lot like the Python shell but because we did manage.py it allows us to do things a Django way and actually query our database now open up the command prompt and let’s go ahead and start making our first queries.

#django #django model queries #django orm #django queries #django query #model django query #model query #query with django

Chet  Lubowitz

Chet Lubowitz

1592895420

Securing a Containerized Django Application with Let's Encrypt

In this tutorial, we’ll look at how to secure a containerized Django app running behind an HTTPS Nginx proxy with Let’s Encrypt SSL certificates.

This post builds on the Dockerizing Django with Postgres, Gunicorn, and Nginx post. It assumes you understand how to containerize a Django app along with Postgres, Nginx, and Gunicorn.

Nowadays you simply can’t go to production with your application running over HTTP. Without HTTPS, your site is less secure and trustworthy. With Let’s Encrypt, which simplifies the process of obtaining and installing SSL certificates, there’s simply no excuse anymore not to have HTTPS.

#let's encrypt #django application