mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-11 19:55:52 +02:00
unbound: Test for working EDNS buffer size and adjust accordingly
Some networks have equipment that fails to forward DNS queries with EDNS and the DO bit set. They might even lose the replies. This patch will adjust unbound so that it will not try to receive too large replies and falls back to TCP earlier. This creates some higher load on the DNS servers but at least gives us working DNS. Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
This commit is contained in:
@@ -86,6 +86,24 @@ update_forwarders() {
|
||||
esac
|
||||
done
|
||||
|
||||
# Determine EDNS buffer size
|
||||
local current_edns_buffer_size=$(unbound-control get_option edns-buffer-size)
|
||||
|
||||
if [ -n "${current_edns_buffer_size}" ]; then
|
||||
local new_edns_buffer_size=${current_edns_buffer_size}
|
||||
|
||||
for ns in ${forwarders}; do
|
||||
local edns_buffer_size=$(ns_determine_edns_buffer_size ${ns})
|
||||
if [ -n "${edns_buffer_size}" ]; then
|
||||
if [ ${edns_buffer_size} -lt ${current_edns_buffer_size} ]; then
|
||||
new_edns_buffer_size=${edns_buffer_size}
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
unbound-control -q set_option edns-buffer-size: ${new_edns_buffer_size}
|
||||
fi
|
||||
|
||||
# Show warning for any broken upstream name servers
|
||||
if [ -n "${broken_forwarders}" ]; then
|
||||
boot_mesg "Ignoring broken upstream name server(s): ${broken_forwarders:1}" ${WARNING}
|
||||
@@ -249,6 +267,7 @@ get_memory_amount() {
|
||||
|
||||
test_name_server() {
|
||||
local ns=${1}
|
||||
local args
|
||||
|
||||
# Return codes:
|
||||
# 0 DNSSEC validating
|
||||
@@ -259,9 +278,15 @@ test_name_server() {
|
||||
# Exit when the server is not reachable
|
||||
ns_is_online ${ns} || return 1
|
||||
|
||||
# Determine the maximum edns buffer size that works
|
||||
local edns_buffer_size=$(ns_determine_edns_buffer_size ${ns})
|
||||
if [ -n "${edns_buffer_size}" ]; then
|
||||
args="${args} +bufsize=${edns_buffer_size}"
|
||||
fi
|
||||
|
||||
local errors
|
||||
for rr in DNSKEY DS RRSIG; do
|
||||
if ! ns_forwards_${rr} ${ns}; then
|
||||
if ! ns_forwards_${rr} ${ns} ${args}; then
|
||||
errors="${errors} ${rr}"
|
||||
fi
|
||||
done
|
||||
@@ -271,7 +296,7 @@ test_name_server() {
|
||||
return 3
|
||||
fi
|
||||
|
||||
if ns_is_validating ${ns}; then
|
||||
if ns_is_validating ${ns} ${args}; then
|
||||
# Return 0 if validating
|
||||
return 0
|
||||
else
|
||||
@@ -283,41 +308,62 @@ test_name_server() {
|
||||
# Sends an A query to the nameserver w/o DNSSEC
|
||||
ns_is_online() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
dig @${ns} +nodnssec A ${TEST_DOMAIN} >/dev/null
|
||||
dig @${ns} +nodnssec A ${TEST_DOMAIN} $@ >/dev/null
|
||||
}
|
||||
|
||||
# Resolving ${TEST_DOMAIN_FAIL} will fail if the nameserver is validating
|
||||
ns_is_validating() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
dig @${ns} A ${TEST_DOMAIN_FAIL} | grep -q SERVFAIL
|
||||
dig @${ns} A ${TEST_DOMAIN_FAIL} $@ | grep -q SERVFAIL
|
||||
}
|
||||
|
||||
# Checks if we can retrieve the DNSKEY for this domain.
|
||||
# dig will print the SOA if nothing was found
|
||||
ns_forwards_DNSKEY() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
dig @${ns} DNSKEY ${TEST_DOMAIN} | grep -qv SOA
|
||||
dig @${ns} DNSKEY ${TEST_DOMAIN} $@ | grep -qv SOA
|
||||
}
|
||||
|
||||
ns_forwards_DS() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
dig @${ns} DS ${TEST_DOMAIN} | grep -qv SOA
|
||||
dig @${ns} DS ${TEST_DOMAIN} $@ | grep -qv SOA
|
||||
}
|
||||
|
||||
ns_forwards_RRSIG() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
dig @${ns} +dnssec A ${TEST_DOMAIN} | grep -q RRSIG
|
||||
dig @${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
|
||||
dig @${ns} +tcp A ${TEST_DOMAIN} $@ >/dev/null || return 1
|
||||
}
|
||||
|
||||
ns_determine_edns_buffer_size() {
|
||||
local ns=${1}
|
||||
shift
|
||||
|
||||
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
|
||||
echo "${b}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@@ -394,6 +440,7 @@ case "$1" in
|
||||
;;
|
||||
*)
|
||||
echo "Test failed for an unknown reason"
|
||||
exit ${ret}
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -403,6 +450,11 @@ case "$1" in
|
||||
echo "${ns} does not support TCP fallback"
|
||||
fi
|
||||
|
||||
edns_buffer_size=$(ns_determine_edns_buffer_size ${ns})
|
||||
if [ -n "${edns_buffer_size}" ]; then
|
||||
echo "EDNS buffer size for ${ns}: ${edns_buffer_size}"
|
||||
fi
|
||||
|
||||
exit ${ret}
|
||||
;;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user