Raspberry Pi SSL Certificates using Let’s Encrypt

This Raspberry Pi SSL certificate project will walk you through the steps to installing and setting up the Let’s Encrypt Certbot client on the Pi.

Raspberry Pi SSL with Lets Encrypt

This Certbot client allows the user to grab an SSL certificate from Let’s Encrypt by either utilizing your web server or running a temporary server.

Let’s Encrypt is the best way to easily obtain a secure and certified SSL certificate for your Raspberry Pi completely free.

Before you get started with setting up SSL on your Raspberry Pi, make sure that you have a domain name already set up and pointed at your IP address as an IP Address cannot have a certified SSL Certificate.

If you are using Cloudflare as your DNS provider, make sure you have the DNS set to bypass Cloudflare’s proxy. The proxy hides your IP address meaning the Let’s Encrypt tool will fail to verify your Raspberry Pi’s IP address and generate an SSL certificate.

Equipment List

Below are all the bits and pieces that I used for setting up Let’s Encrypt SSL on my Raspberry Pi. You also will need an internet connection to be able to complete this tutorial.

Recommended

Optional

This tutorial on acquiring an SSL Certificate was last tested on Raspberry Pi OS Bullseye and the Raspberry Pi 3.

Installing and Running LetsEncrypt

1. Before we setup LetsEncrypt on our Raspberry Pi we should first ensure everything is up to date.

We can do this by running the following two commands.

sudo apt update
sudo apt upgrade

2. Now we can go ahead and install the actual LetsEncrypt software to our Raspberry Pi by running one of the following commands.

This piece of software is called “Cerbot”. If you are running Apache, you can install the certbot module for it otherwise install the standard version of certbot.

Apache

sudo apt install python3-certbot-apache

Everything Else

sudo apt install certbot

3. With Certbot finally installed we can proceed with grabbing an SSL certificate for our Raspberry Pi from Let’s Encrypt. There is a couple of ways of handling this.

If you are not using Apache, you can skip this step. If you are using Apache, then the easiest way of grabbing a certificate is by running the command shown below, this will automatically grab and install the certificate into Apache’s configuration.

Before you do that, you will first have to make sure port 80 and port 443 are port forwarded. Also, if you are using Cloudflare as your DNS provider, you will need to temporarily bypass it as it hides your real IP address.

sudo certbot --apache

4. If you are not running Apache, there are two different ways we can go about grabbing a certificate from Let’s Encrypt. Thanks to the certbot software, we can either grab the server using a standalone python server.

Alternatively, if you are running another web server such as NGINX, we can also utilize that to grab the certificate as well. Though you will have to set up the certificate manually once it has been grabbed.

Go to step 5a if you are not running another web server, otherwise go to step 5b.

5a. Utilizing the standalone built-in web server is incredibly easy, though first, you will have to make sure your port 80 is unblocked and forwarded. Make sure you replace example.com with the domain name you intend on utilizing.

sudo certbot certonly --standalone -d example.com -d www.example.com

5b. Using web root requires a bit more knowledge than using the built-in web server. Make sure /var/www/example points to a working website directory that can be reached from the internet. Also, make sure to replace example.com with the domain name you are using for your website.

sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com

6. After running these commands, you will be prompted to enter some details, such as your email address. These details are required for Let’s Encrypt to keep track of the certificates it provides and also allow them to contact you if any issues arrive with the certificate.

Once you have filled out the required information, it will proceed to grab the certificate from Let’s Encrypt.

If you run into any issues, make sure you have a valid domain name pointing at your IP, make sure port 80 and port 443 are not blocked. Finally, if you are using Cloudflare as your DNS provider, ensure that you have the DNS currently set to bypass the proxy servers.

The certificates that are grabbed by the certbot client will be stored in the following folder. Of course, swapping out example.com with your own domain name.

/etc/letsencrypt/live/example.com/

You will find both the full chain file (fullchain.pem) and the certificate’s private key file (privkey.pem) within these folders. Make sure you don’t allow others to access these files as they are what keep your SSL connection secure and identify it as a legitimate connection.

With the files now successfully grabbed you can proceed to set up any piece of software you need to use them. For instance, if you want to setup NGINX to utilize the SSL certificates, follow our Raspberry Pi SSL Nginx guide below.

Using your new SSL Certificate with NGINX

1. Begin by opening your NGINX configuration file. These are typically stored in /etc/nginx/ or /etc/nginx/sites-available/.

Once you have found your configuration file, open it up using your favorite text editor, mine, for instance, is nano. Once you are within the file search for a text block like what is display below.

Make sure you swap out our example.com with the domain name that you are using.

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

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name example.com;

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

2. To this block of code, we will need to make some changes. Follow our steps and read our explanations of why we are making the change below.

Find

listen [::]:80 default_server

Add Below

listen 443 ssl;

This change tells NGINX to start listening on port 443. Port 443 is important as it is the port that handles HTTPS/SSL traffic and will be the port web browsers try to connect over when using https://.

Find

server_name example.com;

Add Below

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

This change tells NGINX where to find our certificate files. It will use these to set up the SSL/HTTPS connection.

The private key secures the actual connection. Only your server can read and see this file, and this file should be kept secure otherwise, people could potentially intercept and decrypt your traffic.

The fullchain contains all the information needed to talk with the server over the HTTPS connection. It also contains the information needed to verify it is a legitimately signed SSL file.

3. With all those changes done, you should end up with something similar to what is displayed below. Of course, make sure you replaced example.com with your domain name.

Once you are satisfied that you have entered the new data correctly, you can save and quit out of the file and then restart NGINX so it loads in the new configuration.

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

        listen 443 ssl;

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name example.com;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

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

4. You should now have a fully operational HTTPS connection for your NGINX web server utilizing the certificate we generated with Let’s Encrypt.

Conclusion

You should now hopefully have a fully validated SSL certificate that is provided to you from Let’s Encrypt. You will find this tutorial pretty handy across a wide range of projects, especially the server based Raspberry Pi projects.

Hopefully, you have found this Raspberry Pi SSL tutorial helpful, if you have any issues or feedback feel free to leave a comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

14 Comments

  1. Avatar for Dominic
    Dominic on

    It works, thanks a lot!

  2. Avatar for D.
    D. on

    It will be a pretty nice follow-up tutorial on how to renew and auto-renew these certificates. Right now I’m in the renewal situation and I have no clue how to do that 🙂

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi D.,

      Typically the certbot software we use within this tutorial will automatically renew any certificate when its due.

      You can ask for a renewal now by using the following command in the terminal.

      sudo certbot renew

      Please let me know if you need additional assistance.

      Kind regards,
      Emmet

  3. Avatar for Cornel
    Cornel on

    Thank you very much! I used it for the Apache and it worked very well.
    The only correction was this: I had to add “sudo ” in front of “certbot –apache” command.

  4. Avatar for Sebastian
    Sebastian on

    Thank you so much! I’ve been struggling with finding a solution to the unsigned cert.

    I think it would help a lot of people if you added this section to the owncloud tutorial.

    Again thank you, finally i have a 100% working cloudstorage solution!

  5. Avatar for GRL
    GRL on

    Thank you . This was helpful. Is it necessary to renew often?

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi GRL,

      The certificates last 3 months from memory.

      So as long as you renew the certificates at least every 2 and a half months you should be fine.

      Cheers,
      Emmet

  6. Avatar for ed heiser
    ed heiser on

    Any way to do this when your isp blocks outgoing on port 80?

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi Ed,

      It is possible to make use of something like the Cloudflare DNS Certbot plugin instead. This works by instead writing a DNS record to the domain you are trying to get a certificate for and verifying it based off of that record.

      Cheers,
      Emmet

  7. Avatar for someone
    someone on

    Can you give an example with Apache server rather thanwith NGINX

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi,

      Using python-certbot-apache the cerbot script should actually automatically setup and configure the Apache files for use with SSL. Is that not working for you?

      Cheers,
      Emmet

  8. Avatar for Tommy
    Tommy on

    Nice write-up! I only just used certbot a few weeks ago to generate a let’s encrypt cert for my site. Now maybe I have an excuse to get the Raspberry Pi 3 back out.

  9. Avatar for ducsu
    ducsu on

    Here is my renew for cron.

    renew every Monday @ 12am:
    00 0 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log
    05 0 * * 1 /etc/init.d/nginx reload

  10. Avatar for Ivo Peters
    Ivo Peters on

    Wow… this one works perfectly! Very good job. Little minus….Missing the ‘how-to-renew’ part with Cron job.