Skip to content

Instantly share code, notes, and snippets.

@attila
Last active October 3, 2021 21:57
Show Gist options
  • Save attila/af560dbec3dba2b2c2a0bea11639ba9d to your computer and use it in GitHub Desktop.
Save attila/af560dbec3dba2b2c2a0bea11639ba9d to your computer and use it in GitHub Desktop.
Roll your own dynamic DNS – check if public IPv4 address has changed, then update it in Linode DNS
# Example crontab
# PATH is extended to include locally installed pip packages, for linode-cli
# m h dom mon dow command
*/15 * * * * PATH=~/.local/bin:$PATH ~/bin/update_dns.sh 2>&1 | logger -t DYN_DNS
#!/bin/sh
# Check if public IPv4 address has changed, update it in Linode DNS
#
# This script is POSIX compliant
#
# Requirements:
# - dig
# - jq
# - linode-cli
#
# Copyright (c) 2021 Attila Beregszaszi
#
# Use and distribution licensed under the MIT license
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set -eu
# Variable Declaration - change these
DOMAIN_ID=1234
RECORD_ID=5678
# Get current IPv4 address
CURRENT_IP=$(dig +short myip.opendns.com @resolver1.opendns.com A)
# Basic sanity check on the command output
PATTERN='^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$'
set +e
MATCH=$(expr "${CURRENT_IP}" : "${PATTERN}")
set -e
if [ "${MATCH}" -eq 0 ]; then
echo "Invalid IP returned from external lookup"
exit 1
fi
# Get current value from DNS
DNS_VALUE=$(linode-cli domains records-view "${DOMAIN_ID}" "${RECORD_ID}" --json | jq -r '.[].target')
# Check if current IP is different from the one in DNS
if [ "${CURRENT_IP}" = "${DNS_VALUE}" ]; then
echo "IPv4 address has not changed, skipping"
exit 0
fi
# Update DNS
echo "IPv4 changed, updating DNS ..."
linode-cli domains records-update "${DOMAIN_ID}" "${RECORD_ID}" --type A --target "${CURRENT_IP}" 1> /dev/null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment