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