#!/bin/bash
# This is ugly script to use Yandex DNS nameservers together with
# Compute nameservers. Used via bind config.

BIND_CONFIG="/etc/bind/named.conf.options"
BIND_UPDATE=no

make_resolv_conf() {
    # Ignore non-user-facing interfaces
    if [ "${interface}" != "eth0" ]
    then
        exit 0
    fi
    case $reason in
        BOUND|BOUND6|RENEW|REBIND|REBOOT)
        ;;
        *)
        exit 0
        ;;
    esac
    local new_resolv_conf
    tmp_bind_conf="$(mktemp dnsupdate.XXXXXXXX)"
    chmod 644 ${tmp_bind_conf}
    # define our resolvers
    read -r -d '' CUSTOM_NAMESERVERS << EOF
nameserver ::1
EOF
    read -r -d '' YANDEX_NAMESERVERS << EOF
nameserver 2a02:6b8::1:1
nameserver 2a02:6b8:0:3400::1
EOF
    echo "${CUSTOM_NAMESERVERS}" > /tmp/nameservers
    # fill bind config
    cat <<EOF > ${tmp_bind_conf}
options {
    directory "/var/cache/bind";
    query-source address * port 5301;
    forward only;
    auth-nxdomain no;    # conform to RFC1035
    resolver-query-timeout 1;
    max-ncache-ttl 0;
    allow-query { any; };
    listen-on-v6 { any; };
    forwarders {
EOF


    # DHCPv4
    if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] ||
       [ -n "$new_domain_name_servers" ]; then
        resolv_conf=$(readlink -f "/etc/resolv.conf" 2>/dev/null) ||
            resolv_conf="/etc/resolv.conf"

        new_resolv_conf="${resolv_conf}.dhclient-new.$$"
        wait_for_rw "$new_resolv_conf"
        rm -f $new_resolv_conf

        if [ -n "$new_domain_name" ]; then
            echo domain ${new_domain_name%% *} >>$new_resolv_conf
        fi

        if [ -n "$new_domain_search" ]; then
            if [ -n "$new_domain_name" ]; then
                domain_in_search_list=""
                for domain in $new_domain_search; do
                    if [ "$domain" = "${new_domain_name}" ] ||
                       [ "$domain" = "${new_domain_name}." ]; then
                        domain_in_search_list="Yes"
                    fi
                done
                if [ -z "$domain_in_search_list" ]; then
                    new_domain_search="$new_domain_name $new_domain_search"
                fi
            fi
            echo "search ${new_domain_search}" >> $new_resolv_conf
        elif [ -n "$new_domain_name" ]; then
            echo "search ${new_domain_name}" >> $new_resolv_conf
        fi

        if [ -n "$new_domain_name_servers" ]; then
            echo "${CUSTOM_NAMESERVERS}" >>$new_resolv_conf
            for nameserver in $new_domain_name_servers; do
                echo nameserver $nameserver >>$new_resolv_conf
                echo "        ${nameserver};" >>${tmp_bind_conf}
            done
            BIND_UPDATE=yes
            echo "${YANDEX_NAMESERVERS}" >>$new_resolv_conf
        else # keep 'old' nameservers
            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p $resolv_conf >>$new_resolv_conf
        fi

    if [ -f $resolv_conf ]; then
        chown --reference=$resolv_conf $new_resolv_conf
        chmod --reference=$resolv_conf $new_resolv_conf
    fi
        mv -f $new_resolv_conf $resolv_conf
    # DHCPv6
    elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then
        resolv_conf=$(readlink -f "/etc/resolv.conf" 2>/dev/null) ||
            resolv_conf="/etc/resolv.conf"

        new_resolv_conf="${resolv_conf}.dhclient-new.$$"
        wait_for_rw "$new_resolv_conf"
        rm -f $new_resolv_conf

        if [ -n "$new_dhcp6_domain_search" ]; then
            echo "search ${new_dhcp6_domain_search}" >> $new_resolv_conf
        fi

        if [ -n "$new_dhcp6_name_servers" ]; then
            echo "${CUSTOM_NAMESERVERS}" >>$new_resolv_conf
            for nameserver in $new_dhcp6_name_servers; do
                # append %interface to link-local-address nameservers
                if [ "${nameserver##fe80::}" != "$nameserver" ] ||
                   [ "${nameserver##FE80::}" != "$nameserver" ]; then
                    nameserver="${nameserver}%${interface}"
                fi
                echo nameserver $nameserver >>$new_resolv_conf
                echo "        ${nameserver};" >>${tmp_bind_conf}
            done
            BIND_UPDATE=yes
            echo "${YANDEX_NAMESERVERS}" >>$new_resolv_conf
        else # keep 'old' nameservers
            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p $resolv_conf >>$new_resolv_conf
        fi

    if [ -f $resolv_conf ]; then
            chown --reference=$resolv_conf $new_resolv_conf
            chmod --reference=$resolv_conf $new_resolv_conf
    fi
        mv -f $new_resolv_conf $resolv_conf
    fi

    # close bind config
    cat <<EOF >> ${tmp_bind_conf}
    };
};
EOF
if [ "$BIND_UPDATE" = "yes" ]
then
    mv ${tmp_bind_conf} ${BIND_CONFIG}
else
    rm -f %{tmp_bind_conf}
fi
}
