Ostatnio aktywny 2 days ago

Lookup current IPv4 and IPv6 addresses and updates them on Hetzner DNS if they changed. Saves current IP addresses in `$HOME/.my-ipv4` and `$HOME/.my-ipv6`

update-ip.sh Surowy
1#!/bin/sh
2# Created on 2025-12-07 12:22 UTC
3# Author: Dominic Reich (OE7DRT) <quick.hat4396@qtztsjosmprqmgtunjyf.com>
4#
5# Removed IPv6 as this way does not get the real IPv6 address (why?)
6# 2025-12-24
7
8# Get my outgoing ipv4 address via ifconfig.me and compare it with the recent ip saved in ~/.my-ipv4
9# Update dns with the actual ipv4 if it changed
10
11# set default value for CHECK
12# override this when starting the script like `CHECK=true update-ip.sh`
13: "${CHECK:=false}"
14
15if [ "${CHECK}x" = "truex" ]
16then
17 # currently abort if jq is not installed
18 # might enter another routine to still display the record at the end
19 command -v jq > /dev/null 2>&1 || { echo >&2 "jq not found"; exit 1; }
20
21 # jq may be placed somewhere in /usr/local so first get the real path
22 JQ=$(command -v jq)
23fi
24
25# specify file names
26IPFILE4="${HOME}/.my-ipv4"
27IPFILE6="${HOME}/.my-ipv6"
28
29# Auth token (Hetzner new dns console as of Dec 2025)
30API_URL="https://api.hetzner.cloud/v1/zones/"
31AUTH_TOKEN=""
32
33# Domain settings (zone id, rrset name, rrset type)
34ZONE_ID="domain.local"
35RR_NAME="@"
36RR_TYPE4="A"
37RR_TYPE6="AAAA"
38RR_COMMENT4=""
39RR_COMMENT6=""
40
41# remote ipv4
42IPREMOTE4=$(curl -4 -sgkL https://ifconfig.me/ip 2>/dev/null)
43# IPREMOTE6=$(curl -6 -sgkL https://ifconfig.me/ip 2>/dev/null)
44# echo "DBG: got ip ${IPREMOTE4}"
45
46# check if remote ips contain valid data
47# TODO:
48# get info about useful regex on ipv4 and ipv6 addresses
49
50# check if old IP4 is saved in file
51if [ -w "${IPFILE4}" -a -f "${IPFILE4}" ]
52then
53 SAVEDIP4=$(cat ${IPFILE4})
54 # echo "DBG: saved ip is ${SAVEDIP4}"
55else
56 # no existing ipv4 file, create one and add new ipv4 into it
57 /bin/echo -n "${IPREMOTE4}" > ${IPFILE4}
58 # echo "DBG: saved ip ${IPREMOTE4} to file ${IPFILE4}"
59fi
60
61#check for IP6
62# if [ -w "${IPFILE6}" -a -f "${IPFILE6}" ]
63# then
64# SAVEDIP6=$(cat ${IPFILE6})
65# # echo "DBG: saved ip is ${SAVEDIP4}"
66# else
67# # no existing ipv4 file, create one and add new ipv4 into it
68# /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
69# # echo "DBG: saved ip ${IPREMOTE4} to file ${IPFILE4}"
70# fi
71
72# check if remote ip is identical as locally saved ip
73if [ "${SAVEDIP4}x" = "${IPREMOTE4}x" ]
74then
75 # if remote ip is equal as locally saved (old) ip
76 # echo "DBG: do nothing, ips are equal"
77 echo >&2 "IPv4 identical. Nothing to do"
78else
79 echo >&2 "Setting IPv4 address to ${IPREMOTE4}"
80 # ips differ, update dns ip with remote ip and save into local ip file
81 curl -s -g -X POST -H "Authorization: Bearer ${AUTH_TOKEN}" \
82 -H "Content-Type: application/json" \
83 -d '{"records":[{"value":"'${IPREMOTE4}'","comment":"'${RR_COMMENT4}'"}]}' \
84 "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE4}/actions/set_records" > /dev/null
85 /bin/echo -n "${IPREMOTE4}" > ${IPFILE4}
86fi
87
88if [ "${CHECK}x" = "truex" ]
89then
90 # finally check (output actual json record saved on dns server) remote ip
91 curl -s -H "Authorization: Bearer ${AUTH_TOKEN}" \
92 "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE4}" | ${JQ} "[.[] | .records]"
93fi
94
95# and repeat for ipv6
96# if [ "${SAVEDIP6}x" = "${IPREMOTE6}x" ]
97# then
98# # if remote ip is equal as locally saved (old) ip
99# # echo "DBG: do nothing, ips are equal"
100# echo >&2 "IPv6 identical. Nothing to do"
101# else
102# echo >&2 "Setting IPv6 address to ${IPREMOTE6}"
103# # ips differ, update dns ip with remote ip and save into local ip file
104# curl -s -g -X POST -H "Authorization: Bearer ${AUTH_TOKEN}" \
105# -H "Content-Type: application/json" \
106# -d '{"records":[{"value":"'${IPREMOTE6}'","comment":"'${RR_COMMENT6}'"}]}' \
107# "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}/actions/set_records" > /dev/null
108# /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
109# fi
110#
111# if [ "${CHECK}x" = "truex" ]
112# then
113# # also check for ipv6
114# curl -s -H "Authorization: Bearer ${AUTH_TOKEN}" \
115# "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}" | ${JQ} "[.[] | .records]"
116# fi
117