]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/initscripts/system/unbound
dns.cgi: Show ISP name servers as disabled
[people/pmueller/ipfire-2.x.git] / src / initscripts / system / unbound
CommitLineData
d0e5f71f
ML
1#!/bin/sh
2# Begin $rc_base/init.d/unbound
3
4# Description : Unbound DNS resolver boot script for IPfire
5# Author : Marcel Lorenz <marcel.lorenz@ipfire.org>
d0e5f71f
ML
6
7. /etc/sysconfig/rc
8. ${rc_functions}
9
b29c97b1
AF
10TEST_DOMAIN="ipfire.org"
11
12# This domain will never validate
13TEST_DOMAIN_FAIL="dnssec-failed.org"
14
36792be6
MT
15# Cache any local zones for 60 seconds
16LOCAL_TTL=60
17
ee90aa98
MT
18# Load configuration
19eval $(/usr/local/bin/readhash /var/ipfire/dns/settings)
d0e5f71f 20
974d8653
MT
21DIG_ARGS=()
22
ee90aa98 23if [ "${PROTO}" = "TCP" ]; then
974d8653
MT
24 DIG_ARGS+=( "+tcp" )
25fi
26
f75c279b
AF
27ip_address_revptr() {
28 local addr=${1}
29
30 local a1 a2 a3 a4
31 IFS=. read -r a1 a2 a3 a4 <<< ${addr}
32
33 echo "${a4}.${a3}.${a2}.${a1}.in-addr.arpa"
34}
35
b8f5eda8
MT
36read_name_servers() {
37 local i
38 for i in 1 2; do
39 echo "$(</var/ipfire/red/dns${i})"
682a6b2d 40 done 2>/dev/null | xargs echo
b8f5eda8
MT
41}
42
3ec3329d
AF
43check_red_has_carrier_and_ip() {
44 # Interface configured ?
45 [ ! -e "/var/ipfire/red/iface" ] && return 0;
46
47 # Interface present ?
48 [ ! -e "/sys/class/net/$(</var/ipfire/red/iface)" ] && return 0;
49
50 # has carrier ?
51 [ ! "$(</sys/class/net/$(</var/ipfire/red/iface)/carrier)" = "1" ] && return 0;
52
53 # has ip ?
54 [ "$(ip address show dev $(</var/ipfire/red/iface) | grep "inet")" = "" ] && return 0;
55
56 return 1;
57}
58
b8f5eda8
MT
59config_header() {
60 echo "# This file is automatically generated and any changes"
61 echo "# will be overwritten. DO NOT EDIT!"
62 echo
63}
64
f75c279b
AF
65own_hostname() {
66 local hostname=$(hostname -f)
0d7ca700 67 # 1.1.1.1 is reserved for unused green, skip this
f75c279b
AF
68 if [ -n "${GREEN_ADDRESS}" -a "${GREEN_ADDRESS}" != "1.1.1.1" ]; then
69 unbound-control -q local_data "${hostname} ${LOCAL_TTL} IN A ${GREEN_ADDRESS}"
70 fi
71
72 local address
73 for address in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
74 [ -n "${address}" ] || continue
75 [ "${address}" = "1.1.1.1" ] && continue
76
77 address=$(ip_address_revptr ${address})
78 unbound-control -q local_data "${address} ${LOCAL_TTL} IN PTR ${hostname}"
79 done
80}
81
36792be6 82update_hosts() {
6874a576 83 local enabled address hostname domainname generateptr
36792be6 84
6874a576 85 while IFS="," read -r enabled address hostname domainname generateptr; do
36792be6
MT
86 [ "${enabled}" = "on" ] || continue
87
88 # Build FQDN
89 local fqdn="${hostname}.${domainname}"
90
91 unbound-control -q local_data "${fqdn} ${LOCAL_TTL} IN A ${address}"
f75c279b 92
868d2a1f
MT
93 # Skip reverse resolution if the address equals the GREEN address
94 [ "${address}" = "${GREEN_ADDRESS}" ] && continue
95
6874a576
PM
96 # Skip reverse resolution if user requested not to do so
97 [ "${generateptr}" = "off" ] && continue
98
f75c279b
AF
99 # Add RDNS
100 address=$(ip_address_revptr ${address})
101 unbound-control -q local_data "${address} ${LOCAL_TTL} IN PTR ${fqdn}"
36792be6
MT
102 done < /var/ipfire/main/hosts
103}
104
b8f5eda8
MT
105write_forward_conf() {
106 (
107 config_header
108
974d8653 109 # Force using TCP for upstream servers only
ee90aa98 110 if [ "${PROTO}" = "TCP" ]; then
974d8653
MT
111 echo "# Force using TCP for upstream servers only"
112 echo "server:"
113 echo " tcp-upstream: yes"
114 echo
115 fi
116
ee90aa98 117 local insecure_zones=""
a6dcc5bb 118
1ececb67
MT
119 local enabled zone server servers remark disable_dnssec rest
120 while IFS="," read -r enabled zone servers remark disable_dnssec rest; do
b8f5eda8
MT
121 # Line must be enabled.
122 [ "${enabled}" = "on" ] || continue
123
a6dcc5bb
MT
124 # Zones that end with .local are commonly used for internal
125 # zones and therefore not signed
126 case "${zone}" in
127 *.local)
128 insecure_zones="${insecure_zones} ${zone}"
129 ;;
1ececb67
MT
130 *)
131 if [ "${disable_dnssec}" = "on" ]; then
132 insecure_zones="${insecure_zones} ${zone}"
133 fi
134 ;;
a6dcc5bb
MT
135 esac
136
15cf79e3
MT
137 echo "stub-zone:"
138 echo " name: ${zone}"
139 for server in ${servers//|/ }; do
140 if [[ ${server} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
141 echo " stub-addr: ${server}"
142 else
143 echo " stub-host: ${server}"
144 fi
145 done
146 echo
147
148 # Make all reverse lookup zones transparent
c7e41255
MT
149 case "${zone}" in
150 *.in-addr.arpa)
c7e41255 151 echo "server:"
9f099932 152 echo " local-zone: \"${zone}\" transparent"
c7e41255
MT
153 echo
154 ;;
c7e41255 155 esac
b8f5eda8 156 done < /var/ipfire/dnsforward/config
a6dcc5bb
MT
157
158 if [ -n "${insecure_zones}" ]; then
159 echo "server:"
160
161 for zone in ${insecure_zones}; do
162 echo " domain-insecure: ${zone}"
163 done
164 fi
50005ad1
MT
165
166 echo "forward-zone:"
167 echo " name: \".\""
168
169 # Force using TLS only
ee90aa98 170 if [ "${PROTO}" = "TLS" ]; then
50005ad1
MT
171 echo " forward-tls-upstream: yes"
172 fi
173
174 # Add upstream name servers
175 local id address tls_hostname enabled remark
176 while IFS="," read -r id address tls_hostname enabled remark; do
177 # Skip disabled servers
178 [ "${enabled}" != "enabled" ] && continue
179
180 # Set DNS server
181 if [ "${PROTO}" = "TLS" ]; then
182 if [ -n "${tls_hostname}" ]; then
183 echo " forward-addr: ${address}@853#${tls_hostname}"
184 fi
185 else
186 echo " forward-addr: ${address}"
187 fi
188 done < /var/ipfire/dns/servers
b8f5eda8
MT
189 ) > /etc/unbound/forward.conf
190}
191
b658a451
MT
192write_tuning_conf() {
193 # https://www.unbound.net/documentation/howto_optimise.html
194
195 # Determine number of online processors
196 local processors=$(getconf _NPROCESSORS_ONLN)
197
198 # Determine number of slabs
199 local slabs=1
200 while [ ${slabs} -lt ${processors} ]; do
201 slabs=$(( ${slabs} * 2 ))
202 done
203
204 # Determine amount of system memory
205 local mem=$(get_memory_amount)
206
207 # In the worst case scenario, unbound can use double the
208 # amount of memory allocated to a cache due to malloc overhead
209
4a0d69ca
MT
210 # Even larger systems with more than 8GB of RAM
211 if [ ${mem} -ge 8192 ]; then
212 mem=1024
213
214 # Extra large systems with more than 4GB of RAM
215 elif [ ${mem} -ge 4096 ]; then
216 mem=512
217
b658a451 218 # Large systems with more than 2GB of RAM
4a0d69ca 219 elif [ ${mem} -ge 2048 ]; then
128db1a3 220 mem=256
b658a451 221
4a0d69ca
MT
222 # Medium systems with more than 1GB of RAM
223 elif [ ${mem} -ge 1024 ]; then
224 mem=128
225
b658a451
MT
226 # Small systems with less than 256MB of RAM
227 elif [ ${mem} -le 256 ]; then
128db1a3 228 mem=16
b658a451
MT
229
230 # Everything else
231 else
128db1a3 232 mem=64
b658a451
MT
233 fi
234
235 (
236 config_header
237
238 # We run one thread per processor
239 echo "num-threads: ${processors}"
5012e53c 240 echo "so-reuseport: yes"
b658a451
MT
241
242 # Adjust number of slabs
243 echo "infra-cache-slabs: ${slabs}"
244 echo "key-cache-slabs: ${slabs}"
245 echo "msg-cache-slabs: ${slabs}"
246 echo "rrset-cache-slabs: ${slabs}"
247
248 # Slice up the cache
249 echo "rrset-cache-size: $(( ${mem} / 2 ))m"
250 echo "msg-cache-size: $(( ${mem} / 4 ))m"
251 echo "key-cache-size: $(( ${mem} / 4 ))m"
0a7dca2c
MT
252
253 # Increase parallel queries
254 echo "outgoing-range: 8192"
255 echo "num-queries-per-thread: 4096"
c20b2009
MT
256
257 # Use larger send/receive buffers
258 echo "so-sndbuf: 4m"
259 echo "so-rcvbuf: 4m"
b658a451
MT
260 ) > /etc/unbound/tuning.conf
261}
262
263get_memory_amount() {
264 local key val unit
265
266 while read -r key val unit; do
267 case "${key}" in
268 MemTotal:*)
269 # Convert to MB
270 echo "$(( ${val} / 1024 ))"
271 break
272 ;;
273 esac
274 done < /proc/meminfo
275}
b8f5eda8 276
68fac98a
AF
277fix_time_if_dns_fail() {
278 # If DNS still not work try to init ntp with
279 # hardcoded ntp.ipfire.org (81.3.27.46)
3ec3329d
AF
280 check_red_has_carrier_and_ip
281 if [ -e "/var/ipfire/red/iface" -a "${?}" = "1" ]; then
68fac98a
AF
282 host 0.ipfire.pool.ntp.org > /dev/null 2>&1
283 if [ "${?}" != "0" ]; then
3eeff87f 284 boot_mesg "DNS still not functioning... Trying to sync time with ntp.ipfire.org (81.3.27.46)..."
68fac98a
AF
285 loadproc /usr/local/bin/settime 81.3.27.46
286 fi
287 fi
288}
289
043e7aa5
MT
290resolve() {
291 local hostname="${1}"
292
293 local found=0
294 local ns
295 for ns in $(read_name_servers); do
296 local answer
974d8653 297 for answer in $(dig "${DIG_ARGS[@]}" +short "@${ns}" A "${hostname}"); do
043e7aa5
MT
298 found=1
299
300 # Filter out non-IP addresses
301 if [[ ! "${answer}" =~ \.$ ]]; then
302 echo "${answer}"
303 fi
304 done
305
306 # End loop when we have got something
307 [ ${found} -eq 1 ] && break
308 done
309}
310
661ab153 311# Sets up Safe Search for various search engines
d7190078 312update_safe_search() {
661ab153
MT
313 local google_tlds=(
314 google.ad
315 google.ae
316 google.al
317 google.am
318 google.as
319 google.at
320 google.az
321 google.ba
322 google.be
323 google.bf
324 google.bg
325 google.bi
326 google.bj
327 google.bs
328 google.bt
329 google.by
330 google.ca
331 google.cat
332 google.cd
333 google.cf
334 google.cg
335 google.ch
336 google.ci
337 google.cl
338 google.cm
339 google.cn
340 google.co.ao
341 google.co.bw
342 google.co.ck
343 google.co.cr
344 google.co.id
345 google.co.il
346 google.co.in
347 google.co.jp
348 google.co.ke
349 google.co.kr
350 google.co.ls
351 google.com
352 google.co.ma
353 google.com.af
354 google.com.ag
355 google.com.ai
356 google.com.ar
357 google.com.au
358 google.com.bd
359 google.com.bh
360 google.com.bn
361 google.com.bo
362 google.com.br
363 google.com.bz
364 google.com.co
365 google.com.cu
366 google.com.cy
367 google.com.do
368 google.com.ec
369 google.com.eg
370 google.com.et
371 google.com.fj
372 google.com.gh
373 google.com.gi
374 google.com.gt
375 google.com.hk
376 google.com.jm
377 google.com.kh
378 google.com.kw
379 google.com.lb
380 google.com.ly
381 google.com.mm
382 google.com.mt
383 google.com.mx
384 google.com.my
385 google.com.na
386 google.com.nf
387 google.com.ng
388 google.com.ni
389 google.com.np
390 google.com.om
391 google.com.pa
392 google.com.pe
393 google.com.pg
394 google.com.ph
395 google.com.pk
396 google.com.pr
397 google.com.py
398 google.com.qa
399 google.com.sa
400 google.com.sb
401 google.com.sg
402 google.com.sl
403 google.com.sv
404 google.com.tj
405 google.com.tr
406 google.com.tw
407 google.com.ua
408 google.com.uy
409 google.com.vc
410 google.com.vn
411 google.co.mz
412 google.co.nz
413 google.co.th
414 google.co.tz
415 google.co.ug
416 google.co.uk
417 google.co.uz
418 google.co.ve
419 google.co.vi
420 google.co.za
421 google.co.zm
422 google.co.zw
423 google.cv
424 google.cz
425 google.de
426 google.dj
427 google.dk
428 google.dm
429 google.dz
430 google.ee
431 google.es
432 google.fi
433 google.fm
434 google.fr
435 google.ga
436 google.ge
437 google.gg
438 google.gl
439 google.gm
440 google.gp
441 google.gr
442 google.gy
443 google.hn
444 google.hr
445 google.ht
446 google.hu
447 google.ie
448 google.im
449 google.iq
450 google.is
451 google.it
452 google.je
453 google.jo
454 google.kg
455 google.ki
456 google.kz
457 google.la
458 google.li
459 google.lk
460 google.lt
461 google.lu
462 google.lv
463 google.md
464 google.me
465 google.mg
466 google.mk
467 google.ml
468 google.mn
469 google.ms
470 google.mu
471 google.mv
472 google.mw
473 google.ne
474 google.nl
475 google.no
476 google.nr
477 google.nu
478 google.pl
479 google.pn
480 google.ps
481 google.pt
482 google.ro
483 google.rs
484 google.ru
485 google.rw
486 google.sc
487 google.se
488 google.sh
489 google.si
490 google.sk
491 google.sm
492 google.sn
493 google.so
494 google.sr
495 google.st
496 google.td
497 google.tg
498 google.tk
499 google.tl
500 google.tm
501 google.tn
502 google.to
503 google.tt
504 google.vg
505 google.vu
506 google.ws
507 )
508
d7190078
MT
509 # Cleanup previous settings
510 unbound-control local_zone_remove "bing.com" >/dev/null
511 unbound-control local_zone_remove "duckduckgo.com" >/dev/null
512 unbound-control local_zone_remove "yandex.com" >/dev/null
513 unbound-control local_zone_remove "yandex.ru" >/dev/null
514 unbound-control local_zone_remove "youtube.com" >/dev/null
661ab153 515
d7190078
MT
516 local domain
517 for domain in ${google_tlds[@]}; do
518 unbound-control local_zone_remove "${domain}"
519 done >/dev/null
661ab153 520
d7190078
MT
521 # Nothing to do if safe search is not enabled
522 if [ "${ENABLE_SAFE_SEARCH}" != "on" ]; then
523 return 0
524 fi
661ab153 525
d7190078
MT
526 # Bing
527 unbound-control bing.com transparent >/dev/null
528 for address in $(resolve "strict.bing.com"); do
529 unbound-control local_data "www.bing.com ${LOCAL_TTL} IN A ${address}"
530 done >/dev/null
531
532 # DuckDuckGo
533 unbound-control local_zone duckduckgo.com typetransparent >/dev/null
534 for address in $(resolve "safe.duckduckgo.com"); do
535 unbound-control local_data "duckduckgo.com ${LOCAL_TTL} IN A ${address}"
536 done >/dev/null
537
538 # Google
539 local addresses="$(resolve "forcesafesearch.google.com")"
540 for domain in ${google_tlds[@]}; do
541 unbound-control local_zone "${domain}" transparent >/dev/null
542 for address in ${addresses}; do
543 unbound-control local_data: "www.${domain} ${LOCAL_TTL} IN A ${address}"
544 done >/dev/null
545 done
661ab153 546
d7190078
MT
547 # Yandex
548 for domain in yandex.com yandex.ru; do
549 unbound-control local_zone "${domain}" typetransparent >/dev/null
550 for address in $(resolve "familysearch.${domain}"); do
551 unbound-control local_data "${domain} ${LOCAL_TTL} IN A ${address}"
552 done >/dev/null
553 done
661ab153 554
d7190078
MT
555 # YouTube
556 unbound-control local_zone youtube.com transparent >/dev/null
557 for address in $(resolve "restrictmoderate.youtube.com"); do
558 unbound-control local_data "www.youtube.com ${LOCAL_TTL} IN A ${address}"
559 done >/dev/null
f617fd91 560
d7190078 561 return 0
661ab153
MT
562}
563
d0e5f71f
ML
564case "$1" in
565 start)
80bc6022
MT
566 # Print a nicer messagen when unbound is already running
567 if pidofproc -s unbound; then
568 statusproc /usr/sbin/unbound
569 exit 0
570 fi
571
b8f5eda8 572 eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
d0e5f71f 573
b8f5eda8 574 # Update configuration files
b658a451 575 write_tuning_conf
b8f5eda8
MT
576 write_forward_conf
577
578 boot_mesg "Starting Unbound DNS Proxy..."
579 loadproc /usr/sbin/unbound || exit $?
580
f75c279b
AF
581 # Make own hostname resolveable
582 own_hostname
583
d7190078
MT
584 # Install Safe Search rules when the system is already online
585 if [ -e "/var/ipfire/red/active" ]; then
586 update_safe_search
587 fi
588
36792be6
MT
589 # Update hosts
590 update_hosts
05478072 591
68fac98a 592 fix_time_if_dns_fail
b8f5eda8 593 ;;
d0e5f71f
ML
594
595 stop)
b8f5eda8
MT
596 boot_mesg "Stopping Unbound DNS Proxy..."
597 killproc /usr/sbin/unbound
598 ;;
d0e5f71f
ML
599
600 restart)
b8f5eda8
MT
601 $0 stop
602 sleep 1
603 $0 start
604 ;;
d0e5f71f
ML
605
606 status)
b8f5eda8 607 statusproc /usr/sbin/unbound
b8f5eda8
MT
608 ;;
609
610 update-forwarders)
4e2d3325 611 : # XXX must set ISP name servers if necessary
b8f5eda8 612 ;;
d0e5f71f 613
3ec3329d 614 remove-forwarders)
4e2d3325 615 : # XXX must remove ISP name servers
3ec3329d
AF
616 ;;
617
043e7aa5
MT
618 resolve)
619 resolve "${2}"
620 ;;
621
d7190078
MT
622 update-safe-search)
623 update_safe_search
624 ;;
625
d0e5f71f 626 *)
4e2d3325 627 echo "Usage: $0 {start|stop|restart|status|resolve|update-forwarders|remove-forwarders|update-safe-search}"
b8f5eda8
MT
628 exit 1
629 ;;
d0e5f71f
ML
630esac
631
632# End $rc_base/init.d/unbound