1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#!/bin/sh
# Work with DigitalOcean api to update "A" and "AAAA" records for a domain.
# Store DigitalOcean API token in file : DIGITALOCEAN_TOKEN
# Store domain to be updated in file : DIGITALOCEAN_DOMAIN
ip_version="$1"
if [ -z "${ip_version:-}" ] || ([ "$ip_version" != 4 ] && [ "$ip_version" != 6 ]); then
echo "Error: no valid IP version provided" >&2
echo "Usage: dyndns.bash <4|6> [domain]" >&2
exit 1
fi
SCRIPT="$0"
SCRIPT_DIR=$(cd "${SCRIPT%/*}" && pwd )
SCRIPT_NAME=${SCRIPT##*/}
CACHE_DIR=${CACHE_DIR:-~/.cache/dyndns}
CONFIG_DIR=${CONFIG_DIR:-~/.config/dyndns}
mkdir -p ${CACHE_DIR}
mkdir -p ${CONFIG_DIR}
IP="$($SCRIPT_DIR/get_ip_addr.sh $ip_version)"
if [ -z "$IP" ]; then
echo "Error: could not find IP address" >&2
exit 1
fi
DIGITALOCEAN_TOKEN=`cat ${CONFIG_DIR}/DIGITALOCEAN_TOKEN`
DOMAIN=${2:-`cat ${CONFIG_DIR}/DIGITALOCEAN_DOMAIN`}
SUBDOMAIN=`echo $DOMAIN | sed "s/[^.]\+\.[^.]\+$//g"`
if [ -z "$SUBDOMAIN" ]; then
SUBDOMAIN="@"
ROOT_DOMAIN=$DOMAIN
elif [ "$SUBDOMAIN" = "@." ]; then
SUBDOMAIN="@"
ROOT_DOMAIN=`echo $DOMAIN | sed "s/^@.//"`
else
SUBDOMAIN=`echo $SUBDOMAIN | sed "s/\.$//g"`
ROOT_DOMAIN=`echo $DOMAIN | sed "s/^${SUBDOMAIN}\.//g"`
fi
REPEAT_CHECK_DIR=${CACHE_DIR}
REPEAT_CHECK_A=$REPEAT_CHECK_DIR/REPEAT_CHECK_${SUBDOMAIN}.${ROOT_DOMAIN}_A
REPEAT_CHECK_AAAA=$REPEAT_CHECK_DIR/REPEAT_CHECK_${SUBDOMAIN}.${ROOT_DOMAIN}_AAAA
REPEAT_CHECK="$([ $ip_version = 4 ] && echo $REPEAT_CHECK_A || echo $REPEAT_CHECK_AAAA)"
get_a_record_ids() {
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
"https://api.digitalocean.com/v2/domains/$ROOT_DOMAIN/records" 2> /dev/null | jq '.domain_records | map(select(.type == "A" and .name == "$SUBDOMAIN")) | map(.id) | .[]'
}
get_aaaa_record_ids() {
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
"https://api.digitalocean.com/v2/domains/$ROOT_DOMAIN/records" 2> /dev/null | jq '.domain_records | map(select(.type == "AAAA" and .name == "$SUBDOMAIN")) | map(.id) | .[]'
}
add_a_record() {
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-d "{\"type\":\"A\" \
,\"name\":\"$SUBDOMAIN\" \
,\"data\":\"$IP\" \
,\"priority\":null \
,\"port\":null \
,\"ttl\":1800 \
,\"weight\":null \
,\"flags\":null \
,\"tag\":null \
}" \
"https://api.digitalocean.com/v2/domains/$ROOT_DOMAIN/records" 2> /dev/null | jq '.domain_record.id'
}
add_aaaa_record() {
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-d "{\"type\":\"AAAA\" \
,\"name\":\"$SUBDOMAIN\" \
,\"data\":\"$IP\" \
,\"priority\":null \
,\"port\":null \
,\"ttl\":1800 \
,\"weight\":null \
,\"flags\":null \
,\"tag\":null \
}" \
"https://api.digitalocean.com/v2/domains/$ROOT_DOMAIN/records" 2> /dev/null | jq '.domain_record.id'
}
delete_record_by_id() {
echo deleting existing A/AAAA record for ${SUBDOMAIN}.${ROOT_DOMAIN}
curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
"https://api.digitalocean.com/v2/domains/$ROOT_DOMAIN/records/$1" > /dev/null 2>&1
}
replace_a_records() {
for id in `get_a_record_ids`; do
delete_record_by_id $id
done
new_record_id=`add_a_record`
if [ "$new_record_id" = "null" ] ; then
echo unable to add new A record for ${SUBDOMAIN}.${ROOT_DOMAIN} with value: $IP
return 1
fi
echo added new A record for ${SUBDOMAIN}.${ROOT_DOMAIN} with value: $IP
}
replace_aaaa_records() {
for id in `get_aaaa_record_ids`; do
delete_record_by_id $id
done
new_record_id=`add_aaaa_record`
if [ "$new_record_id" = "null" ] ; then
echo unable to add new AAAA record for ${SUBDOMAIN}.${ROOT_DOMAIN} with value: $IP
return 1
fi
echo added new AAAA record for ${SUBDOMAIN}.${ROOT_DOMAIN} with value: $IP
}
replace_records() {
[ $ip_version = 4 ] && replace_a_records || replace_aaaa_records
}
# exit if previous successful call was with same argument
if [ -e $REPEAT_CHECK ]; then
PREVIOUS_IP=`cat $REPEAT_CHECK`
if [ "$IP" = "$PREVIOUS_IP" ]; then
echo previous update was also with argument: \"$IP\" so exiting now to avoid duplicate work.
exit
fi
fi
# attempt to replace records and, if successful, save arguments to check against next time
if replace_records $IP; then
# if successful then save arguments.
echo update worked so saving arguments \"$IP\" in $REPEAT_CHECK
mkdir -p $REPEAT_CHECK_DIR
echo "$IP" > $REPEAT_CHECK
fi
|