Skip to content

kurosaki1976/lets-encrypt-acme

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 

Repository files navigation

Let's Encrypt SSL wildcard certificates with acme.sh auto renewal

Author

Installation

In this tutorial the acme.sh installation and the issuing/renewing certificates' process take place on a Bind9 DNS server running GNU/Linux Debian 12 Bookworm.

  • Git clone and install
apt install git socat
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh/
./acme.sh --install \
	--home /opt/acme.sh \
	--config-home /opt/acme.sh/data \
	--cert-home /opt/acme.sh/certs \
	--accountemail "[email protected]" \
	--accountkey /opt/acme.sh/example.tld.key \
	--accountconf /opt/acme.sh/example.tld.conf

Issuing/renewing certificates automatically with nsupdate

  • Generate a key for updating the zone
cat > /etc/bind/nsupdate.key <<EOF
`tsig-keygen -a hmac-sha512 letsencrypt-key`
EOF
  • Secure the key
chmod 640 /etc/bind/nsupdate.key
chown bind.bind /etc/bind/nsupdate.key
  • Include the key in Bind9 main configuration file
nano /etc/bind/named.conf

...
include "/etc/bind/nsupdate.key";
...
  • Configure the zone to allow dynamic updates
zone "example.tld" {
    type master;
    update-policy {
        grant "letsencrypt" name _acme-challenge.example.tld. TXT;
    };
}
  • Make the DNS server and update key available to acme.sh
export NSUPDATE_SERVER="127.0.0.1"
export NSUPDATE_KEY="/etc/bind/nsupdate.key"
export NSUPDATE_ZONE="example.tld"
  • Issue a wildcard certificate
acme.sh --issue -d example.tld -d *.example.tld --days 90 --dns dns_nsupdate --dnssleep 60

If everything succeeded, it should get two TXT records temporarily added to zone example.tld, similarily to:

_acme-challenge.example.tld. 60 IN TXT "W_-Qk9a2e5xlMWEJHfbl5Sp_vw8T1oLsIaIthzDgcDs"
_acme-challenge.example.tld. 60 IN TXT "NQ9KX3PSo0T_qhIKyAYQoBq7XRng3WwfnV58YyeI9k0"

TIP: To allow Let’s Encrypt certificate authority the issuance of SSL certificates for example.tld, add the following CAA records:

example.tld. 60 IN CAA 0 issuewild "letsencrypt.org"
                   CAA 0 iodef "mailto:[email protected]"

Automate certificate renewal

crontab -e

0 0 1 */2 * "/opt/acme.sh"/acme.sh --renew -d example.tld -d *.example.tld --days 90 --dns dns_nsupdate --dnssleep 60 > /dev/null

Stop certificate renewal

acme.sh --remove -d example.tld -d *.example.tld

Deploy the Let's Encrypt SSL Certificate on services

Let's Encrypt SSL Certificate on Zimbra

mkdir /opt/zimbra/ssl/letsencrypt
mv example.tld.key fullchain.cer /opt/zimbra/ssl/letsencrypt/
cd /opt/zimbra/ssl/letsencrypt/
wget https://letsencrypt.org/certs/trustid-x3-root.pem.txt
cat fullchain.cer trustid-x3-root.pem.txt > chain.pem
chown zimbra.zimbra *
su - zimbra
$ cd /opt/zimbra/ssl/letsencrypt/
$ /opt/zimbra/bin/zmcertmgr verifycrt comm example.tld.key fullchain.cer chain.pem
cp -a /opt/zimbra/ssl/zimbra /opt/zimbra/ssl/zimbra.$(date "+%Y%m%d")
cp example.tld.key /opt/zimbra/ssl/zimbra/commercial/commercial.key
su - zimbra
$ cd /opt/zimbra/ssl/letsencrypt/
$ /opt/zimbra/bin/zmcertmgr deploycrt comm fullchain.cer chain.pem
$ zmcontrol restart

Test the certificate

su - zimbra
$ echo QUIT | openssl s_client -connect mail.example.tld:443 | openssl x509 -noout -text | less

Let's Encrypt SSL Certificate on iRedMail Server

mkdir /opt/letsencrypt
mv example.tld.{cer,key} /opt/letsencrypt
chmod 0444 /opt/letsencrypt/example.tld.cer
chmod 0400 /opt/letsencrypt/example.tld.key
mv /etc/ssl/certs/iRedMail.crt{,.bak}
mv /etc/ssl/private/iRedMail.key{,.bak}
ln -s /opt/letsencrypt/example.tld.cer /etc/ssl/certs/iRedMail.crt
ln -s /opt/letsencrypt/example.tld.key /etc/ssl/private/iRedMail.key

Restart related services

systemctl restart postfix.service dovecot.service nginx.service

Let's Encrypt SSL Certificate on Proxmox Mail Gateway

Mail certificate

mv /etc/pmg/pmg-tls.pem{,.org}
cat example.tld.key fullchain.cer > /etc/pmg/pmg-tls.pem
chmod 0600 /etc/pmg/pmg-tls.pem
chown root.root /etc/pmg/pmg-tls.pem

HTTPs certificate

mv /etc/pmg/pmg-api.pem{,.org}
cat example.tld.key fullchain.cer > /etc/pmg/pmg-api.pem
chmod 0640 /etc/pmg/pmg-api.pem
chown root.www-data /etc/pmg/pmg-api.pem

Restart related service

systemctl restart pmgproxy.service

Let's Encrypt SSL Certificate on Proxmox Vitual Environment

Use the Web GUI to deploy the files fullchain.cer and example.tld.key.

(Datacenter/"Proxmox Node"/System/Certificates/Upload Custom Certificate)

Tough the recommended method is by using the Web GUI, the command line could be used as well:

cp fullchain.cer /etc/pve/local/pveproxy-ssl.pem
cp example.tld.key /etc/pve/local/pveproxy-ssl.key
chmod 0640 /etc/pve/local/pveproxy-ssl.*
chown root.www-data /etc/pve/local/pveproxy-ssl.*

Restart related service

systemctl restart pveproxy.service

Let's Encrypt SSL Certificate on pfSense Firewall

Use the Web GUI to deploy the files fullchain.cer and example.tld.key.

(System/Certificate Manager/Certificates/"Add/Sign Button"/Method "Import an existing Certificate")

(System/Advanced/Admin Access/SSL/TLS Certificate)

Let's Encrypt SSL Certificate on Web Server

mv fullchain.cer /etc/ssl/certs/
mv example.tld.cer /etc/ssl/certs/
mv example.tld.key /etc/ssl/private/
chmod 0444 /etc/ssl/certs/{example.tld,fullchain}.cer
chmod 0400 /etc/ssl/private/example.tld.key

Apache

nano /etc/apache2/sites-available/exampleTLD.conf

...
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.tld.cer
SSLCertificateKeyFile /etc/ssl/private/example.tld.key
SSLCertificateChainFile "/etc/ssl/certs/fullchain.cer"
SSLProtocol -all +TLSv1.3 +TLSv1.2
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
SSLHonorCipherOrder on
SSLOpenSSLConfCmd Curves X25519:secp521r1:secp384r1:prime256v1
SSLOpenSSLConfCmd DHParameters "/etc/ssl/dh4096.pem"
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options SAMEORIGIN
Header always set X-Content-Type-Options nosniff
Header always set Content-Security-Policy "default-src 'self';"
Header always set X-XSS-Protection "1; mode=block"
Header always set Set-Cookie "HttpOnly;Secure"
SSLCompression off
SSLSessionTickets off
...

Test settings, if syntax returns OK, restart the web service:

apache2ctl -t
systemctl restart apache2.service

Nginx

nano /etc/nginx/sites-available/exampleTLD

...
ssl on;
ssl_certificate /etc/ssl/certs/fullchain.cer;
ssl_certificate_key /etc/ssl/private/example.tld.key;
ssl_dhparam /etc/ssl/dh4096.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self';" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Set-Cookie "HttpOnly;Secure" always;
...

Test settings, if syntax returns OK, restart the web service:

nginx -t
systemctl restart nginx.service

References