X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=src%2Finitscripts%2Fsystem%2Funbound;h=34b3e06fda5179fdca1b963c0210b213d2d15fff;hp=3002f480050cd4f7c63c228843caf15cc5950978;hb=e263c29c929e69e345833f436d4958d88264020c;hpb=05478072cd8faee443ceadb1ebfac11057bd6dc1 diff --git a/src/initscripts/system/unbound b/src/initscripts/system/unbound index 3002f48005..34b3e06fda 100644 --- a/src/initscripts/system/unbound +++ b/src/initscripts/system/unbound @@ -14,6 +14,7 @@ TEST_DOMAIN_FAIL="dnssec-failed.org" INSECURE_ZONES= USE_FORWARDERS=1 +ENABLE_SAFE_SEARCH=off # Cache any local zones for 60 seconds LOCAL_TTL=60 @@ -24,30 +25,6 @@ EDNS_DEFAULT_BUFFER_SIZE=4096 # Load optional configuration [ -e "/etc/sysconfig/unbound" ] && . /etc/sysconfig/unbound -function cidr() { - local cidr nbits IFS; - IFS=. read -r i1 i2 i3 i4 <<< ${1} - IFS=. read -r m1 m2 m3 m4 <<< ${2} - cidr=$(printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))") - nbits=0 - IFS=. - for dec in $2 ; do - case $dec in - 255) let nbits+=8;; - 254) let nbits+=7;; - 252) let nbits+=6;; - 248) let nbits+=5;; - 240) let nbits+=4;; - 224) let nbits+=3;; - 192) let nbits+=2;; - 128) let nbits+=1;; - 0);; - *) echo "Error: $dec is not recognised"; exit 1 - esac - done - echo "${cidr}/${nbits}" -} - ip_address_revptr() { local addr=${1} @@ -61,7 +38,7 @@ read_name_servers() { local i for i in 1 2; do echo "$(/dev/null | xargs echo } config_header() { @@ -172,9 +149,9 @@ own_hostname() { } update_hosts() { - local enabled address hostname domainname + local enabled address hostname domainname generateptr - while IFS="," read -r enabled address hostname domainname; do + while IFS="," read -r enabled address hostname domainname generateptr; do [ "${enabled}" = "on" ] || continue # Build FQDN @@ -185,6 +162,9 @@ update_hosts() { # Skip reverse resolution if the address equals the GREEN address [ "${address}" = "${GREEN_ADDRESS}" ] && continue + # Skip reverse resolution if user requested not to do so + [ "${generateptr}" = "off" ] && continue + # Add RDNS address=$(ip_address_revptr ${address}) unbound-control -q local_data "${address} ${LOCAL_TTL} IN PTR ${fqdn}" @@ -197,8 +177,8 @@ write_forward_conf() { local insecure_zones="${INSECURE_ZONES}" - local enabled zone server remark - while IFS="," read -r enabled zone server remark; do + local enabled zone server servers remark disable_dnssec rest + while IFS="," read -r enabled zone servers remark disable_dnssec rest; do # Line must be enabled. [ "${enabled}" = "on" ] || continue @@ -208,12 +188,43 @@ write_forward_conf() { *.local) insecure_zones="${insecure_zones} ${zone}" ;; + *) + if [ "${disable_dnssec}" = "on" ]; then + insecure_zones="${insecure_zones} ${zone}" + 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}" + for server in ${servers//|/ }; do + if [[ ${server} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo " stub-addr: ${server}" + else + echo " stub-host: ${server}" + fi + done + echo + echo "server:" + echo " local-zone: \"${zone}\" transparent" + echo + ;; + *) + echo "forward-zone:" + echo " name: ${zone}" + for server in ${servers//|/ }; do + if [[ ${server} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo " forward-addr: ${server}" + else + echo " forward-host: ${server}" + fi + done + echo + ;; + esac done < /var/ipfire/dnsforward/config if [ -n "${insecure_zones}" ]; then @@ -364,7 +375,12 @@ ns_is_validating() { 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. @@ -454,6 +470,284 @@ disable_dnssec() { 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 +} + +resolve() { + local hostname="${1}" + + local found=0 + local ns + for ns in $(read_name_servers); do + local answer + for answer in $(dig +short "@${ns}" A "${hostname}"); do + found=1 + + # Filter out non-IP addresses + if [[ ! "${answer}" =~ \.$ ]]; then + echo "${answer}" + fi + done + + # End loop when we have got something + [ ${found} -eq 1 ] && break + done +} + +# Sets up Safe Search for various search engines +write_safe_search_conf() { + local google_tlds=( + google.ad + google.ae + google.al + google.am + google.as + google.at + google.az + google.ba + google.be + google.bf + google.bg + google.bi + google.bj + google.bs + google.bt + google.by + google.ca + google.cat + google.cd + google.cf + google.cg + google.ch + google.ci + google.cl + google.cm + google.cn + google.co.ao + google.co.bw + google.co.ck + google.co.cr + google.co.id + google.co.il + google.co.in + google.co.jp + google.co.ke + google.co.kr + google.co.ls + google.com + google.co.ma + google.com.af + google.com.ag + google.com.ai + google.com.ar + google.com.au + google.com.bd + google.com.bh + google.com.bn + google.com.bo + google.com.br + google.com.bz + google.com.co + google.com.cu + google.com.cy + google.com.do + google.com.ec + google.com.eg + google.com.et + google.com.fj + google.com.gh + google.com.gi + google.com.gt + google.com.hk + google.com.jm + google.com.kh + google.com.kw + google.com.lb + google.com.ly + google.com.mm + google.com.mt + google.com.mx + google.com.my + google.com.na + google.com.nf + google.com.ng + google.com.ni + google.com.np + google.com.om + google.com.pa + google.com.pe + google.com.pg + google.com.ph + google.com.pk + google.com.pr + google.com.py + google.com.qa + google.com.sa + google.com.sb + google.com.sg + google.com.sl + google.com.sv + google.com.tj + google.com.tr + google.com.tw + google.com.ua + google.com.uy + google.com.vc + google.com.vn + google.co.mz + google.co.nz + google.co.th + google.co.tz + google.co.ug + google.co.uk + google.co.uz + google.co.ve + google.co.vi + google.co.za + google.co.zm + google.co.zw + google.cv + google.cz + google.de + google.dj + google.dk + google.dm + google.dz + google.ee + google.es + google.fi + google.fm + google.fr + google.ga + google.ge + google.gg + google.gl + google.gm + google.gp + google.gr + google.gy + google.hn + google.hr + google.ht + google.hu + google.ie + google.im + google.iq + google.is + google.it + google.je + google.jo + google.kg + google.ki + google.kz + google.la + google.li + google.lk + google.lt + google.lu + google.lv + google.md + google.me + google.mg + google.mk + google.ml + google.mn + google.ms + google.mu + google.mv + google.mw + google.ne + google.nl + google.no + google.nr + google.nu + google.pl + google.pn + google.ps + google.pt + google.ro + google.rs + google.ru + google.rw + google.sc + google.se + google.sh + google.si + google.sk + google.sm + google.sn + google.so + google.sr + google.st + google.td + google.tg + google.tk + google.tl + google.tm + google.tn + google.to + google.tt + google.vg + google.vu + google.ws + ) + + ( + # Nothing to do if safe search is not enabled + if [ "${ENABLE_SAFE_SEARCH}" != "on" ]; then + exit 0 + fi + + # This all belongs into the server: section + echo "server:" + + # Bing + 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 typetransparent" + for address in $(resolve "safe.duckduckgo.com"); do + echo " local-data: \"duckduckgo.com ${LOCAL_TTL} IN A ${address}\"" + done + + # Google + addresses="$(resolve "forcesafesearch.google.com")" + local domain + for domain in ${google_tlds[@]}; do + echo " local-zone: ${domain} transparent" + for address in ${addresses}; do + echo " local-data: \"www.${domain} ${LOCAL_TTL} IN A ${address}\"" + done + done + + # Yandex + 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" + for address in $(resolve "restrictmoderate.youtube.com"); do + echo " local-data: \"www.youtube.com ${LOCAL_TTL} IN A ${address}\"" + done + ) > /etc/unbound/safe-search.conf +} + case "$1" in start) # Print a nicer messagen when unbound is already running @@ -464,14 +758,10 @@ case "$1" in eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings) - # Create control keys at first run - if [ ! -r "/etc/unbound/unbound_control.key" ]; then - unbound-control-setup -d /etc/unbound &>/dev/null - fi - # Update configuration files write_tuning_conf write_forward_conf + write_safe_search_conf boot_mesg "Starting Unbound DNS Proxy..." loadproc /usr/sbin/unbound || exit $? @@ -485,15 +775,7 @@ case "$1" in # Update hosts update_hosts - # 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 work ... init time with ntp.ipfire.org at 81.3.27.46 ..." - loadproc /usr/local/bin/settime 81.3.27.46 - fi - fi + fix_time_if_dns_fail ;; stop) @@ -518,6 +800,11 @@ case "$1" in fi update_forwarders + + unbound-control flush_negative > /dev/null + unbound-control flush_bogus > /dev/null + + fix_time_if_dns_fail ;; test-name-server) @@ -556,8 +843,12 @@ case "$1" in exit ${ret} ;; + resolve) + resolve "${2}" + ;; + *) - echo "Usage: $0 {start|stop|restart|status|update-forwarders|test-name-server}" + echo "Usage: $0 {start|stop|restart|status|update-forwarders|test-name-server|resolve}" exit 1 ;; esac