最後活躍 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`

dominic 已修改 2 days ago. 還原成這個修訂版本

1 file changed, 2 insertions, 1 deletion

update-ip.sh

@@ -1,5 +1,6 @@
1 - #!/bin/bash
1 + #!/bin/sh
2 2 # Created on 2025-12-07 12:22 UTC
3 + # Author: Dominic Reich (OE7DRT) <quick.hat4396@qtztsjosmprqmgtunjyf.com>
3 4 #
4 5 # Removed IPv6 as this way does not get the real IPv6 address (why?)
5 6 # 2025-12-24

dominic 已修改 2 days ago. 還原成這個修訂版本

1 file changed, 36 insertions, 32 deletions

update-ip.sh

@@ -1,6 +1,8 @@
1 - #!/bin/sh
1 + #!/bin/bash
2 2 # Created on 2025-12-07 12:22 UTC
3 - # Author: Dominic Reich (OE7DRT) <quick.hat4396@qtztsjosmprqmgtunjyf.com>
3 + #
4 + # Removed IPv6 as this way does not get the real IPv6 address (why?)
5 + # 2025-12-24
4 6
5 7 # Get my outgoing ipv4 address via ifconfig.me and compare it with the recent ip saved in ~/.my-ipv4
6 8 # Update dns with the actual ipv4 if it changed
@@ -37,7 +39,7 @@ RR_COMMENT6=""
37 39
38 40 # remote ipv4
39 41 IPREMOTE4=$(curl -4 -sgkL https://ifconfig.me/ip 2>/dev/null)
40 - IPREMOTE6=$(curl -6 -sgkL https://ifconfig.me/ip 2>/dev/null)
42 + # IPREMOTE6=$(curl -6 -sgkL https://ifconfig.me/ip 2>/dev/null)
41 43 # echo "DBG: got ip ${IPREMOTE4}"
42 44
43 45 # check if remote ips contain valid data
@@ -56,15 +58,15 @@ else
56 58 fi
57 59
58 60 #check for IP6
59 - if [ -w "${IPFILE6}" -a -f "${IPFILE6}" ]
60 - then
61 - SAVEDIP6=$(cat ${IPFILE6})
62 - # echo "DBG: saved ip is ${SAVEDIP4}"
63 - else
64 - # no existing ipv4 file, create one and add new ipv4 into it
65 - /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
66 - # echo "DBG: saved ip ${IPREMOTE4} to file ${IPFILE4}"
67 - fi
61 + # if [ -w "${IPFILE6}" -a -f "${IPFILE6}" ]
62 + # then
63 + # SAVEDIP6=$(cat ${IPFILE6})
64 + # # echo "DBG: saved ip is ${SAVEDIP4}"
65 + # else
66 + # # no existing ipv4 file, create one and add new ipv4 into it
67 + # /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
68 + # # echo "DBG: saved ip ${IPREMOTE4} to file ${IPFILE4}"
69 + # fi
68 70
69 71 # check if remote ip is identical as locally saved ip
70 72 if [ "${SAVEDIP4}x" = "${IPREMOTE4}x" ]
@@ -73,6 +75,7 @@ then
73 75 # echo "DBG: do nothing, ips are equal"
74 76 echo >&2 "IPv4 identical. Nothing to do"
75 77 else
78 + echo >&2 "Setting IPv4 address to ${IPREMOTE4}"
76 79 # ips differ, update dns ip with remote ip and save into local ip file
77 80 curl -s -g -X POST -H "Authorization: Bearer ${AUTH_TOKEN}" \
78 81 -H "Content-Type: application/json" \
@@ -89,23 +92,24 @@ then
89 92 fi
90 93
91 94 # and repeat for ipv6
92 - if [ "${SAVEDIP6}x" = "${IPREMOTE6}x" ]
93 - then
94 - # if remote ip is equal as locally saved (old) ip
95 - # echo "DBG: do nothing, ips are equal"
96 - echo >&2 "IPv6 identical. Nothing to do"
97 - else
98 - # ips differ, update dns ip with remote ip and save into local ip file
99 - curl -s -g -X POST -H "Authorization: Bearer ${AUTH_TOKEN}" \
100 - -H "Content-Type: application/json" \
101 - -d '{"records":[{"value":"'${IPREMOTE6}'","comment":"'${RR_COMMENT6}'"}]}' \
102 - "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}/actions/set_records" > /dev/null
103 - /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
104 - fi
105 -
106 - if [ "${CHECK}x" = "truex" ]
107 - then
108 - # also check for ipv6
109 - curl -s -H "Authorization: Bearer ${AUTH_TOKEN}" \
110 - "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}" | ${JQ} "[.[] | .records]"
111 - fi
95 + # if [ "${SAVEDIP6}x" = "${IPREMOTE6}x" ]
96 + # then
97 + # # if remote ip is equal as locally saved (old) ip
98 + # # echo "DBG: do nothing, ips are equal"
99 + # echo >&2 "IPv6 identical. Nothing to do"
100 + # else
101 + # echo >&2 "Setting IPv6 address to ${IPREMOTE6}"
102 + # # ips differ, update dns ip with remote ip and save into local ip file
103 + # curl -s -g -X POST -H "Authorization: Bearer ${AUTH_TOKEN}" \
104 + # -H "Content-Type: application/json" \
105 + # -d '{"records":[{"value":"'${IPREMOTE6}'","comment":"'${RR_COMMENT6}'"}]}' \
106 + # "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}/actions/set_records" > /dev/null
107 + # /bin/echo -n "${IPREMOTE6}" > ${IPFILE6}
108 + # fi
109 + #
110 + # if [ "${CHECK}x" = "truex" ]
111 + # then
112 + # # also check for ipv6
113 + # curl -s -H "Authorization: Bearer ${AUTH_TOKEN}" \
114 + # "${API_URL}${ZONE_ID}/rrsets/${RR_NAME}/${RR_TYPE6}" | ${JQ} "[.[] | .records]"
115 + # fi

dominic 已修改 2 weeks ago. 還原成這個修訂版本

1 file changed, 111 insertions

update-ip.sh(檔案已創建)

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