#!/bin/sh # Begin $rc_base/init.d/unbound # Description : Unbound DNS resolver boot script for IPfire # Author : Marcel Lorenz . /etc/sysconfig/rc . ${rc_functions} TEST_DOMAIN="ipfire.org" # This domain will never validate TEST_DOMAIN_FAIL="dnssec-failed.org" # Cache any local zones for 60 seconds LOCAL_TTL=60 # Load configuration eval $(/usr/local/bin/readhash /var/ipfire/dns/settings) eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings) ip_address_revptr() { local addr=${1} local a1 a2 a3 a4 IFS=. read -r a1 a2 a3 a4 <<< ${addr} echo "${a4}.${a3}.${a2}.${a1}.in-addr.arpa" } read_name_servers() { # Read name servers from ISP if [ "${USE_ISP_NAMESERVERS}" = "on" -a "${PROTO}" != "TLS" ]; then local i for i in 1 2; do echo "$(/dev/null fi # Read configured name servers local id address tls_hostname enabled remark while IFS="," read -r id address tls_hostname enabled remark; do [ "${enabled}" != "enabled" ] && continue if [ "${PROTO}" = "TLS" ]; then if [ -n "${tls_hostname}" ]; then echo "${address}@853#${tls_hostname}" fi else echo "${address}" fi done < /var/ipfire/dns/servers } check_red_has_carrier_and_ip() { # Interface configured ? [ ! -e "/var/ipfire/red/iface" ] && return 0; # Interface present ? [ ! -e "/sys/class/net/$( /etc/unbound/forward.conf } write_tuning_conf() { # https://www.unbound.net/documentation/howto_optimise.html # Determine number of online processors local processors=$(getconf _NPROCESSORS_ONLN) # Determine number of slabs local slabs=1 while [ ${slabs} -lt ${processors} ]; do slabs=$(( ${slabs} * 2 )) done # Determine amount of system memory local mem=$(get_memory_amount) # 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 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=16 # Everything else else mem=64 fi ( config_header # We run one thread per processor echo "num-threads: ${processors}" echo "so-reuseport: yes" # Adjust number of slabs echo "infra-cache-slabs: ${slabs}" echo "key-cache-slabs: ${slabs}" echo "msg-cache-slabs: ${slabs}" echo "rrset-cache-slabs: ${slabs}" # Slice up the cache 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 } get_memory_amount() { local key val unit while read -r key val unit; do case "${key}" in MemTotal:*) # Convert to MB echo "$(( ${val} / 1024 ))" break ;; esac done < /proc/meminfo } fix_time_if_dns_fail() { # If DNS still not work try to init ntp with # hardcoded ntp.ipfire.org (81.3.27.46) 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)..." loadproc /usr/local/bin/settime 81.3.27.46 fi fi } resolve() { local hostname="${1}" local answer for answer in $(dig +short A "${hostname}"); do # Filter out non-IP addresses if [[ ! "${answer}" =~ \.$ ]]; then echo "${answer}" fi done } update_forwarders() { # DO nothing when we do not use the ISP name servers [ "${USE_ISP_NAMESERVERS}" != "on" ] && return 0 # Update unbound about the new servers local nameservers=( $(read_name_servers) ) if [ -n "${nameservers[*]}" ]; then unbound-control -q forward "${nameservers[@]}" else unbound-control -q forward off fi } # Sets up Safe Search for various search engines update_safe_search() { 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 ) # Cleanup previous settings unbound-control local_zone_remove "bing.com" >/dev/null unbound-control local_zone_remove "duckduckgo.com" >/dev/null unbound-control local_zone_remove "yandex.com" >/dev/null unbound-control local_zone_remove "yandex.ru" >/dev/null unbound-control local_zone_remove "youtube.com" >/dev/null local domain for domain in ${google_tlds[@]}; do unbound-control local_zone_remove "${domain}" done >/dev/null # Nothing to do if safe search is not enabled if [ "${ENABLE_SAFE_SEARCH}" != "on" ]; then return 0 fi # Bing unbound-control bing.com transparent >/dev/null for address in $(resolve "strict.bing.com"); do unbound-control local_data "www.bing.com ${LOCAL_TTL} IN A ${address}" done >/dev/null # DuckDuckGo unbound-control local_zone duckduckgo.com typetransparent >/dev/null for address in $(resolve "safe.duckduckgo.com"); do unbound-control local_data "duckduckgo.com ${LOCAL_TTL} IN A ${address}" done >/dev/null # Google local addresses="$(resolve "forcesafesearch.google.com")" for domain in ${google_tlds[@]}; do unbound-control local_zone "${domain}" transparent >/dev/null for address in ${addresses}; do unbound-control local_data: "www.${domain} ${LOCAL_TTL} IN A ${address}" done >/dev/null done # Yandex for domain in yandex.com yandex.ru; do unbound-control local_zone "${domain}" typetransparent >/dev/null for address in $(resolve "familysearch.${domain}"); do unbound-control local_data "${domain} ${LOCAL_TTL} IN A ${address}" done >/dev/null done # YouTube unbound-control local_zone youtube.com transparent >/dev/null for address in $(resolve "restrictmoderate.youtube.com"); do unbound-control local_data "www.youtube.com ${LOCAL_TTL} IN A ${address}" done >/dev/null return 0 } case "$1" in start) # Print a nicer messagen when unbound is already running if pidofproc -s unbound; then statusproc /usr/sbin/unbound exit 0 fi # Update configuration files write_tuning_conf write_forward_conf boot_mesg "Starting Unbound DNS Proxy..." loadproc /usr/sbin/unbound || exit $? # Make own hostname resolveable own_hostname # Install Safe Search rules when the system is already online if [ -e "/var/ipfire/red/active" ]; then update_safe_search fi # Update hosts update_hosts fix_time_if_dns_fail ;; stop) boot_mesg "Stopping Unbound DNS Proxy..." killproc /usr/sbin/unbound ;; restart) $0 stop sleep 1 $0 start ;; status) statusproc /usr/sbin/unbound ;; update-forwarders) update_forwarders # Update Safe Search settings update_safe_search ;; remove-forwarders) update_forwarders ;; resolve) resolve "${2}" ;; update-safe-search) update_safe_search ;; *) echo "Usage: $0 {start|stop|restart|status|resolve|update-forwarders|remove-forwarders|update-safe-search}" exit 1 ;; esac # End $rc_base/init.d/unbound