-
Notifications
You must be signed in to change notification settings - Fork 5
/
pdns.sh
executable file
·129 lines (111 loc) · 3.92 KB
/
pdns.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env bash
# Author: @antoifon
#
# Example how to deploy a DNS challange using powerdns
#
set -e
set -u
set -o pipefail
umask 077
exit_on_invalid_hook() {
local hook="$1"
case $hook in
deploy_challenge)
;;
clean_challenge)
;;
deploy_cert)
;;
*) # unknown hook - ignore and exit
exit 0
;;
esac
}
exit_on_invalid_hook "$1"
mysql_base="pdns"
mysql_host="localhost"
mysql_user="root"
mysql_pass="password"
table_domains="domains"
table_records="records"
mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$mydir/pdns.sh.conf" ]; then . $mydir/pdns.sh.conf; fi
# Wait this value in seconds at max for all nameservers to be ready
# with the deployed challange or fail if they are not
dns_sync_timeout_secs=90
export pw_file="$HOME/.letsencrypt_pdns_my.cnf"
export mysql_default_opts="--defaults-file=$pw_file --host=$mysql_host --user=$mysql_user --silent"
# write the mysql password to file, do not specify it the command line(insecure)
touch $pw_file
chmod 600 $pw_file
cat >$pw_file <<EOF
[mysql]
password=$mysql_pass
EOF
domain="${2}"
token="${4}"
timestamp=$(date +%s)
IFS='.' read -a myarray_domain <<< "$domain"
# Extract TLD from domain
lastcmp=$(echo $domain | rev | cut -d "." -f2);
if [ ${#lastcmp} == 2 ]; then
root_domain=$(echo $domain | rev | cut -d "." -f1-3 | rev) # ccTLDs
root_length=2
else
root_domain=$(echo $domain | rev | cut -d "." -f1-2 | rev) # TLD
root_length=1
fi
done="no"
function mysql_exec { mysql $mysql_default_opts "${@}"; }
if [[ "$1" = "deploy_challenge" ]]; then
id="$(mysql_exec -N -e "SELECT id FROM $mysql_base.$table_domains WHERE name='$root_domain';")"
soa="$(mysql_exec -N -e "SELECT content FROM $mysql_base.$table_records WHERE domain_id='$id' AND type='SOA'")"
idSoa="$(mysql_exec -N -e "SELECT id FROM $mysql_base.$table_records WHERE domain_id='$id' AND type='SOA'")"
IFS=' ' read -r -a soArray <<< "$soa"
soArray[2]=$((soArray[2]+1))
soaNew="$( IFS=$' '; echo "${soArray[*]}" )"
mysql_exec -e "UPDATE $mysql_base.$table_records SET content='$soaNew' WHERE id='$idSoa'"
mysql_exec -e "INSERT INTO $mysql_base.$table_records (id,domain_id,name,type,content,ttl,prio,change_date) VALUES ('', '$id', '_acme-challenge.$domain','TXT','$token','5','0','$timestamp')"
domain_without_trailing_dot=${domain%.}
dots=${domain_without_trailing_dot//[^.]}
if [ "${#dots}" -gt $root_length ]; then
# certificate is for subdomain
nameservers="$(dig -t ns +short ${domain#*.})"
else
# certificate is for domain itself, dont strip of a domain part
nameservers="$(dig -t ns +short ${domain})"
fi
challenge_deployed=0
for((timeout_counter=0,failed_servers=0;$timeout_counter<$dns_sync_timeout_secs;failed_servers=0,timeout_counter++)); do
for nameserver in $nameservers;do
if ! dig @$nameserver +short -t TXT _acme-challenge.$domain | grep -- "$token" > /dev/null; then
failed_servers=1
fi
done
[ "$failed_servers" == 0 ] && { challenge_deployed=1 ; break ; }
sleep 1
printf "."
done
if [ "$challenge_deployed" == "1" ]; then
done="yes"
else
echo -e "\n\nERROR:"
echo "Challenge could not be deployed to all nameservers. Timeout of $dns_sync_timeout_secs "
echo "seconds reached. If your slave servers need more time to synchronize, increase value "
echo "of variable dns_sync_timeout_secs in file $0."
exit 1
fi
fi
if [[ "$1" = "clean_challenge" ]]; then
mysql_exec -e "DELETE FROM $mysql_base.$table_records WHERE content = '$token' AND type = 'TXT'"
done="yes"
fi
if [[ "${1}" = "deploy_cert" ]]; then
# do nothing for now
done="yes"
fi
if [[ ! "${done}" = "yes" ]]; then
echo Unkown hook "${1}"
exit 1
fi
exit 0