HTTPS on Raspberry Pi

This post is about how to set up https on a raspberry pi device, based on my recent experience

Installing certbot on Raspberry Pi

What helped me a lot is a discussion on this issue. And particularly a comment. In case the issue will be harder to find I'll leave it here:

  1. Uninstall all previous broken package/dependencies
  2. add deb testing main contrib non-free rpi to /etc/apt/sources.list
  3. apt-get update
  4. apt-get install certbot

For me the part with updating was not enough, with the installation of certbot there was a warning about incompatible packages in the system, so I upgraded and the problem was gone for good.

Generate certificates

To generate certificates with certbot

$ sudo certbot certonly -a webroot --webroot-path=/var/www/html -d -d

Now certbot will ask a lot of questions. After this, it prints to console IMPORTANT NOTES block and you can check that certs were generated by issuing this command

$ sudo ls -l /etc/letsencrypt/live/your_domain_name

For even stronger security recommended generating the Diffie-Hellman group.

This will take a reeeeeeeaaaaaaaaalllllyyyyy long time

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Configure Nginx

It is recommended to create a snippets folder in nginx folder $ mkdir /etc/nginx/snippets. Here we can place reusable parts of the code that can be included in the final configuration file. Lets call this file /etc/nginx/snippets/ssl-params.conf

# from
# and

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
# add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

# ssl_dhparam /etc/ssl/certs/dhparam.pem;

Uncomment the last line if you generated Diffie-Hellman group from the previous section.

Next, for purpose of this tutorial we'll edit the default nginx configuration file /etc/nginx/sites-available/default. But before, let's backup this file cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

This config will be in two parts - first: redirect all traffic from HTTP to HTTPS

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    return 301 https://$server_name$request_uri;

The second block is about actual SSL configuration

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;

    include snippets/ssl-params.conf;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;

Above is a complete config for a static site with index.html entry point that located in /var/www/html

Now, let's check nginx configuration file

$ sudo nginx -t

Reload Nginx config after making changes

$ sudo service nginx reload

Certificate auto-renewal

Letsenscript certifictes only last for 90 days, so it is recommended to renew certificates once in a while. A great tool for such tasks will be cron task manager that available without installation on many Unix systems by default.

To edit tasks list

$ sudo crontab -e

Add this line to file

30 2 * * * /usr/bin/certbot renew --noninteractive --renew-hook "/bin/systemctl reload nginx" >> /var/log/le-renew.log

Be careful, every user in a system have their own tasks list!

The Last

Some tips if you encounter any errors:

Great resource to check your site SSL certificate score is here - SSL Online Analyzer Tool

This article is greatly inspired by this, more in-depth publication from digitalocean Let's Enscript on Debian 8

The Last Last

This is some badass sites about HTTPS and DNS