]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/initscripts/system/unbound
dnsforward.cgi: Reloading unbound is enough to apply changes
[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
6137797c
MT
61write_hosts_conf() {
62 (
63 config_header
f75c279b 64
6137797c
MT
65 # Make own hostname resolveable
66 # 1.1.1.1 is reserved for unused green, skip this
67 if [ -n "${GREEN_ADDRESS}" -a "${GREEN_ADDRESS}" != "1.1.1.1" ]; then
68 echo "local-data: \"${HOSTNAME} ${LOCAL_TTL} IN A ${GREEN_ADDRESS}\""
69 fi
f59bc0c5 70
6137797c
MT
71 local address
72 for address in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
73 [ -n "${address}" ] || continue
74 [ "${address}" = "1.1.1.1" ] && continue
36792be6 75
6137797c
MT
76 address=$(ip_address_revptr ${address})
77 echo "local-data: \"${address} ${LOCAL_TTL} IN PTR ${HOSTNAME}\""
78 done
36792be6 79
6137797c
MT
80 # Add all hosts
81 local enabled address hostname domainname generateptr
82 while IFS="," read -r enabled address hostname domainname generateptr; do
83 [ "${enabled}" = "on" ] || continue
36792be6 84
6137797c
MT
85 # Build FQDN
86 local fqdn="${hostname}.${domainname}"
87 echo "local-data: \"${fqdn} ${LOCAL_TTL} IN A ${address}\""
f75c279b 88
6137797c
MT
89 # Skip reverse resolution if the address equals the GREEN address
90 [ "${address}" = "${GREEN_ADDRESS}" ] && continue
868d2a1f 91
6137797c
MT
92 # Skip reverse resolution if user requested not to do so
93 [ "${generateptr}" = "off" ] && continue
6874a576 94
6137797c
MT
95 # Add RDNS
96 address=$(ip_address_revptr ${address})
97 echo "local-data: \"${address} ${LOCAL_TTL} IN PTR ${fqdn}\""
98 done < /var/ipfire/main/hosts
99 ) > /etc/unbound/hosts.conf
36792be6
MT
100}
101
b8f5eda8
MT
102write_forward_conf() {
103 (
104 config_header
105
beebf925
MT
106 # Enable strict QNAME minimisation
107 if [ "${QNAME_MIN}" = "strict" ]; then
108 echo "server:"
109 echo " qname-minimisation-strict: yes"
110 echo
111 fi
112
974d8653 113 # Force using TCP for upstream servers only
ee90aa98 114 if [ "${PROTO}" = "TCP" ]; then
974d8653
MT
115 echo "# Force using TCP for upstream servers only"
116 echo "server:"
117 echo " tcp-upstream: yes"
118 echo
119 fi
120
ee90aa98 121 local insecure_zones=""
a6dcc5bb 122
1ececb67
MT
123 local enabled zone server servers remark disable_dnssec rest
124 while IFS="," read -r enabled zone servers remark disable_dnssec rest; do
b8f5eda8
MT
125 # Line must be enabled.
126 [ "${enabled}" = "on" ] || continue
127
a6dcc5bb
MT
128 # Zones that end with .local are commonly used for internal
129 # zones and therefore not signed
130 case "${zone}" in
131 *.local)
132 insecure_zones="${insecure_zones} ${zone}"
133 ;;
1ececb67
MT
134 *)
135 if [ "${disable_dnssec}" = "on" ]; then
136 insecure_zones="${insecure_zones} ${zone}"
137 fi
138 ;;
a6dcc5bb
MT
139 esac
140
15cf79e3
MT
141 echo "stub-zone:"
142 echo " name: ${zone}"
143 for server in ${servers//|/ }; do
144 if [[ ${server} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
145 echo " stub-addr: ${server}"
146 else
147 echo " stub-host: ${server}"
148 fi
149 done
150 echo
151
152 # Make all reverse lookup zones transparent
c7e41255
MT
153 case "${zone}" in
154 *.in-addr.arpa)
c7e41255 155 echo "server:"
9f099932 156 echo " local-zone: \"${zone}\" transparent"
c7e41255
MT
157 echo
158 ;;
c7e41255 159 esac
b8f5eda8 160 done < /var/ipfire/dnsforward/config
a6dcc5bb
MT
161
162 if [ -n "${insecure_zones}" ]; then
163 echo "server:"
164
165 for zone in ${insecure_zones}; do
166 echo " domain-insecure: ${zone}"
167 done
168 fi
50005ad1
MT
169
170 echo "forward-zone:"
171 echo " name: \".\""
172
173 # Force using TLS only
ee90aa98 174 if [ "${PROTO}" = "TLS" ]; then
50005ad1
MT
175 echo " forward-tls-upstream: yes"
176 fi
177
178 # Add upstream name servers
2654c669
MT
179 local ns
180 for ns in $(read_name_servers); do
181 echo " forward-addr: ${ns}"
182 done
b8f5eda8
MT
183 ) > /etc/unbound/forward.conf
184}
185
b658a451
MT
186write_tuning_conf() {
187 # https://www.unbound.net/documentation/howto_optimise.html
188
189 # Determine number of online processors
190 local processors=$(getconf _NPROCESSORS_ONLN)
191
192 # Determine number of slabs
193 local slabs=1
194 while [ ${slabs} -lt ${processors} ]; do
195 slabs=$(( ${slabs} * 2 ))
196 done
197
198 # Determine amount of system memory
199 local mem=$(get_memory_amount)
200
201 # In the worst case scenario, unbound can use double the
202 # amount of memory allocated to a cache due to malloc overhead
203
4a0d69ca
MT
204 # Even larger systems with more than 8GB of RAM
205 if [ ${mem} -ge 8192 ]; then
206 mem=1024
207
208 # Extra large systems with more than 4GB of RAM
209 elif [ ${mem} -ge 4096 ]; then
210 mem=512
211
b658a451 212 # Large systems with more than 2GB of RAM
4a0d69ca 213 elif [ ${mem} -ge 2048 ]; then
128db1a3 214 mem=256
b658a451 215
4a0d69ca
MT
216 # Medium systems with more than 1GB of RAM
217 elif [ ${mem} -ge 1024 ]; then
218 mem=128
219
b658a451
MT
220 # Small systems with less than 256MB of RAM
221 elif [ ${mem} -le 256 ]; then
128db1a3 222 mem=16
b658a451
MT
223
224 # Everything else
225 else
128db1a3 226 mem=64
b658a451
MT
227 fi
228
229 (
230 config_header
231
232 # We run one thread per processor
233 echo "num-threads: ${processors}"
5012e53c 234 echo "so-reuseport: yes"
b658a451
MT
235
236 # Adjust number of slabs
237 echo "infra-cache-slabs: ${slabs}"
238 echo "key-cache-slabs: ${slabs}"
239 echo "msg-cache-slabs: ${slabs}"
240 echo "rrset-cache-slabs: ${slabs}"
241
242 # Slice up the cache
243 echo "rrset-cache-size: $(( ${mem} / 2 ))m"
244 echo "msg-cache-size: $(( ${mem} / 4 ))m"
245 echo "key-cache-size: $(( ${mem} / 4 ))m"
0a7dca2c
MT
246
247 # Increase parallel queries
248 echo "outgoing-range: 8192"
249 echo "num-queries-per-thread: 4096"
c20b2009
MT
250
251 # Use larger send/receive buffers
252 echo "so-sndbuf: 4m"
253 echo "so-rcvbuf: 4m"
b658a451
MT
254 ) > /etc/unbound/tuning.conf
255}
256
257get_memory_amount() {
258 local key val unit
259
260 while read -r key val unit; do
261 case "${key}" in
262 MemTotal:*)
263 # Convert to MB
264 echo "$(( ${val} / 1024 ))"
265 break
266 ;;
267 esac
268 done < /proc/meminfo
269}
b8f5eda8 270
a33489a7
MT
271fix_time_if_dns_fails() {
272 # If DNS is working, everything is fine
273 if resolve "ping.ipfire.org" &>/dev/null; then
274 return 0
68fac98a 275 fi
a33489a7
MT
276
277 # Try to sync time with a known time server
278 boot_mesg "DNS not functioning... Trying to sync time with ntp.ipfire.org (81.3.27.46)..."
279 loadproc /usr/local/bin/settime 81.3.27.46
68fac98a
AF
280}
281
043e7aa5
MT
282resolve() {
283 local hostname="${1}"
284
54898bc6
MT
285 local answer
286 for answer in $(dig +short A "${hostname}"); do
287 # Filter out non-IP addresses
288 if [[ ! "${answer}" =~ \.$ ]]; then
289 echo "${answer}"
290 fi
043e7aa5
MT
291 done
292}
293
2654c669 294update_forwarders() {
a32fd634 295 # Do nothing when we do not use the ISP name servers
2654c669
MT
296 [ "${USE_ISP_NAMESERVERS}" != "on" ] && return 0
297
a32fd634
MT
298 # We cannot update anything when using TLS
299 # Unbound will then try to connect to the servers using UDP on port 853
300 [ "${PROTO}" = "TLS" ] && return 0
301
2654c669
MT
302 # Update unbound about the new servers
303 local nameservers=( $(read_name_servers) )
304 if [ -n "${nameservers[*]}" ]; then
305 unbound-control -q forward "${nameservers[@]}"
306 else
307 unbound-control -q forward off
308 fi
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 # Update configuration files
b658a451 573 write_tuning_conf
6137797c 574 write_hosts_conf
b8f5eda8
MT
575 write_forward_conf
576
577 boot_mesg "Starting Unbound DNS Proxy..."
578 loadproc /usr/sbin/unbound || exit $?
579
d7190078
MT
580 # Install Safe Search rules when the system is already online
581 if [ -e "/var/ipfire/red/active" ]; then
582 update_safe_search
583 fi
b8f5eda8 584 ;;
d0e5f71f
ML
585
586 stop)
b8f5eda8
MT
587 boot_mesg "Stopping Unbound DNS Proxy..."
588 killproc /usr/sbin/unbound
589 ;;
d0e5f71f
ML
590
591 restart)
b8f5eda8
MT
592 $0 stop
593 sleep 1
594 $0 start
595 ;;
0c109477
SS
596 reload)
597 # Update configuration files
0c109477 598 write_forward_conf
6137797c 599 write_hosts_conf
0c109477
SS
600
601 # Update Safe Search rules if the system is online.
602 if [ -e "/var/ipfire/red/active" ]; then
603 update_safe_search
604 fi
605
0c109477
SS
606 # Call unbound-control and perform the reload
607 /usr/sbin/unbound-control -q reload
608 ;;
d0e5f71f
ML
609
610 status)
b8f5eda8 611 statusproc /usr/sbin/unbound
b8f5eda8
MT
612 ;;
613
614 update-forwarders)
2654c669 615 update_forwarders
54898bc6 616
a33489a7
MT
617 # Make sure DNS works at this point
618 fix_time_if_dns_fails
619
54898bc6
MT
620 # Update Safe Search settings
621 update_safe_search
b8f5eda8 622 ;;
d0e5f71f 623
3ec3329d 624 remove-forwarders)
2654c669 625 update_forwarders
3ec3329d
AF
626 ;;
627
043e7aa5
MT
628 resolve)
629 resolve "${2}"
630 ;;
631
d7190078
MT
632 update-safe-search)
633 update_safe_search
634 ;;
635
d0e5f71f 636 *)
0c109477 637 echo "Usage: $0 {start|stop|restart|reload|status|resolve|update-forwarders|remove-forwarders|update-safe-search}"
b8f5eda8
MT
638 exit 1
639 ;;
d0e5f71f
ML
640esac
641
642# End $rc_base/init.d/unbound