From: Erik Kapfer Date: Fri, 1 Nov 2019 13:38:57 +0000 (+0100) Subject: DNS-over-TLS: Integration into web user interface X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2FDoT;p=people%2Fummeegge%2Fipfire-2.x.git DNS-over-TLS: Integration into web user interface - unbound init has been modified and do not uses 'update_forwarders' function if DoT has been detected. - DoT works with forward.conf which includes also 'qname-minimization strict'. - dnsovertls.cgi can be used to configure DoT connections but do also accepts other ports (e.g. 53). - dot-indexCGI-check checks if and how the connections has been established and delivers the result to /var/ipfire/red/dot which will be used by index.cgi to deliver the status via color codes. color codes: red = server is off ; orange = DNSsec do not works but certificate is trustworthy and crypto works ; green = all is working. - check_connections.sh is a shell script which checks all configured connections also with the above color codes. - test_tls.sh is also a shell script which check also all configured connections but with the raw output of kdig. - language file has only be adapted for english. Signed-off-by: Erik Kapfer --- diff --git a/config/dot/EX-dnsovertls.menu b/config/dot/EX-dnsovertls.menu new file mode 100644 index 0000000000..32826667be --- /dev/null +++ b/config/dot/EX-dnsovertls.menu @@ -0,0 +1,6 @@ +$subipfire->{'56.dnsovertls'} = { + 'caption' => $Lang::tr{'dnsovertls'}, + 'uri' => '/cgi-bin/dnsovertls.cgi', + 'title' => $Lang::tr{'dnsovertls'}, + 'enabled' => 1, +}; \ No newline at end of file diff --git a/config/dot/check_connection.sh b/config/dot/check_connection.sh new file mode 100644 index 0000000000..9b28e45e82 --- /dev/null +++ b/config/dot/check_connection.sh @@ -0,0 +1,89 @@ +#!/bin/bash - + +# Text and formatting +COLUMNS="$(tput cols)"; +R=$(tput setaf 1); +G=$(tput setaf 2); +O=$(tput setaf 166) +N=$(tput sgr0); +seperator(){ printf -v _hr "%*s" ${COLUMNS} && echo ${_hr// /${1-=}}; } +WELCOME="${b}${O}Will check now your configured DNS-over-TLS servers from '/etc/unbound/forward.conf'${N}" + +# Check if kdig is presant +command -v kdig >/dev/null 2>&1 || { echo >&2 "kdig is required but it's not installed. Aborting."; exit 1; } + +# Paths +FORWARDCONF="/etc/unbound/forward.conf" +BUNDLE="/etc/ssl/certs/ca-bundle.crt" + +# Check for DoT forwarder +if ! grep -ERw "forward-addr: ([0-9.]+){4}@853#[a-zA-Z0-9]+([-.]?[a-zA-Z0-9]+)*.[a-zA-Z]+$" ${FORWARDCONF} > /dev/null 2>&1; then + echo "Haven´t found usable DoT forwarders in ${FORWARDCONF}. Need to quit... " + exit 1 +fi + +# Get DoT data and write it to files +DOT="/tmp/DOT" +HOST="/tmp/host.in" +IP="/tmp/ip.in" +grep -hERo "([0-9.]+){4}@853#.*" ${FORWARDCONF} > ${DOT} +awk -F'#' '{ print $2 }' ${DOT} > ${HOST} +awk -F'@' '{ print $1 }' ${DOT} > ${IP} + + +# Mainpart +clear +seperator "$@" +echo +printf "%*s\n" $(((${#WELCOME}+COLUMNS)/2)) "${WELCOME}"; +echo +while read -u 3 -r ip && read -u 4 -r host; do + echo + seperator "$@" + echo "From Host: ${O}${host}${N} ---- With IP: ${O}${ip}${N} ---- Date: ${O}$(date)${N}" + echo + IFS=$'\n' + check_array=( $(kdig -d @"${ip}" +dnssec +tls-ca=${BUNDLE} +tls-host="${host}" www.isoc.org | \ + grep -oE 'The certificate.*|TLS session.*|ra ad;|\(TCP\) in .*' | sed -e 's/;//g' -e 's/(TCP) //g') ) + for element in "${check_array[@]}"; do + echo "${element}" | sed -e '/The certificate is trusted./d' -e '/TLS session.*/d' -e '/ra.*/d' + done + echo + + # Check TLS + if echo "${check_array[1]}" | grep -q 'TLS session'; then + ENC=$(echo "${check_array[1]}" | awk '{ print $3 }' | sed -e 's/(//g' -e 's/)//g') + echo "${G}The encryption is OK and works with: ${ENC}${N}" + else + echo "${R}Encryption do not works, this server seems to be OFF${N}" + continue + + fi + echo + + # Check certificate trust + if [ "${check_array[0]}" = "The certificate is trusted. " ]; then + echo "${G}The certificate is trusted and OK${N}" + else + echo "${R}The certificate is NOT Trusted and NOT OK${N}" + fi + echo + + # Check DNSSEC + if [ "${check_array[2]}" = "ra ad" ]; then + echo "${G}The DNSSEC validation works and is OK${N}" + else + echo "${R}The DNSSEC validation do NOT works and is NOT OK${N}" + fi + +done 3<${IP} 4<${HOST} + +echo +seperator +echo +echo "All DNS-over-TLS servers from /etc/unbound/forward.conf has been tested." + +# Clean up +rm -rf ${DOT} ${IP} ${HOST} + +# EOF diff --git a/config/dot/dot-indexCGI-check b/config/dot/dot-indexCGI-check new file mode 100755 index 0000000000..0c3b3c1bbd --- /dev/null +++ b/config/dot/dot-indexCGI-check @@ -0,0 +1,78 @@ +#!/bin/bash - + +# Script checks if DoT server certificate is trusted and if DNSSec works. +# If the certificate is trusted and DNSsec works, the server IP will be +# displayed in color green. +# If the certificate is trusted but DNSsec do NOT works, the IP will be +# displayed in orange. +# If the certificate is NOT trusted, the server IP will be displayed in red. +# +# Script uses HTML font color attributes and pipes them to /var/ipfire/red/dns +# so the index.cgi can it display in IPFire home WUI site. +# +# ummeegge ipfire.org ; 29.09.2019 +############################################################################## +# + +## Formatting +# Certificate is trusted, DNSSEC works +G="" +# Certificate is trusted but DNSSEC does NOT work +O="" +# Server certificate is not trusted and should NOT be used +R="" +N="" + +# Paths +FORWARDCONF="/etc/unbound/forward.conf" +BUNDLE="/etc/ssl/certs/ca-bundle.crt" +# Get DoT data and write it to files +DOT="/tmp/DOT" +HOST="/tmp/host.in" +IP="/tmp/ip.in" +RES="/tmp/result" +DNS="/var/ipfire/red/dot" +grep -hERo "([0-9.]+){4}@853#.*" ${FORWARDCONF} > ${DOT} +awk -F'#' '{ print $2 }' ${DOT} > ${HOST} +awk -F'@' '{ print $1 }' ${DOT} > ${IP} + +# Check for DoT forwarder +if ! grep -ERw "forward-addr: ([0-9.]+){4}@853#[a-zA-Z0-9]+([-.]?[a-zA-Z0-9]+)*.[a-zA-Z]+$" ${FORWARDCONF} > /dev/null 2>&1; then + logger -t DNS-over-TLS "DoT: Haven´t found usable DoT forwarders in ${FORWARDCONF}. '/etc/fcron.hourly/dot-indexCGI-color.sh' Need to quit... " + exit 1 +else + echo > ${DNS} +fi + +search_func() { + if [[ "${check_array[0]}" = "The certificate is trusted. " ]] && [[ "${check_array[2]}" = "ra ad" ]]; then + echo "${G}${ip}${N}" + elif [[ "${check_array[0]}" = "The certificate is trusted. " ]] && [[ "${check_array[2]}" != "ra ad" ]]; then + echo "${O}${ip}${N}" + else + echo "${R}${ip}${N}" + continue + fi +} + +# Mainpart + +while read -u 3 -r ip && read -u 4 -r host; do + IFS=$'\n' + check_array=( $(kdig -d @"${ip}" +dnssec +tls-ca=${BUNDLE} +tls-host="${host}" www.isoc.org | \ + grep -oE 'The certificate.*|TLS session.*|ra ad;|\(TCP\) in .*' | sed -e 's/;//g' -e 's/(TCP) //g') ) + for element in "${check_array[@]}"; do + echo "${element}" | sed -e '/The certificate is trusted./d' -e '/TLS session.*/d' -e '/ra.*/d' -e '/in /d' + done + + search_func >> ${RES} + +done 3<${IP} 4<${HOST} 2> /dev/null + +cat ${RES} | sed ':a;N;s/\n/ | /;ta' > ${DNS} + +# Clean up +rm -rf ${DOT} ${IP} ${HOST} ${RES} + +# EOF + diff --git a/config/dot/test_tls.sh b/config/dot/test_tls.sh new file mode 100644 index 0000000000..97711e978c --- /dev/null +++ b/config/dot/test_tls.sh @@ -0,0 +1,52 @@ +#!/bin/bash - + +# +# Test if DoT certificates are trustworthy. +# +# ummeegge 08.12.2018 +########################################### +# + +# Formatting +COLUMNS="$(tput cols)"; +seperator(){ printf -v _hr "%*s" ${COLUMNS} && echo ${_hr// /${1-=}}; } + +# Check if kdig is presant +command -v kdig >/dev/null 2>&1 || { echo >&2 "kdig is required but it's not installed. Aborting."; exit 1; } + +# Paths +FORWARDCONF="/etc/unbound/forward.conf" +BUNDLE="/etc/ssl/certs/ca-bundle.crt" + +# Check for DoT forwarder +if ! grep -ERw "forward-addr: ([0-9.]+){4}@853#[a-zA-Z0-9]+([-.]?[a-zA-Z0-9]+)*.[a-zA-Z]+$" ${FORWARDCONF} > /dev/null 2>&1; then + echo "Haven´t found usable DoT forwarders in ${FORWARDCONF}. Need to quit... " + exit 1 +fi + +# Get DoT data and write it to files +DOT="/tmp/DOT" +HOST="/tmp/host.in" +IP="/tmp/ip.in" +grep -hERo "([0-9.]+){4}@853#.*" ${FORWARDCONF} > ${DOT} +awk -F'#' '{ print $2 }' ${DOT} > ${HOST} +awk -F'@' '{ print $1 }' ${DOT} > ${IP} + +# Mainpart +echo +seperator +while read -u 3 -r ip && read -u 4 -r host; do + echo + kdig -d @"${ip}" +dnssec +tls-ca="${BUNDLE}" +tls-host="${host}" www.isoc.org; exit=$? + echo + echo "Exit status: $exit" + echo + seperator + sleep 5 +done 3<${IP} 4<${HOST} + +# Clean up +rm -rf ${DOT} ${IP} ${HOST} + + +# EOF diff --git a/html/cgi-bin/dnsovertls.cgi b/html/cgi-bin/dnsovertls.cgi new file mode 100644 index 0000000000..dc22f1b040 --- /dev/null +++ b/html/cgi-bin/dnsovertls.cgi @@ -0,0 +1,398 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2013 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +use strict; + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +#workaround to suppress a warning when a variable is used only once +my @dummy = ( ${Header::colouryellow} ); +undef (@dummy); + +my %cgiparams=(); +my %checked=(); +my %selected=(); +my $errormessage = ''; +my $tlsconfig = "${General::swroot}/dns/tlsconfig"; +my $changed = 'no'; +my %color = (); +my %mainsettings = (); +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); +&Header::showhttpheaders(); + +$cgiparams{'ENABLED'} = 'off'; +$cgiparams{'ACTION'} = ''; +$cgiparams{'HOSTNAME'} = ''; +$cgiparams{'SERVER_IP'} = ''; +$cgiparams{'PORT'} = '853'; +$cgiparams{'REMARK'} =''; +&Header::getcgihash(\%cgiparams); +open(FILE, ">>$tlsconfig") or die 'Unable to create file.'; +open(FILE, $tlsconfig) or die 'Unable to open config file.'; +my @current = ; +close(FILE); + +### +# Add / Edit entries. +# +if ($cgiparams{'ACTION'} eq $Lang::tr{'add'}) +{ + + # Check if the entered domainname is valid. + unless(&General::validfqdn($cgiparams{'HOSTNAME'})) { + $errormessage = $Lang::tr{'invalid domain name'}; + goto ERROR; + } + + # Check if the settings for the forward server are valid. + unless(&General::validip($cgiparams{'SERVER_IP'})) { + $errormessage = $Lang::tr{'invalid ip'}; + goto ERROR; + } + + # Check if the settings for the port are valid. + unless(&General::validport($cgiparams{'PORT'})) { + $errormessage = $Lang::tr{'invalid port'}; + goto ERROR; + } + + # Go further if there was no error. + if ( ! $errormessage) + { + # Check if a remark has been entered. + $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); + + # Check if we want to edit an existing or add a new entry. + if($cgiparams{'EDITING'} eq 'no') { + # Check in 'ADD' mode if IP is already in usage + foreach my $line (@current) { + chomp($line); + my @temp=split(/\,/,$line); + if ($temp[2] eq $cgiparams{'SERVER_IP'}) { + $errormessage = $Lang::tr{'fwhost err ipcheck'}; + goto ERROR; + } + } + + open(FILE,">>$tlsconfig") or die 'Unable to open config file.'; + flock FILE, 2; + print FILE "$cgiparams{'ENABLED'},$cgiparams{'HOSTNAME'},$cgiparams{'SERVER_IP'},$cgiparams{'PORT'},$cgiparams{'REMARK'}\n"; + } else { + open(FILE, ">$tlsconfig") or die 'Unable to open config file.'; + flock FILE, 2; + my $id = 0; + foreach my $line (@current) + { + $id++; + if ($cgiparams{'EDITING'} eq $id) { + print FILE "$cgiparams{'ENABLED'},$cgiparams{'HOSTNAME'},$cgiparams{'SERVER_IP'},$cgiparams{'PORT'},$cgiparams{'REMARK'}\n"; + } else { print FILE "$line"; } + } + } + + close(FILE); + undef %cgiparams; + $changed = 'yes'; + } else { + # stay on edit mode if an error occur + if ($cgiparams{'EDITING'} ne 'no') + { + $cgiparams{'ACTION'} = $Lang::tr{'edit'}; + $cgiparams{'ID'} = $cgiparams{'EDITING'}; + } + } + # Restart unbound + system('/usr/local/bin/unboundctrl restart >/dev/null'); +} + +ERROR: + + +### +# Remove existing entries. +# +if ($cgiparams{'ACTION'} eq $Lang::tr{'delete'}) +{ + my $id = 0; + open(FILE, ">$tlsconfig") or die 'Unable to open config file.'; + flock FILE, 2; + foreach my $line (@current) + { + $id++; + unless ($cgiparams{'ID'} eq $id) { print FILE "$line"; } + } + close(FILE); + # Restart unbound. + system('/usr/local/bin/unboundctrl restart >/dev/null'); +} + +### +# Toggle Enable/Disable for entries. +# +if ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) +{ + open(FILE, ">$tlsconfig") or die 'Unable to open config file.'; + flock FILE, 2; + my $id = 0; + foreach my $line (@current) + { + $id++; + unless ($cgiparams{'ID'} eq $id) { print FILE "$line"; } + else + { + chomp($line); + my @temp = split(/\,/,$line); + print FILE "$cgiparams{'ENABLE'},$temp[1],$temp[2],$temp[3],$temp[4]\n"; + } + } + close(FILE); + # Restart unbound. + system('/usr/local/bin/unboundctrl restart >/dev/null'); +} + +### +# Read items for edit mode. +# +if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) +{ + my $id = 0; + foreach my $line (@current) + { + $id++; + if ($cgiparams{'ID'} eq $id) + { + chomp($line); + my @temp = split(/\,/,$line); + $cgiparams{'ENABLED'} = $temp[0]; + $cgiparams{'HOSTNAME'} = $temp[1]; + $cgiparams{'SERVER_IP'} = $temp[2]; + $cgiparams{'PORT'} = $temp[3]; + $cgiparams{'REMARK'} = $temp[4]; + } + } +} + +$checked{'ENABLED'}{'off'} = ''; +$checked{'ENABLED'}{'on'} = ''; +$checked{'ENABLED'}{$cgiparams{'ENABLED'}} = "checked='checked'"; + +&Header::openpage($Lang::tr{'dnsovertls configuration'}, 1, ''); + +&Header::openbigbox('100%', 'left', '', $errormessage); + + +### +# Error messages layout. +# +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + &Header::closebox(); +} + +print "
\n"; + +my $buttontext = $Lang::tr{'add'}; +if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) { + &Header::openbox('100%', 'left', $Lang::tr{'dnsforward edit an entry'}); + $buttontext = $Lang::tr{'update'}; +} else { + &Header::openbox('100%', 'left', $Lang::tr{'dnsforward add a new entry'}); +} + +### +# Content of the main page. +# +print < + + $Lang::tr{'hostname'}: * + + $Lang::tr{'enabled'} + + + + $Lang::tr{'ip address'}: * + + + + + $Lang::tr{'port'}: * + + + + + + + + +
$Lang::tr{'remark'}:
+
+
+ + + + + + +
* $Lang::tr{'required field'} + + +
+END +; +if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) { + print "\n"; +} else { + print "\n"; +} + +&Header::closebox(); +print "\n"; + +### +# Existing rules. +# +&Header::openbox('100%', 'left', $Lang::tr{'dnsovertls entries'}); +print < + + $Lang::tr{'hostname'} + $Lang::tr{'ip address'} + $Lang::tr{'port'} + $Lang::tr{'remark'} + $Lang::tr{'action'} + +END +; + +# If something has happened re-read config +if($cgiparams{'ACTION'} ne '' or $changed ne 'no') +{ + open(FILE, $tlsconfig) or die 'Unable to open config file.'; + @current = ; + close(FILE); + # Restart unbound. + system('/usr/local/bin/unboundctrl restart >/dev/null'); +} + +### +# Re-read entries and highlight selected item for editing. +# +my $id = 0; +my $col=""; +foreach my $line (@current) +{ + $id++; + chomp($line); + my @temp = split(/\,/,$line); + my $toggle = ''; + my $gif = ''; + my $gdesc = ''; + my $toggle = ''; + + if($cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'ID'} eq $id) { + print ""; + $col="bgcolor='${Header::colouryellow}'"; } + elsif ($id % 2) { + print ""; + $col="bgcolor='$color{'color22'}'"; } + else { + print ""; + $col="bgcolor='$color{'color20'}'"; } + + if ($temp[0] eq 'on') { $gif='on.gif'; $toggle='off'; $gdesc=$Lang::tr{'click to disable'};} + else { $gif='off.gif'; $toggle='on'; $gdesc=$Lang::tr{'click to enable'}; } + +### +# Display edit page. +# +print <$temp[1] + $temp[2] + $temp[3] + $temp[4] + +
+ + + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +END + ; +} +print "\n"; + +### +# Print the legend at the bottom if there are any configured entries. +# +# Check if the file size is zero - no existing entries. +if ( ! -z "$tlsconfig") { +print < + +   $Lang::tr{'legend'}: +   $Lang::tr{ + $Lang::tr{'click to disable'} +     $Lang::tr{ + $Lang::tr{'click to enable'} +     $Lang::tr{ + $Lang::tr{'edit'} +     $Lang::tr{ + $Lang::tr{'delete'} + + +END +; +} + +&Header::closebox(); + +&Header::closebigbox(); + +&Header::closepage(); + + diff --git a/html/cgi-bin/index.cgi b/html/cgi-bin/index.cgi index c7bf9f3232..9116fb0f74 100644 --- a/html/cgi-bin/index.cgi +++ b/html/cgi-bin/index.cgi @@ -213,12 +213,33 @@ END $Lang::tr{'dns servers'}: +
$dns_servers END + my $dot_servers; + if ( -e "${General::swroot}/red/dot" ) { + open (TMP, "<${General::swroot}/red/dot"); + $dot_servers = ; + chomp($dot_servers); + close TMP; + } + print < + + $Lang::tr{'dnsovertls'}: + + +
+ $dot_servers + + + +END + if (&General::RedIsWireless()) { my $iface = $netsettings{"RED_DEV"} || "red0"; diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 8b7e63cb86..2f812cf7b5 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -865,6 +865,9 @@ 'dnsforward entries' => 'Current entries', 'dnsforward forward_servers' => 'Nameservers', 'dnsforward zone' => 'Zone', +'dnsovertls' => 'DNS-over-TLS', +'dnsovertls configuration' => 'DNS-over-TLS configuration', +'dnsovertls entries' => 'DNS-over-TLS entries', 'dnssec aware' => 'DNSSEC Aware', 'dnssec disabled warning' => 'WARNING: DNSSEC has been disabled', 'dnssec information' => 'DNSSEC Information', @@ -2964,4 +2967,4 @@ 'zoneconf val zoneslave amount error' => 'A zone that is not in bridge mode can\'t have more than one NIC assigned', ); -#EOF +#EOF \ No newline at end of file diff --git a/src/initscripts/system/unbound b/src/initscripts/system/unbound index d195fd3256..7164346389 100644 --- a/src/initscripts/system/unbound +++ b/src/initscripts/system/unbound @@ -23,6 +23,10 @@ LOCAL_TTL=60 # EDNS buffer size EDNS_DEFAULT_BUFFER_SIZE=4096 +# Path to other DNS configurations +DOT="/var/ipfire/dns/tlsconfig" +DNSFORWARD="/var/ipfire/dnsforward/config" + # Load optional configuration [ -e "/etc/sysconfig/unbound" ] && . /etc/sysconfig/unbound @@ -48,6 +52,15 @@ read_name_servers() { done 2>/dev/null | xargs echo } +read_dot_servers() { + if [ -f "/usr/bin/dot-indexCGI-check" ]; then + bash /usr/bin/dot-indexCGI-check + else + dot=$(unbound-control list_forwards | grep -Eo "([0-9.]+){4}" | tr '\n' ' ') + echo "${dot}" > /var/ipfire/red/dns + fi +} + check_red_has_carrier_and_ip() { # Interface configured ? [ ! -e "/var/ipfire/red/iface" ] && return 0; @@ -264,7 +277,7 @@ write_forward_conf() { echo ;; esac - done < /var/ipfire/dnsforward/config + done < ${DNSFORWARD} if [ -n "${insecure_zones}" ]; then echo "server:" @@ -273,6 +286,33 @@ write_forward_conf() { echo " domain-insecure: ${zone}" done fi + + # Add DNS-over-TLS forwarder configuration + if grep -q '^on,' ${DOT}; then + echo "# DNS-over-TLS configuration block" + echo "server:" + echo " tls-cert-bundle: /etc/ssl/certs/ca-bundle.crt" + echo " qname-minimisation-strict: yes" + echo + echo "forward-zone:" + echo " name: \".\"" + echo " forward-tls-upstream: yes" + echo + read_dot_servers + else + echo "# DNS forward configuration block" + echo "forward-zone:" + echo " name: \".\"" + echo + read_name_servers + fi + + local enabled domain ip port remark + while IFS="," read -r enabled domain ip port remark; do + # Line must be enabled + [ "${enabled}" = "on" ] || continue + echo " forward-addr: ${ip}@${port}#${domain}" + done < ${DOT} ) > /etc/unbound/forward.conf } @@ -450,7 +490,7 @@ ns_supports_tcp() { shift # If TCP is forced we know by now if the server responds to it - if [ "${FORCE_TCP}" = "on" ]; then + if [ "${FORCE_TCP}" = "on" ]; then return 0 fi @@ -805,7 +845,6 @@ case "$1" in # Update configuration files write_tuning_conf - write_forward_conf write_safe_search_conf boot_mesg "Starting Unbound DNS Proxy..." @@ -814,12 +853,20 @@ case "$1" in # Make own hostname resolveable own_hostname - # Update any known forwarding name servers - update_forwarders + # Use update_forwards only in case if DoT or dns forwarding is disabled + # otherwise use write_forward_conf + if ! grep -q 'on' ${DOT} && ! grep -q 'on' ${DNSFORWARD}; then + update_forwarders + else + read_dot_servers + fi # Update hosts update_hosts + # Write forward conf + write_forward_conf + fix_time_if_dns_fail ;; @@ -844,7 +891,14 @@ case "$1" in exit 0 fi - update_forwarders + # Use update_forwards only in case if DoT or dns forwarding is disabled + # otherwise use write_forward_conf + if ! grep -q 'on' ${DOT} && ! grep -q 'on' ${DNSFORWARD}; then + update_forwarders + else + write_forward_conf + read_dot_servers + fi unbound-control flush_negative > /dev/null unbound-control flush_bogus > /dev/null