Acme.sh with local bind server wildcard certs

Hello all, I worked on a script today to make acme.sh validate domain control for wildcard certificates with local bind server, it might not be as pro as you might need but it does the job to add the challenges and remove them at the end of the process, it is used as a dnsapi script so for it to work your zone files must be something like this: (zone file name must be like domain.com.zone)

$TTL 604800
$ORIGIN domain.com.
@ IN SOA ns1.domain.com. carlos\.ruiz.domain.com. (
2016111414	; serial
1800	; refresh (30 mins)
900	; retry (15 mins)
604800	; expire (7 days)
1200	)	; minimum (20 mins)
@	18000	IN	A	104.199.181.223
*	18000	IN	A	104.199.181.223
@	18000	IN	NS	ns1.domain.com.
@	18000	IN	NS	ns2.domain.com.
@	18000	IN	MX	10	mail.domain.com.
@       IN      TXT     "v=spf1 include:mail.org ~all"  

here is the bash script

#!/bin/bash

ZONE_DIR="/etc/bind/zone_files"
TMP_DIR="/tmp"

function dns_bind_local_add() {
CHALLENGE=$1
DOMAIN=`echo $CHALLENGE|/bin/sed 's/_acme-challenge.//'`
KEY=$2
ZONE_FILE="$DOMAIN.zone"
if [ -f $ZONE_DIR/$ZONE_FILE ]; then
        /bin/cp -p $ZONE_DIR/$ZONE_FILE $TMP_DIR
        SERIAL=`/usr/bin/awk -v field=6 '/^@ IN SOA/ { if($2=="IN"){field++} for(i=1;i<field;i++){if(i==NF){field=field-NF;getline;i=1}} print $field}' $TMP_DIR/$ZONE_FILE`
        NEW_SERIAL=$(($SERIAL+1))
        /bin/sed -e "s/$SERIAL/$NEW_SERIAL/g" $TMP_DIR/$ZONE_FILE > $TMP_DIR/$ZONE_FILE.wrk
        /bin/echo -e "\n$CHALLENGE.\t1\tIN\tTXT\t\"$KEY\"" >> $TMP_DIR/$ZONE_FILE.wrk
        /bin/mv $TMP_DIR/$ZONE_FILE.wrk $ZONE_DIR/$ZONE_FILE
        if [ -f $TMP_DIR/$ZONE_FILE ]; then
                /bin/rm -fr $TMP_DIR/$ZONE_FILE $TMP_DIR/$ZONE_FILE.wrk
        fi
        /usr/sbin/rndc reload > /dev/null;
        exit 0
else
        echo "$1 $2 $3 $4 $5" > $TMP_DIR/$DOMAIN.domain_not_found
        exit 1
fi;
}

function dns_bind_local_rm(){
        CHALLENGE=$1
        DOMAIN=`echo $CHALLENGE|/bin/sed 's/_acme-challenge.//'`
        KEY=$2
        ZONE_FILE="$DOMAIN.zone"
        SERIAL=`/usr/bin/awk -v field=6 '/^@ IN SOA/ { if($2=="IN"){field++} for(i=1;i<field;i++){if(i==NF){field=field-NF;getline;i=1}} print $field}' $ZONE_DIR/$ZONE_FILE`
        NEW_SERIAL=$(($SERIAL+1))
        /bin/sed -e "/$KEY/, +1 d" -e "s/$SERIAL/$NEW_SERIAL/g" $ZONE_DIR/$ZONE_FILE > $TMP_DIR/$ZONE_FILE.wrk
        /bin/mv $TMP_DIR/$ZONE_FILE.wrk $ZONE_DIR/$ZONE_FILE
        if [ -f $TMP_DIR/$ZONE_FILE.wrk ]; then
                /bin/rm -fr $TMP_DIR/$ZONE_FILE.wrk
        fi
        /usr/sbin/rndc reload > /dev/null;
        exit 0;
}

make sure you change any path for used functions and actual folders to work on,

then you save this script to acme.sh/dnsapi/dns_bind_local.sh
and make it executable with chmod 700 acme.sh/dnsapi/dns_bind_local.sh

then you run acme.sh to issue a wildcard cert like this

./acme.sh/acme.sh --issue -d domain.com -d *.domain.com --dns dns_bind_local --debug

and if you want to install it something like this

./acme.sh/acme.sh --install-cert -d domain.com -d *.domain.com --key-file /etc/ssl/domain.com/domain.com.key --cert-file /etc/ssl/domain.com/domain.com.cer --fullchain-file /etc/ssl/domain.com/fullchain.cer --reloadcmd “service apache2 restart; service postfix restart; service dovecot restart;” --debug --home /acme.sh

of course change routes as needed, and disable --debug if you want a cleaner output, I use this on debian and does the job, hope it saves someone some time

cheers

1 Like

Hi,

I think you can also submit your code to acme.sh’s official repository to be added onto their codebase.

Thank you

3 Likes

Thanks a lot for your suggestion, I will do so, if it is good enough for people here, have a great day!!!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.