constantly firing timers cause systemd to think startup never finishes
[distro-setup] / dynamic-ip-update
1 #!/bin/bash
2 source ~/.bashrc
3
4
5
6 main() {
7
8 fqdn=$(hostname -f)
9 domaintmp=${fqdn#*.}
10 hostnametmp=${fqdn%%.*}
11 # i for internet
12 fqdn=${hostnametmp}i.${domaintmp}
13
14 up4=false
15
16 if ! read -r _ _ gateway _ ifdev _ < <(ip -4 route get 85.119.83.50 2>/dev/null); then
17 # if our internet is down, just give up, no need to have an error
18 if [[ ! $INVOCATION_ID ]]; then
19 echo $0: failed to get route, giving up
20 fi
21 exit 0
22 fi
23
24 case $gateway in
25 10.2.0.1)
26 dynhost=i.b8.nz
27 ;;
28 *)
29 return 0
30 ;;
31 esac
32
33 athome=false
34 if [[ -s /dev/shm/dynamic-ip-update-state ]]; then
35 oldbytes=$(cat /dev/shm/dynamic-ip-update-state)
36 newbytes=$(awk '$1 == "'$ifdev':" {print $2 + $10}' /proc/net/dev)
37 if [[ $oldbytes == [1-9]* ]] && (( newbytes >= oldbytes )); then
38 athome=true
39 printf "%s\n" "$newbytes" >/dev/shm/dynamic-ip-update-state
40 fi
41 fi
42 if ! $athome && timeout -s 9 5 ssh-keyscan -p 2220 -t rsa $gateway 2>/dev/null | grep -qFx "[$gateway]:2220 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCH+/h1dGEfKEusBblndU2e6QT4wLCm5+yqr/sqh/0X9YfjR7BfWWm8nNmuP55cYc+Wuf5ljB1H1acXEcsl1y8e0j3agHfF0V74FE1N1zz5nn2Ep8NHnmqgEhza38ZxMPh+4p3X7zklEKU7+3SzybKBi8sg0wLzlS2LM0JaUN80zR2sK11Kye3dURUXPk78u5wodOkgcEYRwSYaDMJlUzWP+poRXIDJwFaMQnwmxbl/c84yOyaU0x/d6hFwoRscWecihX+vvBNeSyxR4xr2HDOyUWwJkctyAgt2p7w3tfkXOKcCRzTAjGVIMQLTvo0sG/yJbcyHoEFdFybCsgDvfyYn"; then
43 athome=true
44 awk '$1 == "'$ifdev':" {print $2 + $10}' /proc/net/dev > /dev/shm/dynamic-ip-update-state
45 fi
46
47
48 if $athome; then
49 cur4="$(dig +short $dynhost @iankelling.org | tail -1)"
50 if ip4=$(curl -s4 https://iankelling.org/cgi/pubip); then
51 if [[ $cur4 && $ip4 && $cur4 != $ip4 ]]; then
52 up4=true # update ipv4
53 fi
54 fi
55 fi
56
57 # may not be set yet so allow fail
58 cur6="$(host -4 -t aaaa $fqdn iankelling.org | sed -rn 's/.*has IPv6 address (.*)/\1/p;T;q')" ||:
59
60 up6=false
61
62 out6=$(curl -s6 https://iankelling.org/cgi/pubip) ||: # failure allowed if we have no ipv6
63
64 if [[ $out6 ]]; then
65 dev=$(ip -o a show to $out6 | awk '{print $2}')
66 # we use slaac with privacy extension, so get our less private more permanent address
67 mac=$(cat /sys/class/net/$dev/address)
68
69 IFS=: read -a f <<<$mac; set -- ${f[@]}
70 ip6=${out6%:*:*:*:*}:$(printf %x $((0x$1 + 2)))$2:$3'ff:fe'$4:$5$6
71 # in case we aren't using slaac
72 if ! ip a | grep "^ *inet6 $ip6/" &>/dev/null; then
73 ip6=$out6
74 fi
75 fi
76
77 if [[ $cur6 != $ip6 ]]; then
78 up6=true
79 fi
80
81 if ! $up4 && ! $up6; then
82 return 0
83 fi
84
85 # note, a simpler way to do this would be to ssh and use
86 # "${SSH_CLIENT%% *}
87 # to update bind if needed.
88
89 f=$(mktemp)
90 cat >>$f <<EOF
91 server iankelling.org
92 zone b8.nz
93 EOF
94
95 if $up4; then
96 cat >>$f <<EOF
97 update delete $dynhost. A
98 update add $dynhost. 300 A $ip4
99 EOF
100 fi
101
102 if $up6; then
103 if [[ $ip6 ]]; then
104 cat >>$f <<EOF
105 update delete $fqdn. AAAA
106 update add $fqdn. 60 AAAA $ip6
107 EOF
108 else
109 cat >>$f <<EOF
110 update delete $fqdn. AAAA
111 EOF
112 fi
113 fi
114
115 cat >>$f <<EOF
116 show
117 send
118 answer
119 quit
120 EOF
121
122 nsupdate -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$f
123 sed -i 's/^server .*/server bk.b8.nz/' $f
124 nsupdate -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$f
125
126
127 }
128
129 loop-main() {
130 while true; do
131 main
132 sleep 30
133 done
134 }
135
136
137 if [[ $INVOCATION_ID ]]; then
138 loop-main
139 else
140 main
141 fi
142
143 exit 0
144
145
146 # # # persistent initial setup for this:
147 # # # create files in /a/c/machine_specific/vps/filesystem/etc/bind
148 # # # note, conflink also does some group ownership stuff.
149 # mkc /p/c/machine_specific/vps/filesystem/etc/bind
150 # sudo dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST b8.nz
151 # user=$(id -un)
152 # sudo chown $user:$user *
153
154
155 # f=key.b8.nz
156 # cat >$f <<EOF
157 # key b8.nz. {
158 # algorithm HMAC-SHA512;
159 # secret "$(awk '$1 == "Key:" {print $2}' Kb8.nz.*.private)";
160 # };
161 # EOF
162
163 # chmod 640 [kK]*
164
165 # # push here?
166 # #myunison -ob li
167 # #ssh li conflink
168 # ssh li.b8.nz systemctl reload bind9
169
170
171 # # b8.nz has address 65.96.178.16
172 # # b8.nz has IPv6 address 2601:197:600:6efb:82fa:5bff:fe1c:6ecf