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

Philipp Schuster

Ich bin Philipp, studiere Informatik an der TU Dresden und neben meinem Studio arbeite ich beruflich als Werkstudent und Privat an zahlreichen Projekten. Dabei nutze ich unter anderem Rust, Java, Angular, Typescript, C/C++, uvm.

Das könnte dich auch interessieren …

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.