openec2 Article Description

Debian 11 and Nginx – Part 8

Configure Let’s Encrypt with certbot Free SSL certificate(s)

Make sure you have your previous SES e-mail bucket lessons covered, particularly the lesson “AWS – SES e-mail bucket – Part 3 – SES Identity, DNS, SSL” and that you already have a paid SSL certificate, or, after configuring Nginx, we add a free Let’s Encrypt certificate.

This lesson has the toggle called “Attend to important SSL and DNS Prerequisites”: https://openec2.com/lesson/aws-ses-e-mail-bucket-part-3-ses-identity-dns-ssl/

Certbot Primary Command

We previously installed python, certbot and the pip package. I do not recommend use of snapd or the certbot “renewal” command.

/usr/bin/certbot certonly --non-interactive --agree-tos -m me@gmail.com -d mydomain.com --webroot -w /var/www/html --dry-run

This command covers the ability to add primary domains and subdomains. With nginx, we do not use www in the Let’s Encrypt certificates.

Use your own email address, domain name, and website root directory.

Go to your /etc/nginx directory, and if used on the primary domain in nginx.conf, only include the port 80 stanza. Do not include the port 443 stanza.

Comment out your 301 redirect line.

When the command works, remove the –dry-run option and run it again.

Then edit nginx.conf to put back the port 443 stanza, uncomment the 301 redirect line.

Then edit the SSL certificate paths to show:

/etc/letsencrypt/live/mydomain.com/fullchain.pem

/etc/letsencrypt/live/mydomain.com/privkey.pem

Then restart nginx – systemctl restart nginx.

You will now have https:// on your domain.

For multiple domains or subdomains, it is the same technique. However, I use an include directive.

e.g. if the second domain is shop.mydomain.com, (or some other top level domain) I would create a shop.mydomain.com.conf file.

This file will only have a port 80 stanza. The nginx.conf file already takes care of other entries.

When the certbot command has installed, you then add the port 443 stanza to shop.mydomain.com.conf.

Just before the Port 80 stanza, include your other domain .conf files. e.g.:

include /etc/nginx/shop.mydomain.com.conf;    

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

 

If renewals get crazy – e.g. you are getting certificates such as /etc/letsencrypt/live/mydomain.com-001/… the best method I know is to delete all your mydomain.com directories and files, and start the certbot install from scratch – for that domain.

You can also try the certbot command for deleting a domain. It all gets a bit messy I have to say.

Renew Certificates

We need to renew our certificates every 65 days. Going less than 65 can fail.

Here is a shell script we will run from crontab every night.

The problem with this method is that it must restart all your web services on the EC2 instance when a free certificate is installed.
If using Nginx and php-fpm (or Debian – e.g. php8.2-fpm) we must reload php-fpm after installing a free certificate.
This is not needed of course in Apache2, or httpd services.

cd /home/admin

cd /home/admin
echo "" > info.log
echo "0" > certbot.dat
chmod 777 info.log certbot.dat


vi certbot.sh

#!/bin/sh
d=`date`
c1=`head -1 /home/admin/certbot.dat`
c1=$(expr $c1 + 1)
if [ "$c1" = "65" ] ;
then
echo "0" > /home/admin/certbot.dat
echo "Certbot mydomain.com renewal" $d >> /home/admin/info.log
/usr/bin/certbot certonly --non-interactive --agree-tos -m me@gmail.com -d mydomain.com --webroot -w /var/www/html >/dev/null 2>&1
sudo /usr/bin/systemctl restart nginx >/dev/null 2>&1
sudo /usr/bin/systemctl reload php8.2-fpm >/dev/null 2>&1
sleep 2
echo "Valid dates mydomain.com:" >> /home/admin/info.log
sudo /usr/bin/openssl x509 -noout -dates -in /etc/letsencrypt/live/mydomain.com/cert.pem >> /home/admin/info.log
else
echo "Certbot mydomain.com day $c1 of 65 $d" >> /home/admin/info.log
echo $c1 > /home/admin/certbot.dat
fi

exit

[save and exit]

chmod 777 certbot.sh

If using Linux 2023, you would use /home/ec2-user instead of /home/admin.

Make sure you have your own email address and domain name in the above script.

We now add the to crontab.

crontab -e

5 0 * * * /usr/bin/systemctl reload php-fpm >/dev/null 2>&1
15 1 * * * /home/admin/certbot.sh

We already had the line to reload php-fpm once a night in a graceful way, and we run the certificate program at 1:15am each day. You can set your own values.

You can view the content of info.log as often as you wish. When the counter value in certbot.dat reached 65, it renews and will show in the info.log file, or by examining the certificate in the browser, or by running the openssl command manually from the script.

If you want multiple domains, you simply copy the same certbot.sh code as another domain.

e.g.

cd /home/admin
echo "0" > certbot_shop.dat
chmod 777 certbot_shop.dat

vi certbot.sh

[after the previous "fi" line, add:]

d=`date`
c1=`head -1 /home/admin/certbot_shop.dat`
c1=$(expr $c1 + 1)
if [ "$c1" = "65" ] ;
then
echo "0" > /home/admin/certbot_shop.dat
echo "Certbot shop.mydomain.com renewal" $d >> /home/admin/info.log
/usr/bin/certbot certonly --non-interactive --agree-tos -m me@gmail.com -d shop.mydmain.com --webroot -w /var/www/shop >/dev/null 2>&1
sudo /usr/bin/systemctl restart nginx >/dev/null 2>&1
sleep 2
echo "Valid dates shop.mydomain.com:" >> /home/admin/info.log
sudo /usr/bin/openssl x509 -noout -dates -in /etc/letsencrypt/live/shop.mydomain.com/cert.pem >> /home/admin/info.log
else
echo "Certbot shop.mydomain.com day $c1 of 65 $d" >> /home/admin/info.log
echo $c1 > /home/admin/certbot_shop.dat
fi


[The shells exit line will be below this new stanza]

[save and exit]

The above configurations are the only way I know that work each time.[/vc_wp_text][mk_padding_divider][mk_button dimension=”flat” corner_style=”rounded” url=”https://openec2.com/lesson/aws-ses-e-mail-bucket-part-3-ses-identity-dns-ssl/” target=”_blank”]Additional Notes on SSL and DNS Records[/mk_button][mk_padding_divider][mk_button dimension=”flat” corner_style=”rounded” url=”https://openec2.com/lesson/scripts-part-1-nginx-configuration-files/” target=”_blank”]Additional Nginx Configuration Files[/mk_button][mk_padding_divider][vc_wp_text]


Debian 11 Completed

This completes all the information I have on Debian 11 for use with WordPress (or some alternative purposes).
I would recommend looking at my Scripts sections, and consider adding the blacklist.sh and cidr.sh scripts to block countries, known bad IP addresses, and limit denial of service that hammers a port and leaves it open – thus freezing the site.

To update Debian, I recommend saving your WordPress database and files to an S3 bucket – see my scripts, or having a snapshot backup. Then you do “apt update” and “apt upgrade”.

Cheers :-)