diff options
| author | Jan Tuomi <jan@jantuomi.fi> | 2025-07-09 14:49:01 +0300 |
|---|---|---|
| committer | Jan Tuomi <jan@jantuomi.fi> | 2025-07-09 14:49:01 +0300 |
| commit | b062211887bda338f14cb663c2b3392a52d0df88 (patch) | |
| tree | 3dd9c3ae32b312c10854c05598a17313e3d6efd6 /templates | |
| parent | 64f0adc8bb8d758c07fdd89b937466b1ab5ab43e (diff) | |
Add digitalocean dyndns rc script
Diffstat (limited to 'templates')
| -rw-r--r-- | templates/etc_rc.conf.j2 | 4 | ||||
| -rw-r--r-- | templates/usr_local_bin_do_dyndns.sh.j2 | 51 | ||||
| -rw-r--r-- | templates/usr_local_etc_do_dyndns_auth.j2 | 1 | ||||
| -rw-r--r-- | templates/usr_local_etc_rc.d_do_dyndns.j2 | 53 |
4 files changed, 109 insertions, 0 deletions
diff --git a/templates/etc_rc.conf.j2 b/templates/etc_rc.conf.j2 index 26ae032..8d21ff6 100644 --- a/templates/etc_rc.conf.j2 +++ b/templates/etc_rc.conf.j2 @@ -28,3 +28,7 @@ clear_tmp_enable="YES" cleanvar_enable="YES" auditd_enable="YES" devd_enable="YES" +do_dyndns_enable="YES" +do_dyndns_domain="jan.systems" +do_dyndns_hostname="pursotin" +do_dyndns_if4="wan0" diff --git a/templates/usr_local_bin_do_dyndns.sh.j2 b/templates/usr_local_bin_do_dyndns.sh.j2 new file mode 100644 index 0000000..8579ff3 --- /dev/null +++ b/templates/usr_local_bin_do_dyndns.sh.j2 @@ -0,0 +1,51 @@ +#!/bin/sh +set -eu + +: "${DO_DYNDNS_DOMAIN:?DO_DYNDNS_DOMAIN must be set}" +: "${DO_DYNDNS_HOSTNAME:?DO_DYNDNS_HOSTNAME must be set}" +: "${DO_DYNDNS_IF4:?DO_DYNDNS_IF4 must be set}" +: "${DO_DYNDNS_INTERVAL:?DO_DYNDNS_INTERVAL must be set}" +: "${DO_DYNDNS_AUTH_FILE:?DO_DYNDNS_AUTH_FILE must be set}" + +if [ ! -r "$DO_DYNDNS_AUTH_FILE" ]; then + echo "[ERROR] Auth file '$DO_DYNDNS_AUTH_FILE' not readable" >&2 + exit 1 +fi + +DOMAIN="$DO_DYNDNS_DOMAIN" +HOSTNAME="$DO_DYNDNS_HOSTNAME" +IF4="$DO_DYNDNS_IF4" +INTERVAL="$DO_DYNDNS_INTERVAL" + +while :; do + IP4=$(ifconfig "$IF4" | awk '/inet / { print $2 }' | head -n1) + DIGITALOCEAN_TOKEN=$(awk '{$1=$1; print}' "$DO_DYNDNS_AUTH_FILE") + + echo "[INFO] Updating A record for $DOMAIN → $IP4" + + RECORD_ID=$(curl -s -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v2/domains/$DOMAIN/records?per_page=999999" | + jq -r ".domain_records[] | select(.type==\"A\" and .name==\"$HOSTNAME\") | .id") + + if [ -n "$RECORD_ID" ]; then + curl -s -X PUT \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"data\":\"$IP4\"}" \ + "https://api.digitalocean.com/v2/domains/$DOMAIN/records/$RECORD_ID" + echo "[INFO] Record $RECORD_ID updated" + else + echo "[WARN] No A record found for hostname \"$HOSTNAME\" in domain \"$DOMAIN\". Skipping." + fi + + SLEEP_SEC=$(printf "%s\n" "$INTERVAL" | awk ' + /^[0-9]+s$/ { gsub(/s$/, ""); print $0; exit } + /^[0-9]+m$/ { gsub(/m$/, ""); print $0 * 60; exit } + /^[0-9]+h$/ { gsub(/h$/, ""); print $0 * 3600; exit } + /^[0-9]+d$/ { gsub(/d$/, ""); print $0 * 86400; exit } + /^[0-9]+$/ { print $0; exit } + { print "invalid"; exit 1 } + ') + + sleep "$SLEEP_SEC" +done diff --git a/templates/usr_local_etc_do_dyndns_auth.j2 b/templates/usr_local_etc_do_dyndns_auth.j2 new file mode 100644 index 0000000..2a9cbc5 --- /dev/null +++ b/templates/usr_local_etc_do_dyndns_auth.j2 @@ -0,0 +1 @@ +{{ do_api_token }} diff --git a/templates/usr_local_etc_rc.d_do_dyndns.j2 b/templates/usr_local_etc_rc.d_do_dyndns.j2 new file mode 100644 index 0000000..0198f9d --- /dev/null +++ b/templates/usr_local_etc_rc.d_do_dyndns.j2 @@ -0,0 +1,53 @@ +#!/bin/sh +# +# PROVIDE: do_dyndns +# REQUIRE: NETWORKING +# KEYWORD: shutdown + +. /etc/rc.subr + +name="do_dyndns" +rcvar=do_dyndns_enable + +extra_commands="status" +rcvars="do_dyndns_enable do_dyndns_domain do_dyndns_hostname do_dyndns_if4 do_dyndns_interval do_dyndns_auth_file" +stop_cmd="do_dyndns_stop" + +load_rc_config $name + +: "${do_dyndns_enable:=NO}" +: "${do_dyndns_interval:=5m}" +: "${do_dyndns_hostname:=@}" +: "${do_dyndns_auth_file:=/usr/local/etc/do_dyndns_auth}" + +pidfile="/var/run/${name}.pid" +logfile="/var/log/${name}" + +command="/usr/sbin/daemon" +command_args="-cfr -P ${pidfile} -o ${logfile} /bin/sh -c ' + export PATH=\"/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin\" + export DO_DYNDNS_DOMAIN=\"${do_dyndns_domain}\" + export DO_DYNDNS_HOSTNAME=\"${do_dyndns_hostname}\" + export DO_DYNDNS_IF4=\"${do_dyndns_if4}\" + export DO_DYNDNS_INTERVAL=\"${do_dyndns_interval}\" + export DO_DYNDNS_AUTH_FILE=\"${do_dyndns_auth_file}\" + + exec /usr/local/bin/do_dyndns.sh +'" + +do_dyndns_stop() { + echo "Stopping ${name} with SIGINT..." + if [ -f "${pidfile}" ]; then + kill -INT "$(cat "${pidfile}")" + sleep 5 + if kill -0 "$(cat "${pidfile}")" 2>/dev/null; then + echo "Process didn't exit, sending SIGKILL..." + kill -KILL "$(cat "${pidfile}")" + fi + rm -f "${pidfile}" + else + echo "${name}: no pidfile found" + fi +} + +run_rc_command "$1" |
