Skip to content

Instantly share code, notes, and snippets.

@mrhillsman
Forked from odyssey4me/dns-config.sh
Created August 17, 2016 15:50
Show Gist options
  • Select an option

  • Save mrhillsman/3e9ec2bbe07b5410829ba1924c7b838e to your computer and use it in GitHub Desktop.

Select an option

Save mrhillsman/3e9ec2bbe07b5410829ba1924c7b838e to your computer and use it in GitHub Desktop.

Revisions

  1. Jesse Pretorius revised this gist Aug 17, 2016. No changes.
  2. Jesse Pretorius created this gist Aug 17, 2016.
    118 changes: 118 additions & 0 deletions dns-config.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,118 @@
    #!/bin/bash

    INPUTFILE=${INPUTFILE:-'/etc/resolv.conf'}
    DEBUG=${DEBUG:-false}

    FALLBACK_NAMESERVERS_IPV4='8.8.8.8 8.8.4.4'
    FALLBACK_NAMESERVERS_IPV6='2001:4860:4860::8888 2001:4860:4860::8844'
    HOST_ADDRESSES_IPV4=$(ip a | awk '/inet / {print $2}' | grep -v '^127\.' | cut -d/ -f1 | paste -d' ' -s)
    HOST_ADDRESSES_IPV6=$(ip a | awk '/inet6 / {print $2}' | grep -v '^::' | cut -d/ -f1 | paste -d' ' -s)
    HOST_NAMESERVERS_NOLOCAL_IPV4=$(awk '/^nameserver/ {print $2}' ${INPUTFILE} | grep -v '^127\.\|^::' | grep '\.' | paste -d' ' -s)
    HOST_NAMESERVERS_NOLOCAL_IPV6=$(awk '/^nameserver/ {print $2}' ${INPUTFILE} | grep -v '^127\.\|^::' | grep ':' | paste -d' ' -s)

    WORKING_NAMESERVER_IPV6=""
    WORKING_NAMESERVERS_IPV4=""
    WORKING_NAMESERVERS_ALL=""
    BROKEN_NAMESERVERS_ALL=""

    function test_dns {
    server_list="$@"
    if ${DEBUG}; then
    >&2 echo "--> test_dns server_list: ${server_list}"
    fi
    for server in ${server_list}; do
    if ${DEBUG}; then
    >&2 echo " |--> test_dns checking server: ${server}"
    fi
    if [[ ${BROKEN_NAMESERVERS_ALL} =~ .*${server}.* ]]; then
    if ${DEBUG}; then
    >&2 echo " |--> ${server} has already been tested and did not work"
    fi
    elif [[ ${WORKING_NAMESERVERS_ALL} =~ .*${server}.* ]]; then
    if ${DEBUG}; then
    >&2 echo " |--> ${server} has already been tested and is working"
    fi
    elif $(dig +short +time=1 @${server} google.com > /dev/null); then
    if ${DEBUG}; then
    >&2 echo " |--> test_dns test to ${server} successful"
    fi
    WORKING_NAMESERVERS_ALL="${WORKING_NAMESERVERS_ALL} ${server}"
    if $(echo ${server} | grep '\.' > /dev/null); then
    WORKING_NAMESERVERS_IPV4="${WORKING_NAMESERVERS_IPV4} ${server}"
    else
    WORKING_NAMESERVERS_IPV6="${WORKING_NAMESERVERS_IPV6} ${server}"
    fi
    else
    if ${DEBUG}; then
    >&2 echo " |--> test_dns test to ${server} not successful"
    fi
    BROKEN_NAMESERVERS_ALL="${BROKEN_NAMESERVERS_ALL} ${server}"
    fi
    done
    }

    if ${DEBUG}; then
    >&2 echo -e "\n### Starting Data ###"
    >&2 echo -e "HOST_ADDRESSES_IPV4:\n${HOST_ADDRESSES_IPV4}\n"
    >&2 echo -e "HOST_ADDRESSES_IPV6:\n${HOST_ADDRESSES_IPV6}\n"
    >&2 echo -e "HOST_NAMESERVERS_NOLOCAL_IPV4:\n${HOST_NAMESERVERS_NOLOCAL_IPV4}\n"
    >&2 echo -e "HOST_NAMESERVERS_NOLOCAL_IPV6:\n${HOST_NAMESERVERS_NOLOCAL_IPV6}\n"
    fi

    # Test to see whether the configured IPV6 resolvers work
    if [ ! -z "${HOST_NAMESERVERS_NOLOCAL_IPV6}" ]; then
    test_dns ${HOST_NAMESERVERS_NOLOCAL_IPV6}
    fi

    # Test to see whether the configured IPV4 resolvers work
    if [ ! -z "${HOST_NAMESERVERS_NOLOCAL_IPV4}" ]; then
    test_dns ${HOST_NAMESERVERS_NOLOCAL_IPV4}
    fi

    if ${DEBUG}; then
    >&2 echo -e "\n### Working Name Servers after testing resolv.conf entries ###"
    >&2 echo -e "WORKING_NAMESERVERS_IPV6:\n${WORKING_NAMESERVERS_IPV6}\n"
    >&2 echo -e "WORKING_NAMESERVERS_IPV4:\n${WORKING_NAMESERVERS_IPV4}\n"
    fi

    # If none of the resolvers work, the test whether the host has
    # a working DNS service listener on one of its IPV6 addresses.
    if [ -z "${WORKING_NAMESERVERS_IPV6}" ]; then
    test_dns ${HOST_ADDRESSES_IPV6}
    fi

    # If none of the resolvers work, the test whether the host has
    # a working DNS service listener on one of its IPV4 addresses.
    if [ -z "${WORKING_NAMESERVERS_IPV6}" ]; then
    test_dns ${HOST_ADDRESSES_IPV4}
    fi

    if ${DEBUG}; then
    >&2 echo -e "\n### Working Name Servers after testing the host addresses ###"
    >&2 echo -e "WORKING_NAMESERVERS_IPV6:\n${WORKING_NAMESERVERS_IPV6}\n"
    >&2 echo -e "WORKING_NAMESERVERS_IPV4:\n${WORKING_NAMESERVERS_IPV4}\n"
    fi

    # We only implement the fallback IPV6 addresses if none of the IPV6 addresses
    # in the existing resolv.conf and none of the IPV6 host addresses worked.
    if [ -z "${WORKING_NAMESERVERS_IPV6}" ]; then
    test_dns ${FALLBACK_NAMESERVERS_IPV6}
    fi

    # We only implement the fallback IPV4 addresses if none of the IPV4 addresses
    # in the existing resolv.conf and none of the IPV4 host addresses worked.
    if [ -z "${WORKING_NAMESERVERS_IPV4}" ]; then
    test_dns ${FALLBACK_NAMESERVERS_IPV4}
    fi

    if ${DEBUG}; then
    >&2 echo -e "\n### Working Name Servers after testing the fallback addresses ###"
    >&2 echo -e "WORKING_NAMESERVERS_IPV6:\n${WORKING_NAMESERVERS_IPV6}\n"
    >&2 echo -e "WORKING_NAMESERVERS_IPV4:\n${WORKING_NAMESERVERS_IPV4}\n"
    fi

    WORKING_NAMESERVERS_ALL="${WORKING_NAMESERVERS_IPV6} ${WORKING_NAMESERVERS_IPV4}"

    for server in ${WORKING_NAMESERVERS_ALL}; do
    echo "nameserver ${server}"
    done