Let’s Encrypt + Plesk
Let’s encrypt issues SSL-Certificates for free – meanwhile most Systems trust their CA. Let’s Encrypt features a CLI to request, update and install certificates – which work’s nicely as long as your server’s setup is compatible. A Plesk based setup, however, is not.
Luckily, Plesk features it’s own CLI – so let’s make a short script to renew and update certificates. Here’s the script, I’ll explain later. It requires Let’s Encrypt’s “certbot” to be installed in $HOME.
#!/bin/sh IP="your.ip.v4.address" IP6="your:ip:v6:address" #Domains, format: domain.tld sub1.domain.tld sub2.domain.tld" Domains=("domain.tld sub1.domain.tld sub2.domain.tld" "domain2.tld2") #"Main" domain - the name of the certificate that will be associated to the IPs above... MainDomain="domain.tld" echo "Certificates will be renewed and installed in Plesk:" for dom in "${Domains[@]}"; do echo " $dom" done if [ -n "$1" ]; then echo "Renew will be issued for all, however only domain $1 will be updated in Plesk!" fi echo; echo " IPv4: $IP" echo " IPv6: $IP6" #"MonthName" should be something that is unique between subsequent calles of the script # date +%B should give the name of the current month, for more frequent calls use e.g. # date +%Y-%M-%d_%H-%m-%S MonthName="$(date +%Y-%m-%d_%H-%M-%S)" echo " Unique part for each certificate's name: $MonthName" echo; read -p "This might brake your setup. Type YES to continue: " Keypress if [ "$Keypress" != "YES" ]; then echo "I asked for \"YES\", you gave me \"$Keypress\". Exiting..." exit 1 fi echo; read -p "Call letsencrypt-auto ? [y/N] " Keypress if [ "$Keypress" = "y" ]; then ~/certbot/letsencrypt-auto renew echo; echo "Done." fi echo; function installcert { Certname="LetsEncrypt-Auto_($MonthName)_$1" echo; echo "Installing certifikate \"$Certname\" to domain repository..." key_file="/etc/letsencrypt/live/$1/privkey.pem" cert_file="/etc/letsencrypt/live/$1/cert.pem" cacert_file="/etc/letsencrypt/live/$1/fullchain.pem" /opt/psa/bin/certificate -c $Certname -domain $1 -key-file $key_file -cert-file $cert_file -cacert-file $cacert_file } function installcert_admin { Certname="LetsEncrypt-Auto_($MonthName)_admin_$1" echo; echo "Installing certifikate \"$Certname\" to admin's repository..." key_file="/etc/letsencrypt/live/$1/privkey.pem" cert_file="/etc/letsencrypt/live/$1/cert.pem" cacert_file="/etc/letsencrypt/live/$1/fullchain.pem" /opt/psa/bin/certificate -c $Certname -admin -key-file $key_file -cert-file $cert_file -cacert-file $cacert_file } function assigncert { Certname="LetsEncrypt-Auto_($MonthName)_$1" /opt/psa/bin/subscription -u $2 -certificate-name $Certname } read -p "Install certificates in Plesk? [y/N] " Keypress if [ "$Keypress" = "y" ]; then for domain in "${Domains[@]}"; do #Split into another array subs=($domain) main="${subs[0]}" echo "Working on domain $main..." #Domain $domain will only been updated if either no arguments are given, or the one and only argument matches $domain if ( [ "$1" == "$main" ] ) || ( [ -z "$1" ] ); then installcert "$main" #Then assign all certificates for sub in "${subs[@]}"; do assigncert "$main" "$sub" done else echo "==> Skipped." fi done echo; echo "Done." echo; fi read -p "Install & Assign SSL-Certificate of $MainDomain for IPs (Admin's repository)? [y/N] " Keypress if [ "$Keypress" = "y" ]; then installcert_admin "$MainDomain" /opt/psa/bin/certificate -ac "LetsEncrypt-Auto_($MonthName)_admin_$MainDomain" -admin -ip $IP /opt/psa/bin/certificate -ac "LetsEncrypt-Auto_($MonthName)_admin_$MainDomain" -admin -ip $IP6 fi function mailcert { Uhr="$(date +%Y-%m-%d_%H-%M-%S)" key_file="/etc/letsencrypt/live/$1/privkey.pem" cert_file="/etc/letsencrypt/live/$1/cert.pem" cacert_file="/etc/letsencrypt/live/$1/fullchain.pem" tar -chjf Cert-Backup-$Uhr.tar.bz2 /etc/postfix/postfix_default.pem /usr/share/imapd.pem /usr/share/pop3d.pem #Concat certificate for eMail... cat $key_file >/tmp/newcert.pem cat $cert_file >>/tmp/newcert.pem cat $cacert_file >>/tmp/newcert.pem cp /tmp/newcert.pem /etc/postfix/postfix_default.pem cp /tmp/newcert.pem /usr/share/imapd.pem cp /tmp/newcert.pem /usr/share/pop3d.pem chmod 400 /usr/share/imapd.pem chmod 400 /usr/share/pop3d.pem chmod 600 /etc/postfix/postfix_default.pem rm /tmp/newcert.pem /usr/local/psa/admin/sbin/mailmng --restart-service } read -p "Install certificate of $MainDomain to Postfix/IMAP/POP ? [y/N] " if [ "$Keypress" = "y" ]; then mailcert "$MainDomain" fi
The script has a short configuration section at the top, most notably the domains you want to work on. They are give in a string array, containing the domain name given first when registering a certificate with LetsEncrypt as the first token, and all sub domains you want to secure with the same certificate separated with spaces. More precisely: Let’s encrypt stores your certificates into /etc/letsencrypt/live/<domain>, the first token is used to generate this path. I recommend using your domain without any subdomain for this purpose, i.e. “domain.tld sub.domain.tld sub2.domain.tld”. To achieve this, when calling lestencrypt-auto, give this domain as the first one, i.e.
./letsencrypt-auto certonly --webroot -w /var/www/httpdocs -d domain.tld -d sub.domain.tld
This, of course, requires your domains to be set up in Plesk the same way, i.e. in Plesk, domains with the names “domain.tld”, “sub.domain.tld” and “sub2.domain.tld” must exist. The Plesk-CLI commands used to register and setup are:
- /opt/psa/bin/certificate -c <certname> -domain <domaine> -key-file <key_file> -cert-file <cert_file> -cacert-file <cacert_file>
- /opt/psa/bin/subscription -u <domain> -certificate-name <certname>
If you want your IP-Adresses given a default certificate, you should set both IP-Adress variables AND the “main domain” setting. The script will look for a certificate issued for this domain, register it in the admin’s repositiry and the assign it to both addresses. The respective commands issued are:
- /opt/psa/bin/certificate -c <certname> -admin -key-file <key_file> -cert-file <cert_file> -cacert-file <cacert_file>
- /opt/psa/bin/certificate -ac <certname> -admin -ip <IP>
If you want your email communication to be secured with your Lets Encrypt certificates, you have to request a certificate for your “main domain” that includes your MX subdomain. For example, if “main domain” is set to “example.com” and MX for this domain is “mail.example.com”, your certificate must include this subdomain. Securing a Plesk-based system’s email with your own SSL-Certificates has been described by Jay Versluis on wpguru.co.uk, and I simply scripted his approach.