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