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- 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 60If 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 followingCAArecords:example.tld. 60 IN CAA 0 issuewild "letsencrypt.org" CAA 0 iodef "mailto:[email protected]"
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/nullacme.sh --remove -d example.tld -d *.example.tldmkdir /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.keysu - zimbra
$ cd /opt/zimbra/ssl/letsencrypt/
$ /opt/zimbra/bin/zmcertmgr deploycrt comm fullchain.cer chain.pem
$ zmcontrol restartTest the certificate
su - zimbra
$ echo QUIT | openssl s_client -connect mail.example.tld:443 | openssl x509 -noout -text | lessmkdir /opt/letsencrypt
mv example.tld.{cer,key} /opt/letsencrypt
chmod 0444 /opt/letsencrypt/example.tld.cer
chmod 0400 /opt/letsencrypt/example.tld.keymv /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.keyRestart related services
systemctl restart postfix.service dovecot.service nginx.servicemv /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.pemmv /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.pemRestart related service
systemctl restart pmgproxy.serviceUse 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.serviceUse 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)
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.keynano /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.servicenano /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- An ACME Shell script: acme.sh
 - cerbot
 - Installing a Let's Encrypt SSL Certificate
 - Deploy Commercial SSL Certificate on Proxmox Mail Gateway
 - Certificate Management
 - How-To -- Lets Encrypt and PMG
 - How To Secure Apache with Let's Encrypt on Debian 10
 - Request a free cert from Let's Encrypt
 - Update: Using Free Let’s Encrypt SSL/TLS Certificates with NGINX
 - Installing Let’s Encrypt SSL Certificate with pfSense
 - Let's Encrypt on pfSense
 - How to issue Let’s Encrypt wildcard certificate with acme.sh and Cloudflare DNS
 - CAA Records
 - CAA Record Helper
 - SSL/TLS Strong Encryption: How-To
 - Apache Module mod_ssl
 - Cipherli.st Strong Ciphers for Apache, nginx and Lighttpd
 - SSL Server Test
 - SSL and TLS Deployment Best Practices
 - SSL Server Rating Guide
 - pfSense as Name Server (bind9) with Let’s Encrypt/acme DNS-NSupdate/RFC 2136
 - Creating Wildcard Certificates on pfSense with Let’s Encrypt
 - pfSense setup ACME Lets Encrypt
 - BIND update-policy option
 - Setting up BIND to get the letsencrypt wildcards to work on your system using RFC 2136