Browse Source

dns validation Google Cloud DNS using gcloud

pull/886/head
KshJi Jukka Inkeri 3 months ago
parent
commit
c622445087
2 changed files with 468 additions and 0 deletions
  1. +318
    -0
      dns_scripts/dns_gcloud
  2. +150
    -0
      dns_scripts/dns_gcloud.README.md

+ 318
- 0
dns_scripts/dns_gcloud View File

@ -0,0 +1,318 @@
#!/usr/bin/env bash
# dns_gcloud
# Add/Del/List TXT record using the Google Cloud DNS gcloud command
# ver 2025-09-14
# org. version:
# https://github.com/kshji/gitssl_gcloud
#
# Main reason to make was to support getssl using DNS validation with Google Cloud DNS
# You can use this script to any host setting TXT records, default is _acme-challenge
#
# dns_gloud -c command domain token
#
# get help:
# dns_gloud -? | --help
#
# dns_gloud -c add example.com "testN"
# dns_gloud -c list example.com
# dns_gloud -c del example.com "testN"
# dns_gloud -c add example.com "test1" "test2"
# dns_gloud -c list example.com
# dns_gloud -c del example.com "test1" "test2"
#
# options:
# -d 0|1 # debug on/off to the file /var/tmp/getssl/...log
# -s 10 # sleeptime after gcloud add/del process, default 10
# -h hostname # default is "_acme-challenge."
# # if like to use domain without host, set host empty string !!!
# -t ttlvalue # set ttl, default 60 = 1 min
#
#
PRG="$0"
BINDIR="${PRG%/*}"
[ "$PRG" = "$BINDIR" ] && BINDIR="." # - same dir as program
PRG="${PRG##*/}"
#######################################################################################
usage()
{
cat <<EOT
usage:$PRG -c COMMAND [ -d 0|1 ] [ -t ttlvalue ] [ -s sleep_sec_after_gcloud ] [ -h hostname ] DOMAIN TOKEN
or
$PRG --command COMMAND [ --debug 0|1 ] [ --ttl ttlvalue ] [ --sleep sleep_sec_after_gcloud ] [ --host hostname ] DOMAIN TOKEN
-d 1 # print some debug data and make debug file to the dir /var/tmp/getssl/
-t NNN # set TTL value, default 60. Have to be same in the ADD and DEL
-s NN # default 10 s, sleep seconds after gcloud process
-h hostname # hostname, default is _acme-challenge, empty string = use domain
EOT
}
#######################################################################################
err()
{
echo "$PRG err:$*"
}
#######################################################################################
dbgstr()
{
((DEBUG<1)) && return
echo "$PRG debug:$*"
}
#######################################################################################
dbg()
{
Xdomain="$1" # domain + command
Xcmd="$2"
[ "$Xdomain" = "" ] && Xdomain="default"
[ "$Xcmd" = "" ] && Xcmd="cmd"
Xdomain="${Xdomain%.}" # del last dot
tmpd="/var/tmp/getssl"
tmpf="$tmpd/$PRG.$Xdomain.$Xcmd.log"
mkdir -p "$tmpd" 2>/dev/null
chmod 1777 "$tmpd" 2>/dev/null
cnt=0
# save only last execute info
date > "$tmpf"
echo "GCLOUD_PROJECTID:$GCLOUD_PROJECTID" >> "$tmpf"
echo "GCLOUD_ZONE:$GCLOUD_ZONE" >> "$tmpf"
echo "GCLOUD_ACCOUNT:$GCLOUD_ACCOUNT" >> "$tmpf"
echo "GCLOUD_KEYFILE:$GCLOUD_KEYFILE" >> "$tmpf"
env >> "$tmpf"
for var in $all
do
((cnt++))
echo "$cnt:<$var>" >> "$tmpf"
done
}
#######################################################################################
check_end_dot()
{
# gcloud need fulldomain ending dot = absolut domain path
# set the last dot if missing
Xorg="$1"
Xnodot="${Xorg%.}" # remove last dot if there is
echo "$Xnodot." # add dot allways
}
#######################################################################################
list_txt()
{
Xname="$1"
list=$(gcloud dns record-sets list --zone="$GCLOUD_ZONE" --name="$Xname" --type="TXT" )
stat=$?
(( stat > 0 )) && err "gcloud error to list TXT record" && exit 2
variables=variables
oifs="$IFS"
cnt=0
echo "$list" | while read $variables
do
(( cnt++ ))
(( cnt == 1 )) && continue
#read name type ttl data <<<$line
echo "name:$NAME type:$TYPE ttl:$TTL data:$DATA"
IFS="," values=($DATA)
IFS="$oifs"
numOfvalues=${#values[@]}
for (( var=0; var<numOfvalues ; var++ ))
do
echo " - data($var):${values[$var]}"
done
done
sleep 1
exit 0
}
#######################################################################################
del_txt()
{
Xname="$1"
shift
#
Xtoken=""
while [ $# -gt 0 ]
do
Xtoken="$Xtoken \"$1\""
shift
done
dbgstr "<$Xtoken>"
#exit
# start transaction
gcloud dns record-sets transaction start --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
stat=$?
(( stat > 0 )) && err "gcloud start transaction error" && exit 2
# del TXT
dbgstr gcloud dns record-sets transaction remove --name="$Xname" --ttl=$ttl --type="TXT" \
--zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID" $Xtoken
gcloud dns record-sets transaction remove --name="$Xname" --ttl=$ttl --type="TXT" \
--zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID" $Xtoken
stat=$?
if (( stat > 0 )) ; then
err "gcloud remove error"
gcloud dns record-sets transaction abort --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
exit 2
fi
gcloud dns record-sets transaction execute --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
stat=$?
(( stat > 0 )) && err "gcloud transaction execute error" && exit 2
# if not sleep, get error ???
sleep $sleepafter
exit 0
}
#######################################################################################
add_txt()
{
Xname="$1"
shift
# could be 1-n values
Xtoken=""
while [ $# -gt 0 ]
do
Xtoken="$Xtoken \"$1\""
shift
done
dbgstr "<$Xtoken>"
# start transaction
gcloud dns record-sets transaction start --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
stat=$?
if (( stat > 0 )) ; then
err "gcloud start transaction error"
gcloud dns record-sets transaction abort --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
exit 2
fi
# add TXT
dbgstr gcloud dns record-sets transaction add --name="$Xname" --ttl=$ttl --type="TXT" \
--zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID" $Xtoken
gcloud dns record-sets transaction add --name="$Xname" --ttl=$ttl --type="TXT" \
--zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID" $Xtoken
stat=$?
if (( stat > 0 )) ; then
err "gcloud add error"
gcloud dns record-sets transaction abort --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
exit 2
fi
gcloud dns record-sets transaction execute --zone="$GCLOUD_ZONE" --project="$GCLOUD_PROJECTID"
stat=$?
#echo "execute stat:$stat"
(( stat > 0 )) && err "gcloud transaction execute error" && exit 2
# if not sleep, get error ???
sleep $sleepafter
exit 0
}
#######################################################################################
# MAIN
#######################################################################################
DEBUG=0
command=""
sleepafter=10
# default host to manipulate
host="_acme-challenge."
ttl=60
while [ $# -gt 0 ]
do
arg="$1"
case "$arg" in
-c|--command|--cmd) command="$2"; shift ;;
-d|--debug) DEBUG="$2" ; shift ;;
-s|--sleep) sleepafter="$2"; shift ;;
-h|--host) host="$2"
[ $# -lt 2 ] && usage && exit 2
host="$2"
shift
;;
-t|--ttl) ttl="$2"; shift ;;
-?|--help) usage; exit 2 ;;
-*|--*) # unknown option
err "unknown option $arg"
usage
exit 2
;;
*) # arguments, stop the option parser
break
;;
esac
shift
done
[ "$GCLOUD_PROJECTID" = "" ] && err "GCLOUD_PROJECTID is not set. Unable to set TXT records." && exit 2
[ "$GCLOUD_ZONE" = "" ] && err "GCLOUD_ZONE is not set. Unable to set TXT records." && exit 2
[ "$GCLOUD_ACCOUNT" = "" ] && err "GCLOUD_ACCOUNT is not set. Unable to set TXT records." && exit 2
[ "$GCLOUD_KEYFILE" = "" ] && err "GCLOUD_KEYFILE is not set. Unable to set TXT records." && exit 2
[ ! -f "$GCLOUD_KEYFILE" ] && err "file not usable:$GCLOUD_KEYFILE" && exit 2
all="$*"
fulldomain="$1"
shift
token="$@" # could be 1-n tokens if del
case "$command" in
add) ;;
del) ;;
list) ;;
*) command="" ;;
esac
[ "$command" = "" ] && err "need option -c add | -c del | -c list" && exit 2
[ "$fulldomain" = "" ] && err "need fulldomain argument." && exit 2
[ "$token" = "" -a "$command" != "list" ] && err "need token argument." && exit 2
# dbg info to the program tmp dir
(( DEBUG>0)) && dbg "$fulldomain" "$command"
# host check ending of dot
[ "$host" != "" ] && host=$(check_end_dot "$host")
# host fullname
gname=$(check_end_dot "$host$fulldomain")
#echo "gname: $gname"
# activate google cloud account
gcloud auth activate-service-account "$GCLOUD_ACCOUNT" --key-file="$GCLOUD_KEYFILE" --project="$GCLOUD_PROJECTID"
stat=$?
(( stat > 0 )) && err "gcloud activate account error" && exit 2
case "$command" in
add) add_txt "$gname" $token
;;
del) del_txt "$gname" $token
;;
list) list_txt "$gname"
;;
*)
err "unknown command"
exit 2
;;
esac

+ 150
- 0
dns_scripts/dns_gcloud.README.md View File

@ -0,0 +1,150 @@
# getssl using Google Cloud DNS
https://github.com/kshji/getssl_gcloud
ver 2025-09-13
## You need install gcloud command
[Gcloud install](gle.com/sdk/docs/install)
If you are using *nix server without desktop (x-term), remove DISPLAY set if it's.
If you have set DISPLAY, try init process to start local chrome GUI process.
``` sh
unset DISPLAY
```
Init gcloud using, need to do once.
``` sh
gcloud init
```
Need also Google Cloud Console Service Account:
[Google Cloud Console Service Account](https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts )
* Permissions role "DNS Zone Editor"
* result is JSON keyfile
Service Account account is email, usually something like xxx@xxx.gserviceaccount.com
***Example*** using keyfile:
``` sh
gcloud auth activate-service-account xxx@xxx.gserviceaccount.com --key-file=/somepath/PROJECT_ID_xxxxx.json
```
After auth you can use gcloud dns services.
***Example***: Get zones from your Google Cloud DNS project:
``` sh
gcloud dns managed-zones list --project=PROJECT_ID
```
More gcloud dns commands: [Reference DNS](https://google.com/sdk/gcloud/reference/dns)
***Example***: List domain TXT records:
``` sh
gcloud dns record-sets list --zone=ZONEID --name="example.com." --type="TXT"
```
ZONEID is usually ex. for domain example.com it is ***examplecom***
## getssl configuration DNS validation using Google Cloud DNS
example.com/getssl.cfg
``` sh
CA="https://acme-v02.api.letsencrypt.org"
SANS="*.example.com"
#Set this to "true" to enable DNS validation
VALIDATE_VIA_DNS="true"
# Google Cloud DNS setup
# Use this command/script to add the challenge token to the DN#S entries for the domain
DNS_ADD_COMMAND="/somepath/dns_gcloud -c add "
# Use this command/script to remove the challenge token from the DNS entries for the domain
DNS_DEL_COMMAND="/somepath/dns_gcloud -c del "
# example.com setup Google Cloud DNS validation
export GCLOUD_ZONE="examplecom" # Google Cloud DNS zoneid
export GCLOUD_PROJECTID="mydnsproject" # Google Cloud projectid
# Google Cloud Service Account
export GCLOUD_ACCOUNT="someuser@mydnsproject.iam.gserviceaccount.com"
export GCLOUD_KEYFILE="/somepath/mydnsprojectSomeid.json"
```
## dns_cloud manual
* default host is _acme-challenge.
* default ttl is 60 s.
* default sleep after gcloud process is 10 s.
* default debug is 0 = off
* env variables have to setup before using `dns_gcloud`:
* GCLOUD_ZONE
* GCLOUD_PROJECTID
* GCLOUD_ACCOUNT
* GCLOUD_KEYFILE
### get help
``` sh
dns_gloud -?
dns_gloud --help
```
### Add TXT token
Add TXT token "testN"", host _acme-challenge.example.com
``` sh
dns_gloud -c add example.com "testN"
```
Add TXT token "testN"", host somehost.example.com
``` sh
dns_gloud -h somehost -c add example.com "testN"
```
### Del TXT token
Del TXT token "testN"", host _acme-challenge.example.com
``` sh
dns_gloud -c del example.com "testN"
```
Del TXT token "testN"", host somehost.example.com
``` sh
dns_gloud -h somehost -c del example.com "testN"
```
### List TXT token
List host TXT tokens, default host _acme-challenge
``` sh
dns_gloud -c list example.com
```
List domain TXT tokens, not host. Set host empty string.
``` sh
dns_gloud -h "" -c list example.com
```
### Extra options
Debug messages, option -d with argument 0 or 1.
Some debug messages to the stdout and log env settings to file to dir ***/var/tmp/getssl***
``` sh
dns_gloud -d 1 -h "" -c list example.com
```
Change default 60 second ttl value when adding. Remember,when deleting, ttl have to be same.
``` sh
dns_gloud -c add -t 300 example.com "testN"
```
Change default 10 second sleep after process
``` sh
dns_gloud -c add -s 5 example.com "testN"
```

Loading…
Cancel
Save