X-Git-Url: https://iankelling.org/git/?p=distro-setup;a=blobdiff_plain;f=dynamic-ip-update;h=3ba7f34998098fab2ec80be10fdd9b165402ec40;hp=1e7880274c3a57a6801d930a20e3a1ded1b27dc0;hb=HEAD;hpb=b18dade73dedfe69aa741f8417947d83c4208f2d diff --git a/dynamic-ip-update b/dynamic-ip-update index 1e78802..12726ae 100755 --- a/dynamic-ip-update +++ b/dynamic-ip-update @@ -1,7 +1,68 @@ #!/bin/bash -source ~/.bashrc +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to switch +# its license to GPL. +# Copyright 2024 Ian Kelling +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +set -e; . /usr/local/lib/bash-bear; set +e +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file +this_dir="${this_file%/*}" +readonly this_dir +cd "$this_dir" + +usage() { + cat <&2; exit 1; } + +force=false # default +temp=$(getopt -l help hf "$@") || usage 1 +eval set -- "$temp" +while true; do + case $1 in + -f) force=true ;; + --) shift; break ;; + *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;; + esac + shift +done + +##### end command line parsing ######## main() { @@ -13,23 +74,31 @@ main() { up4=false - if ! read -r _ _ gateway _ ifdev _ < <(ip -4 route get 85.119.83.50 2>/dev/null); then - # if our internet is down, just give up, no need to have an error - if [[ ! $INVOCATION_ID ]]; then + if ! tmp=$(ip -4 route get 85.119.83.50 2>/dev/null); then + # our internet is down + if [[ $INVOCATION_ID ]]; then + return 0 + else echo $0: failed to get route, giving up + exit 0 fi - exit 0 fi + read -r _ _ gateway _ ifdev _ <<<"$tmp" case $gateway in 10.2.0.1) - dynhost=i.b8.nz + dyndomain=b8.nz ;; *) return 0 ;; esac + # We check if we are at home by testing gateway ssh + # fingerprint. However, if we found in the past that we are, I dont + # like to spam its logs with ssh login attempts, so just check if our + # gateway interface has an increasing amount of packets sent + + # received from last time. athome=false if [[ -s /dev/shm/dynamic-ip-update-state ]]; then oldbytes=$(cat /dev/shm/dynamic-ip-update-state) @@ -46,9 +115,14 @@ main() { if $athome; then - cur4="$(dig +short $dynhost @iankelling.org | tail -1)" - if ip4=$(curl -s4 https://iankelling.org/cgi/pubip); then - if [[ $cur4 && $ip4 && $cur4 != $ip4 ]]; then + if ! cur4="$(dig +short $dyndomain @iankelling.org | tail -1)"; then + if [[ ! $INVOCATION_ID ]]; then + echo "$0: dig failed. internet looks down. giving up" + fi + return 0 + fi + if ip4=$(curl --connect-timeout 10 -s4 https://iankelling.org/cgi/pubip); then + if $force || [[ $cur4 && $ip4 && $cur4 != "$ip4" ]]; then up4=true # update ipv4 fi fi @@ -59,14 +133,14 @@ main() { up6=false - out6=$(curl -s6 https://iankelling.org/cgi/pubip) ||: # failure allowed if we have no ipv6 + out6=$(curl --connect-timeout 10 -s6 https://iankelling.org/cgi/pubip) ||: # failure allowed if we have no ipv6 if [[ $out6 ]]; then dev=$(ip -o a show to $out6 | awk '{print $2}') # we use slaac with privacy extension, so get our less private more permanent address mac=$(cat /sys/class/net/$dev/address) - IFS=: read -a f <<<$mac; set -- ${f[@]} + IFS=: read -ra f <<<$mac; set -- ${f[@]} ip6=${out6%:*:*:*:*}:$(printf %x $((0x$1 + 2)))$2:$3'ff:fe'$4:$5$6 # in case we aren't using slaac if ! ip a | grep "^ *inet6 $ip6/" &>/dev/null; then @@ -74,10 +148,16 @@ main() { fi fi - if [[ $cur6 != $ip6 ]]; then + if $force || [[ $cur6 != "$ip6" ]]; then up6=true fi + # if we failed to get our ipv6 addr, we probably have ipv6 + # connectivity problem. + if [[ ! $ip6 ]]; then + ip_arg=-4 + fi + if ! $up4 && ! $up6; then return 0 fi @@ -86,44 +166,47 @@ main() { # "${SSH_CLIENT%% *} # to update bind if needed. - f=$(mktemp) - cat >>$f <>$tmpf <>$f <>$tmpf <>$f <>$tmpf <>$f <>$tmpf <>$f <>$tmpf < nsupdate_fail_limit )); then + echo error: nsupdate is persistently failing >&2 + exit 1 + fi + rm -f $tmpf } loop-main() { @@ -133,10 +216,12 @@ loop-main() { done } - +nsupdate_fails=0 if [[ $INVOCATION_ID ]]; then + nsupdate_fail_limit=10 loop-main else + nsupdate_fail_limit=0 main fi @@ -153,7 +238,7 @@ exit 0 # f=key.b8.nz -# cat >$f <$tmpf <