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