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