Effective + Simple Way to Manage & Obtain Multiple Let’s Encrypt Certificate for Different Domains Using a Small Shell Script
Yesterday I faced the problem that I need a convenient way to manage multiple domains on the same host/IP. I have “main” domains with potentially further sub-domains. How can one optimize the retrieval of certificates without writing all the shell commands manually or look ’em up in the shell history? I asked myself this question and came up with this solution, not sure if my solution is ideal but it is effective and works.
What if one wants certificates for domains sub1.example.com
, example.com
, sub1.example.org
, sub2.example.org
, and example.info
? We could obtain one big certificate using
$ sudo certbot --standalone --preferred-challenges http -d sub1.example.com, example.com, sub1.example.org,sub2.example.org,example.info
but this is not cool. We could use three individual commands for each main domain and its subdomains. But what if we want to add a sub domain in the future and want to reuse the command, without searching long for it in the history? I automatized this process.
Let there be a directory structure as seen below:
domains ├── domain_com.example ├── domain_org.example └── domain_info.example
Suppose each file with prefix “__domain
” has content that is structured as follows:
# add all sub domains here; comments are ignored # MAIN domain must be first entry # all domains that belong to this certificate example.org sub1.example.org gitlab.example.org
My shell script domains.sh
would create three certificates at /etc/letsencrypt/live/example.{com,org,info}/
out of the directory structure in this example. If you want to add more subdomains in the future, you edit the domain txt file (shown above) and rerun domains.sh
. Hence, the certificate in the lets encrypt path will be updated automatically. Note that you have to execute the script with bash
or zsh
but not sh
.
#!/bin/zsh echo "aquires let's encrypt for all domains specified in domains.txt in standalone mode" # dir with text files that contains the primary domain plus all sub domains # this way we have disjunct certificates for all sub domains and not one single BFR DOMAINS_DIR="./domains" for DOMAIN_FILE in $DOMAINS_DIR/domain_* do # construct the command/domain string for a main domain and all its sub domains # and obtains a certificate DOMAINS_CMD_STR="" while read DOMAIN; do # reading each line # ignore all comment lines AND empty lines if (echo "$DOMAIN" | grep -q --invert-match '#') && (echo "$DOMAIN" | grep .); then # main domain must come first, because this is the name where # the certificates are located in /etc/letsencrypt DOMAINS_CMD_STR="$DOMAINS_CMD_STR,$DOMAIN" fi done < $DOMAIN_FILE # remove beginning/trailing comma DOMAINS_CMD_STR=$(echo $DOMAINS_CMD_STR | sed 's/,//') # e.g. "domain1.tld,domain2.tld,...,domainN.tld" # echo "$COMMANDS_STRING" sudo certbot certonly --standalone --preferred-challenges http -d $DOMAINS_CMD_STR done
0 Comments