Create a Let's Encrypt SSL certificate for FusionPBX on Debian 11

Let's Encrypt

This assumes FusionPBX was installed using this FusionPBX install guide or the public install script.  This procedure should work for root domain and subdomain A records pointed at the server IP address. Some modification of this procedure may be required if you wish to use wildcard certificates.

Tested using:

* Certbot v1.1x
* FusionPBX 5
* Debian 11 (May also work with Debian 10)
* Nginx 1.1x

Install
apt install -y python3-certbot-nginx

Create verification directory if it does not already exist

mkdir -p /var/www/letsencrypt
chown -R www-data. /var/www/letsencrypt

Edit nginx to redirect the verification directory and use http port 80.  Also add the fully qualified domain name (FQDN) to server_name.  For this procedure we shall assume FQDN is subdomain.somedomain.com.

nano +49 /etc/nginx/sites-available/fusionpbx
...
...
server {
    listen 80;
    server_name subdomain.somedomain.com;

    location / {
        root /var/www/fusionpbx;
        index index.php;
    }

    #redirect letsencrypt
    location ^~ /.well-known/acme-challenge {
        default_type "text/plain";
        auth_basic "off";
        alias /var/www/letsencrypt;
    }
...
...

# approx line number 162
server {
    listen 443;
    server_name subdomain.somedomain.com;
    ssl                     on;     
    ssl_certificate         /etc/ssl/certs/nginx.crt;     
    ssl_certificate_key     /etc/ssl/private/nginx.key;
    ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers             HIGH:!ADH:!MD5:!aNULL; 
    ...
    ...

Test

Warnings are ok.

nginx -t

If test is successful.

systemctl reload nginx
Firewall

If using a firewall make sure to allow HTTP port 80 and HTTPS port 443.

Generate Certificate 
certbot --nginx -d subdomain.somedomain.com

Confirm that certbot added the certificate location to the configuration file.  If not then add it manually

nano +162 /etc/nginx/sites-available/fusionpbx
...
...
server {
    listen 443;
    server_name subdomain.somedomain.com;
    ssl                     on;
    ssl_certificate /etc/letsencrypt/live/subdomain.somedomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/subdomain.somedomain.com/privkey.pem;
    ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers             HIGH:!ADH:!MD5:!aNULL; 
    ...
    ...
}
systemctl reload nginx
Automatic Renewal

Test renewal

/usr/bin/certbot renew --dry-run

Create renewal cron

crontab -e
# In this example, the command is run at 1:02 am on Sundays.
2 1 * * 0 /usr/bin/certbot renew

Certificate renewal will only succeed once the current Let's Encrypt certificate is over 60 days old. 

Sections: