INSECURE_ZONES=
USE_FORWARDERS=1
ENABLE_SAFE_SEARCH=off
+FORCE_TCP=off
# Cache any local zones for 60 seconds
LOCAL_TTL=60
# Load optional configuration
[ -e "/etc/sysconfig/unbound" ] && . /etc/sysconfig/unbound
+DIG_ARGS=()
+
+if [ "${FORCE_TCP}" = "on" ]; then
+ DIG_ARGS+=( "+tcp" )
+fi
+
ip_address_revptr() {
local addr=${1}
done 2>/dev/null | xargs echo
}
+check_red_has_carrier_and_ip() {
+ # Interface configured ?
+ [ ! -e "/var/ipfire/red/iface" ] && return 0;
+
+ # Interface present ?
+ [ ! -e "/sys/class/net/$(</var/ipfire/red/iface)" ] && return 0;
+
+ # has carrier ?
+ [ ! "$(</sys/class/net/$(</var/ipfire/red/iface)/carrier)" = "1" ] && return 0;
+
+ # has ip ?
+ [ "$(ip address show dev $(</var/ipfire/red/iface) | grep "inet")" = "" ] && return 0;
+
+ return 1;
+}
+
config_header() {
echo "# This file is automatically generated and any changes"
echo "# will be overwritten. DO NOT EDIT!"
}
update_forwarders() {
- if [ "${USE_FORWARDERS}" = "1" -a -e "/var/ipfire/red/active" ]; then
+ check_red_has_carrier_and_ip
+ if [ "${USE_FORWARDERS}" = "1" -a "${?}" = "1" ]; then
local forwarders
local broken_forwarders
unbound-control -q forward off
}
+remove_forwarders() {
+ enable_dnssec
+ echo "local recursor" > /var/ipfire/red/dns
+ unbound-control -q forward off
+
+}
+
own_hostname() {
local hostname=$(hostname -f)
# 1.1.1.1 is reserved for unused green, skip this
(
config_header
+ # Force using TCP for upstream servers only
+ if [ "${FORCE_TCP}" = "on" ]; then
+ echo "# Force using TCP for upstream servers only"
+ echo "server:"
+ echo " tcp-upstream: yes"
+ echo
+ fi
+
local insecure_zones="${INSECURE_ZONES}"
local enabled zone server servers remark disable_dnssec rest
local ns=${1}
shift
- dig @${ns} +nodnssec A ${TEST_DOMAIN} $@ >/dev/null
+ dig "${DIG_ARGS[@]}" @${ns} +nodnssec A ${TEST_DOMAIN} $@ >/dev/null
}
# Resolving ${TEST_DOMAIN_FAIL} will fail if the nameserver is validating
local ns=${1}
shift
- if ! dig @${ns} A ${TEST_DOMAIN_FAIL} $@ | grep -q SERVFAIL; then
+ if ! dig "${DIG_ARGS[@]}" @${ns} A ${TEST_DOMAIN_FAIL} $@ | grep -q SERVFAIL; then
return 1
else
# Determine if NS replies with "ad" data flag if DNSSEC enabled
- dig @${ns} +dnssec SOA ${TEST_DOMAIN} $@ | awk -F: '/\;\;\ flags\:/ { s=1; if (/\ ad/) s=0; exit s }'
+ dig "${DIG_ARGS[@]}" @${ns} +dnssec SOA ${TEST_DOMAIN} $@ | awk -F: '/\;\;\ flags\:/ { s=1; if (/\ ad/) s=0; exit s }'
fi
}
local ns=${1}
shift
- dig @${ns} DNSKEY ${TEST_DOMAIN} $@ | grep -qv SOA
+ dig "${DIG_ARGS[@]}" @${ns} DNSKEY ${TEST_DOMAIN} $@ | grep -qv SOA
}
ns_forwards_DS() {
local ns=${1}
shift
- dig @${ns} DS ${TEST_DOMAIN} $@ | grep -qv SOA
+ dig "${DIG_ARGS[@]}" @${ns} DS ${TEST_DOMAIN} $@ | grep -qv SOA
}
ns_forwards_RRSIG() {
local ns=${1}
shift
- dig @${ns} +dnssec A ${TEST_DOMAIN} $@ | grep -q RRSIG
+ dig "${DIG_ARGS[@]}" @${ns} +dnssec A ${TEST_DOMAIN} $@ | grep -q RRSIG
}
ns_supports_tcp() {
local ns=${1}
shift
- dig @${ns} +tcp A ${TEST_DOMAIN} $@ >/dev/null || return 1
+ # If TCP is forced we know by now if the server responds to it
+ if [ "${FORCE_TCP}" = "on" ]; then
+ return 0
+ fi
+
+ dig "${DIG_ARGS[@]}" @${ns} +tcp A ${TEST_DOMAIN} $@ >/dev/null || return 1
}
ns_determine_edns_buffer_size() {
local b
for b in 4096 2048 1500 1480 1464 1400 1280 512; do
- if dig @${ns} +dnssec +bufsize=${b} A ${TEST_DOMAIN} $@ >/dev/null; then
+ if dig "${DIG_ARGS[@]}" @${ns} +dnssec +bufsize=${b} A ${TEST_DOMAIN} $@ >/dev/null; then
echo "${b}"
return 0
fi
can_resolve_root() {
local ns
for ns in $(get_root_nameservers); do
- if dig @${ns} +dnssec SOA . $@ >/dev/null; then
+ if dig "${DIG_ARGS[@]}" @${ns} +dnssec SOA . $@ >/dev/null; then
return 0
fi
done
fix_time_if_dns_fail() {
# If DNS still not work try to init ntp with
# hardcoded ntp.ipfire.org (81.3.27.46)
- if [ -e /var/ipfire/red/active ]; then
+ check_red_has_carrier_and_ip
+ if [ -e "/var/ipfire/red/iface" -a "${?}" = "1" ]; then
host 0.ipfire.pool.ntp.org > /dev/null 2>&1
if [ "${?}" != "0" ]; then
boot_mesg "DNS still not functioning... Trying to sync time with ntp.ipfire.org (81.3.27.46)..."
local ns
for ns in $(read_name_servers); do
local answer
- for answer in $(dig +short "@${ns}" A "${hostname}"); do
+ for answer in $(dig "${DIG_ARGS[@]}" +short "@${ns}" A "${hostname}"); do
found=1
# Filter out non-IP addresses
echo "server:"
# Bing
- echo " local-zone: www.bing.com transparent"
+ echo " local-zone: bing.com transparent"
for address in $(resolve "strict.bing.com"); do
echo " local-data: \"www.bing.com ${LOCAL_TTL} IN A ${address}\""
done
# DuckDuckGo
- echo " local-zone: duckduckgo.com transparent"
+ echo " local-zone: duckduckgo.com typetransparent"
for address in $(resolve "safe.duckduckgo.com"); do
echo " local-data: \"duckduckgo.com ${LOCAL_TTL} IN A ${address}\""
done
done
# Yandex
- echo " local-zone: yandex.ru transparent"
- echo " local-data: \"yandex.ru A 213.180.193.56\""
+ for domain in yandex.com yandex.ru; do
+ echo " local-zone: ${domain} typetransparent"
+ for address in $(resolve "familysearch.${domain}"); do
+ echo " local-data: \"${domain} ${LOCAL_TTL} IN A ${address}\""
+ done
+ done
# YouTube
echo " local-zone: youtube.com transparent"
fix_time_if_dns_fail
;;
+ remove-forwarders)
+ # Do not try updating forwarders when unbound is not running
+ if ! pgrep unbound &>/dev/null; then
+ exit 0
+ fi
+
+ remove_forwarders
+
+ unbound-control flush_negative > /dev/null
+ unbound-control flush_bogus > /dev/null
+ ;;
+
+
test-name-server)
ns=${2}
;;
*)
- echo "Usage: $0 {start|stop|restart|status|update-forwarders|test-name-server|resolve}"
+ echo "Usage: $0 {start|stop|restart|status|update-forwarders|remove-forwarders|test-name-server|resolve}"
exit 1
;;
esac