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