add cfdns
This commit is contained in:
parent
ed35463a36
commit
df6a2032fa
3 changed files with 237 additions and 0 deletions
|
@ -15,3 +15,7 @@ converts one font type to another with fontforge, (just an alias posing as a bas
|
||||||
using lets encrypt, allows checking and renewal of lets encrypt certificates. usefull for cron jobs
|
using lets encrypt, allows checking and renewal of lets encrypt certificates. usefull for cron jobs
|
||||||
|
|
||||||
this uses certbot with webroot, so make sure to have DOMAIN/.well-known/acme-challenge pointed to /var/www/html/.well-known/acme-challenge on your system
|
this uses certbot with webroot, so make sure to have DOMAIN/.well-known/acme-challenge pointed to /var/www/html/.well-known/acme-challenge on your system
|
||||||
|
|
||||||
|
#### cfdns
|
||||||
|
|
||||||
|
allows creation or updating of existing cloudflare dns records
|
||||||
|
|
233
cfdns
Executable file
233
cfdns
Executable file
|
@ -0,0 +1,233 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
quiet=0 # should i shut up?!?!? :<
|
||||||
|
|
||||||
|
token="" # the api token
|
||||||
|
domain="" # the domain to update
|
||||||
|
|
||||||
|
record="A" # the record type
|
||||||
|
ttl="60" # the new time to live
|
||||||
|
content="" # the new record content
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: cfdns [-hq] [-d DOMAIN] [-t TOKEN] [-r RECORD] [-l TTL] [-cC CONTENT]\n\n"
|
||||||
|
printf "\t-h\t\tshow the help message\n"
|
||||||
|
printf "\t-q\t\tquiet output\n"
|
||||||
|
printf "\t-d DOMAIN\tthe domain name to update\n"
|
||||||
|
printf "\t-t TOKEN\tthe api token\n"
|
||||||
|
printf "\t-r RECORD\tthe new record type\n"
|
||||||
|
printf "\t-l TTL\t\tthe new time to live\n"
|
||||||
|
printf "\t-c CONTENT\tthe new contents of the record\n"
|
||||||
|
printf "\t-C RAW CONTENT\tthe new conents of the record (as raw json)\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
chk_command() {
|
||||||
|
if ! command -v "$1" > /dev/null; then
|
||||||
|
>&2 echo "error: command '$1' could not be found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
chk_command "getopts"
|
||||||
|
chk_command "curl"
|
||||||
|
chk_command "jq"
|
||||||
|
|
||||||
|
while getopts "hqd:t:r:l:c:C:" arg > /dev/null; do
|
||||||
|
case $arg in
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
q)
|
||||||
|
quiet=1
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
domain="${OPTARG}"
|
||||||
|
;;
|
||||||
|
t)
|
||||||
|
token="${OPTARG}"
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
record="${OPTARG}"
|
||||||
|
;;
|
||||||
|
l)
|
||||||
|
ttl="${OPTARG}"
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
content="\"content\": \"${OPTARG}\""
|
||||||
|
;;
|
||||||
|
C)
|
||||||
|
content="${OPTARG}"
|
||||||
|
;;
|
||||||
|
?)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! "$cert" = "cert.pem" ] && [ "$key" = "cert.key" ]; then
|
||||||
|
name=${cert%.*}
|
||||||
|
key="$name.key"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log() {
|
||||||
|
if [ $quiet = 0 ]; then
|
||||||
|
printf "$*\n" 1>&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
if [ $quiet = 0 ]; then
|
||||||
|
printf "\033[32m>>> \033[0m$*\n" 1>&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
printf "\033[31merror: \033[0m$*\n" > /dev/stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
kill $$
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_error() {
|
||||||
|
errs="$1"
|
||||||
|
count="$(echo $errs | jq -r ". | length")"
|
||||||
|
for i in $(seq 0 $(($count - 1))); do
|
||||||
|
err="$(echo $errs | jq -r ".[$i]")"
|
||||||
|
error "$(echo $err | jq -r '.message')"
|
||||||
|
chain="$(echo $err | jq -r '.error_chain')"
|
||||||
|
if ! [ "$chain" = "null" ]; then
|
||||||
|
count="$(echo $chain | jq -r ". | length")"
|
||||||
|
for j in $(seq 0 $(($count - 1))); do
|
||||||
|
error "$(echo $chain | jq -r ".[$j].message")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_curl() {
|
||||||
|
RESPONSE=$(curl --silent --request $1 \
|
||||||
|
--url "https://api.cloudflare.com/client/v4$2" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--header "Authorization: Bearer $token" \
|
||||||
|
--data "$3")
|
||||||
|
SUCCESS=$(echo $RESPONSE | jq -r ".success")
|
||||||
|
if [ "$SUCCESS" != "true" ]; then
|
||||||
|
errs="$(echo $RESPONSE | jq -r .errors)"
|
||||||
|
handle_error "$errs"
|
||||||
|
die
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $RESPONSE | jq ".result"
|
||||||
|
}
|
||||||
|
|
||||||
|
patch() {
|
||||||
|
_curl "PATCH" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
post() {
|
||||||
|
_curl "POST" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
get() {
|
||||||
|
_curl "GET" "$1" ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 1: get the zone the domain is in
|
||||||
|
zone=$(echo "$domain" | awk -F'.' '{print $(NF-1)"."$(NF);}' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$zone" = "" ]; then
|
||||||
|
error "invalid domain: '$domain'"
|
||||||
|
die
|
||||||
|
fi
|
||||||
|
|
||||||
|
step "fetching zones..."
|
||||||
|
zones=$(get "/zones")
|
||||||
|
zone_id="null"
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while true; do
|
||||||
|
json="$(echo "$zones" | jq ".[$i]")"
|
||||||
|
|
||||||
|
if [ "$json" == "null" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
name="$(echo "$json" | jq -r ".name")"
|
||||||
|
id="$(echo "$json" | jq -r ".id")"
|
||||||
|
|
||||||
|
log "found zone: $name ($id)"
|
||||||
|
|
||||||
|
if [ "$name" == "$zone" ]; then
|
||||||
|
zone_id="$id"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
((i=i+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$zone_id" == "null" ]; then
|
||||||
|
error "could not find zone: $zone"
|
||||||
|
die
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 2: get the current record id if it exists
|
||||||
|
step "fetching records..."
|
||||||
|
|
||||||
|
records="$(get "/zones/$zone_id/dns_records")"
|
||||||
|
current="null"
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
_record="$(echo "$records" | jq ".[$i]")"
|
||||||
|
|
||||||
|
if [ "$_record" == "null" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
name="$(echo "$_record" | jq -r ".name")"
|
||||||
|
type="$(echo "$_record" | jq -r ".type")"
|
||||||
|
_content="$(echo "$_record" | jq -r ".name")"
|
||||||
|
id="$(echo "$_record" | jq -r ".id")"
|
||||||
|
|
||||||
|
log "found record: $name $type \"$_content\" ($id)"
|
||||||
|
|
||||||
|
if [ "$name" == "$domain" ] && [ "$record" = "$type" ]; then
|
||||||
|
current="$id"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
((i=i+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Step 3: update record
|
||||||
|
step "updating record"
|
||||||
|
|
||||||
|
update() {
|
||||||
|
patch "/zones/$zone_id/dns_records/$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
post "/zones/$zone_id/dns_records" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
json="{
|
||||||
|
\"name\": \"$domain\",
|
||||||
|
\"proxied\": false,
|
||||||
|
\"type\": \"$record\",
|
||||||
|
$content
|
||||||
|
}"
|
||||||
|
|
||||||
|
log $(echo "$json" | jq -C)
|
||||||
|
|
||||||
|
if [ "$current" == "null" ]; then
|
||||||
|
log "no record found... creating new one"
|
||||||
|
create "$json"
|
||||||
|
else
|
||||||
|
log "record found... updating"
|
||||||
|
update "$current" "$json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
step "successfully updated record"
|
0
recert
Normal file → Executable file
0
recert
Normal file → Executable file
Loading…
Reference in a new issue