| 1 | #!/bin/sh -
|
---|
| 2 | #
|
---|
| 3 | # Shuffle nameservers listed based on the query times, if enabled in
|
---|
| 4 | # resolv.conf. Bare in mind the special syntax.
|
---|
| 5 | #
|
---|
| 6 | # Rick van der Zwet <rick@wirelessleiden.nl>
|
---|
| 7 | #
|
---|
| 8 |
|
---|
| 9 | # ``Random'' sleep to avoid ``slamming'' on the DNS door
|
---|
| 10 | verbose=true
|
---|
| 11 | if [ "$1" = "cron" ]; then
|
---|
| 12 | verbose=false
|
---|
| 13 | sleep `expr $$ % 30`
|
---|
| 14 | fi
|
---|
| 15 |
|
---|
| 16 | TAG='^# START DYNAMIC LIST - updated by /tools/nameserver-shuffle$'
|
---|
| 17 | $verbose && echo "# Searching in /etc/resolv.conf for tag '$TAG'"
|
---|
| 18 |
|
---|
| 19 | TDIR=`mktemp -d -t $(basename $0)`
|
---|
| 20 | # Cleanup before going home
|
---|
| 21 | trap "rm -Rf $TDIR; exit 1" 1 2 3 15
|
---|
| 22 | trap "rm -Rf $TDIR; exit 0" 0
|
---|
| 23 |
|
---|
| 24 | DYNLIST=$TDIR/dynlist
|
---|
| 25 | RESULTLIST=$TDIR/resultlist
|
---|
| 26 | NEWRESOLV=$TDIR/resolv.conf.new
|
---|
| 27 |
|
---|
| 28 | # Get enabled DYNAMIC LIST nameservers
|
---|
| 29 | sed "1,\+$TAG+d" /etc/resolv.conf > $DYNLIST || exit 1
|
---|
| 30 | NAMESERVERS=`awk '/^nameserver/ {print $2}' $DYNLIST | sort -u` || exit 1
|
---|
| 31 |
|
---|
| 32 | # Only do something if we have dynamic nameservers
|
---|
| 33 | $verbose && echo "# Processing" `echo $NAMESERVERS | wc -w` nameservers
|
---|
| 34 | if [ -n "$NAMESERVERS" ]; then
|
---|
| 35 | # Find query times
|
---|
| 36 | for NAMESERVER in $NAMESERVERS; do
|
---|
| 37 | $verbose && printf "## Testing nameserver %-16s query time: " $NAMESERVER
|
---|
| 38 | # Strict checking to avoid buggy links to return decent results.
|
---|
| 39 | QUERY_TIME=`drill SOA wleiden.net @$NAMESERVER 2>/dev/null | awk '/Query time:/ {print $4}'`
|
---|
| 40 | # Failed to complete succesfully
|
---|
| 41 | [ -z "$QUERY_TIME" ] && QUERY_TIME="9999"
|
---|
| 42 | $verbose && echo "$QUERY_TIME"
|
---|
| 43 | echo "$QUERY_TIME $NAMESERVER" >> $RESULTLIST
|
---|
| 44 | done
|
---|
| 45 |
|
---|
| 46 | # Get the header part
|
---|
| 47 | sed -n "1,\+$TAG+p" /etc/resolv.conf > $NEWRESOLV || exit 1
|
---|
| 48 |
|
---|
| 49 | # Output sorted list
|
---|
| 50 | NAMESERVERS=`sort -n $RESULTLIST | uniq -f 1 | awk '{print $2}'`
|
---|
| 51 | for NAMESERVER in $NAMESERVERS; do
|
---|
| 52 | QUERY_TIME=`grep -m 1 "${NAMESERVER}$" $RESULTLIST | cut -d' ' -f1`
|
---|
| 53 | [ "$QUERY_TIME" = "9999" ] && STATUS="Query time: down" || STATUS="Query time: $QUERY_TIME"
|
---|
| 54 | # awk magic to get maximum length of comment field (for display purposes).
|
---|
| 55 | ML=`awk '/^nameserver/ {l=length($4);if (l>ml){ml=l}}END{print ml}' $DYNLIST`
|
---|
| 56 | # awk magic allows adding or updating of status of nameserver
|
---|
| 57 | awk '/^nameserver[[:blank:]]+'"$NAMESERVER"'[[:blank:]]+/ {printf "nameserver %-16s # %-'$ML's (%s)\n", $2, $4,"'"$STATUS"'"}' $DYNLIST >> $NEWRESOLV || exit 1
|
---|
| 58 | done
|
---|
| 59 | $verbose && echo "################################"
|
---|
| 60 | $verbose && echo "## BEGIN new /etc/resolv.conf ##"
|
---|
| 61 | $verbose && echo "################################"
|
---|
| 62 | $verbose && cat $NEWRESOLV
|
---|
| 63 | $verbose && echo "################################"
|
---|
| 64 | $verbose && echo "## END new /etc/resolv.conf ##"
|
---|
| 65 | $verbose && echo "################################"
|
---|
| 66 | cat $NEWRESOLV > /etc/resolv.conf || exit 1
|
---|
| 67 |
|
---|
| 68 | # Update unbound forwarders list
|
---|
| 69 | unbound-control forward $(awk '/^nameserver 172/ {print $2}' /etc/resolv.conf | uniq | head -3)
|
---|
| 70 | fi
|
---|