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