local i
for i in 1 2; do
echo "$(</var/ipfire/red/dns${i})"
- done | xargs echo
+ done 2>/dev/null | xargs echo
}
config_header() {
echo_warning
fi
- if [ -n "${broken_forwarders}" -a -z "${forwarders}" ]; then
- boot_mesg "Falling back to recursor mode" ${WARNING}
- echo_warning
-
- elif [ -n "${forwarders}" ]; then
+ if [ -n "${forwarders}" ]; then
boot_mesg "Configuring upstream name server(s): ${forwarders:1}" ${INFO}
echo_ok
+ # Make sure DNSSEC is activated
+ enable_dnssec
+
echo "${forwarders}" > /var/ipfire/red/dns
unbound-control -q forward ${forwarders}
return 0
+
+ # In case we have found no working forwarders
+ else
+ # Test if the recursor mode is available
+ if can_resolve_root +bufsize=${new_edns_buffer_size}; then
+ # Make sure DNSSEC is activated
+ enable_dnssec
+
+ boot_mesg "Falling back to recursor mode" ${WARNING}
+ echo_warning
+
+ # If not, we set DNSSEC in permissive mode and allow using all recursors
+ elif [ -n "${broken_forwarders}" ]; then
+ disable_dnssec
+
+ boot_mesg "DNSSEC has been set to permissive mode" ${FAILURE}
+ echo_failure
+
+ echo "${broken_forwarders}" > /var/ipfire/red/dns
+ unbound-control -q forward ${broken_forwarders}
+ return 0
+ fi
fi
fi
;;
esac
- echo "forward-zone:"
- echo " name: ${zone}"
- echo " forward-addr: ${server}"
- echo
+ # Reverse-lookup zones must be stubs
+ case "${zone}" in
+ *.in-addr.arpa)
+ echo "stub-zone:"
+ echo " name: ${zone}"
+ echo " stub-addr: ${server}"
+ echo
+ echo "server:"
+ echo " local-zone: \"${zone}\" transparent"
+ echo
+ ;;
+ *)
+ echo "forward-zone:"
+ echo " name: ${zone}"
+ echo " forward-addr: ${server}"
+ echo
+ ;;
+ esac
done < /var/ipfire/dnsforward/config
if [ -n "${insecure_zones}" ]; then
# In the worst case scenario, unbound can use double the
# amount of memory allocated to a cache due to malloc overhead
+ # Even larger systems with more than 8GB of RAM
+ if [ ${mem} -ge 8192 ]; then
+ mem=1024
+
+ # Extra large systems with more than 4GB of RAM
+ elif [ ${mem} -ge 4096 ]; then
+ mem=512
+
# Large systems with more than 2GB of RAM
- if [ ${mem} -ge 2048 ]; then
+ elif [ ${mem} -ge 2048 ]; then
+ mem=256
+
+ # Medium systems with more than 1GB of RAM
+ elif [ ${mem} -ge 1024 ]; then
mem=128
# Small systems with less than 256MB of RAM
elif [ ${mem} -le 256 ]; then
- mem=8
+ mem=16
# Everything else
else
- mem=32
+ mem=64
fi
(
# We run one thread per processor
echo "num-threads: ${processors}"
+ echo "so-reuseport: yes"
# Adjust number of slabs
echo "infra-cache-slabs: ${slabs}"
echo "rrset-cache-size: $(( ${mem} / 2 ))m"
echo "msg-cache-size: $(( ${mem} / 4 ))m"
echo "key-cache-size: $(( ${mem} / 4 ))m"
+
+ # Increase parallel queries
+ echo "outgoing-range: 8192"
+ echo "num-queries-per-thread: 4096"
+
+ # Use larger send/receive buffers
+ echo "so-sndbuf: 4m"
+ echo "so-rcvbuf: 4m"
) > /etc/unbound/tuning.conf
}
local ns=${1}
shift
- dig @${ns} A ${TEST_DOMAIN_FAIL} $@ | grep -q SERVFAIL
+ if ! dig @${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 }'
+ fi
}
# Checks if we can retrieve the DNSKEY for this domain.
return 1
}
+get_root_nameservers() {
+ while read -r hostname ttl record address; do
+ # Searching for A records
+ [ "${record}" = "A" ] || continue
+
+ echo "${address}"
+ done < /etc/unbound/root.hints
+}
+
+can_resolve_root() {
+ local ns
+ for ns in $(get_root_nameservers); do
+ if dig @${ns} +dnssec SOA . $@ >/dev/null; then
+ return 0
+ fi
+ done
+
+ # none of the servers was reachable
+ return 1
+}
+
+enable_dnssec() {
+ local status=$(unbound-control get_option val-permissive-mode)
+
+ # Log DNSSEC status
+ echo "on" > /var/ipfire/red/dnssec-status
+
+ # Don't do anything if DNSSEC is already activated
+ [ "${status}" = "no" ] && return 0
+
+ # Activate DNSSEC and flush cache with any stale and unvalidated data
+ unbound-control -q set_option val-permissive-mode: no
+ unbound-control -q flush_zone .
+}
+
+disable_dnssec() {
+ # Log DNSSEC status
+ echo "off" > /var/ipfire/red/dnssec-status
+
+ unbound-control -q set_option val-permissive-mode: yes
+}
+
+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
+ 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)..."
+ loadproc /usr/local/bin/settime 81.3.27.46
+ fi
+ fi
+}
+
case "$1" in
start)
# Print a nicer messagen when unbound is already running
# Update hosts
update_hosts
+
+ fix_time_if_dns_fail
;;
stop)
fi
update_forwarders
+
+ unbound-control flush_negative > /dev/null
+ unbound-control flush_bogus > /dev/null
+
+ fix_time_if_dns_fail
;;
test-name-server)