]> git.ipfire.org Git - ipfire-2.x.git/blame - src/initscripts/system/unbound
suricata: Change midstream policy to "pass-flow"
[ipfire-2.x.git] / src / initscripts / system / unbound
CommitLineData
d0e5f71f 1#!/bin/sh
66c36198
PM
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
d0e5f71f
ML
21
22. /etc/sysconfig/rc
23. ${rc_functions}
24
36792be6
MT
25# Cache any local zones for 60 seconds
26LOCAL_TTL=60
27
ee90aa98
MT
28# Load configuration
29eval $(/usr/local/bin/readhash /var/ipfire/dns/settings)
4b26aac6 30eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
d0e5f71f 31
f75c279b
AF
32ip_address_revptr() {
33 local addr=${1}
34
35 local a1 a2 a3 a4
36 IFS=. read -r a1 a2 a3 a4 <<< ${addr}
37
38 echo "${a4}.${a3}.${a2}.${a1}.in-addr.arpa"
39}
40
b8f5eda8 41read_name_servers() {
2654c669
MT
42 # Read name servers from ISP
43 if [ "${USE_ISP_NAMESERVERS}" = "on" -a "${PROTO}" != "TLS" ]; then
44 local i
45 for i in 1 2; do
46 echo "$(</var/run/dns${i})"
47 done 2>/dev/null
48 fi
49
50 # Read configured name servers
51 local id address tls_hostname enabled remark
52 while IFS="," read -r id address tls_hostname enabled remark; do
53 [ "${enabled}" != "enabled" ] && continue
54
55 if [ "${PROTO}" = "TLS" ]; then
56 if [ -n "${tls_hostname}" ]; then
57 echo "${address}@853#${tls_hostname}"
58 fi
59 else
60 echo "${address}"
61 fi
62 done < /var/ipfire/dns/servers
b8f5eda8
MT
63}
64
65config_header() {
66 echo "# This file is automatically generated and any changes"
67 echo "# will be overwritten. DO NOT EDIT!"
68 echo
69}
70
6137797c
MT
71write_hosts_conf() {
72 (
73 config_header
f75c279b 74
6137797c
MT
75 # Make own hostname resolveable
76 # 1.1.1.1 is reserved for unused green, skip this
77 if [ -n "${GREEN_ADDRESS}" -a "${GREEN_ADDRESS}" != "1.1.1.1" ]; then
78 echo "local-data: \"${HOSTNAME} ${LOCAL_TTL} IN A ${GREEN_ADDRESS}\""
79 fi
f59bc0c5 80
6137797c
MT
81 local address
82 for address in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
83 [ -n "${address}" ] || continue
84 [ "${address}" = "1.1.1.1" ] && continue
36792be6 85
6137797c
MT
86 address=$(ip_address_revptr ${address})
87 echo "local-data: \"${address} ${LOCAL_TTL} IN PTR ${HOSTNAME}\""
88 done
36792be6 89
6137797c 90 local enabled address hostname domainname generateptr
1b6b8d97
MT
91
92 # Find all unique domain names
93 while IFS="," read -r enabled address hostname domainname generateptr; do
94 [ "${enabled}" = "on" ] || continue
95
5947f92a
MT
96 # Skip empty domainnames
97 [ "${domainname}" = "" ] && continue
98
2b113aeb 99 echo "local-zone: ${domainname} transparent"
5947f92a 100 done < /var/ipfire/main/hosts | sort -u
1b6b8d97
MT
101
102 # Add all hosts
6137797c
MT
103 while IFS="," read -r enabled address hostname domainname generateptr; do
104 [ "${enabled}" = "on" ] || continue
36792be6 105
6137797c
MT
106 # Build FQDN
107 local fqdn="${hostname}.${domainname}"
108 echo "local-data: \"${fqdn} ${LOCAL_TTL} IN A ${address}\""
f75c279b 109
6137797c
MT
110 # Skip reverse resolution if the address equals the GREEN address
111 [ "${address}" = "${GREEN_ADDRESS}" ] && continue
868d2a1f 112
6137797c
MT
113 # Skip reverse resolution if user requested not to do so
114 [ "${generateptr}" = "off" ] && continue
6874a576 115
6137797c
MT
116 # Add RDNS
117 address=$(ip_address_revptr ${address})
118 echo "local-data: \"${address} ${LOCAL_TTL} IN PTR ${fqdn}\""
119 done < /var/ipfire/main/hosts
120 ) > /etc/unbound/hosts.conf
36792be6
MT
121}
122
b8f5eda8
MT
123write_forward_conf() {
124 (
125 config_header
126
beebf925
MT
127 # Enable strict QNAME minimisation
128 if [ "${QNAME_MIN}" = "strict" ]; then
129 echo "server:"
130 echo " qname-minimisation-strict: yes"
131 echo
132 fi
133
974d8653 134 # Force using TCP for upstream servers only
ee90aa98 135 if [ "${PROTO}" = "TCP" ]; then
974d8653
MT
136 echo "# Force using TCP for upstream servers only"
137 echo "server:"
138 echo " tcp-upstream: yes"
139 echo
140 fi
141
ee90aa98 142 local insecure_zones=""
a6dcc5bb 143
1ececb67
MT
144 local enabled zone server servers remark disable_dnssec rest
145 while IFS="," read -r enabled zone servers remark disable_dnssec rest; do
b8f5eda8
MT
146 # Line must be enabled.
147 [ "${enabled}" = "on" ] || continue
148
a6dcc5bb
MT
149 # Zones that end with .local are commonly used for internal
150 # zones and therefore not signed
151 case "${zone}" in
152 *.local)
153 insecure_zones="${insecure_zones} ${zone}"
154 ;;
1ececb67
MT
155 *)
156 if [ "${disable_dnssec}" = "on" ]; then
157 insecure_zones="${insecure_zones} ${zone}"
158 fi
159 ;;
a6dcc5bb
MT
160 esac
161
15cf79e3
MT
162 echo "stub-zone:"
163 echo " name: ${zone}"
164 for server in ${servers//|/ }; do
165 if [[ ${server} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
166 echo " stub-addr: ${server}"
167 else
168 echo " stub-host: ${server}"
169 fi
170 done
171 echo
172
173 # Make all reverse lookup zones transparent
c7e41255
MT
174 case "${zone}" in
175 *.in-addr.arpa)
c7e41255 176 echo "server:"
9f099932 177 echo " local-zone: \"${zone}\" transparent"
c7e41255
MT
178 echo
179 ;;
c7e41255 180 esac
b8f5eda8 181 done < /var/ipfire/dnsforward/config
a6dcc5bb
MT
182
183 if [ -n "${insecure_zones}" ]; then
184 echo "server:"
185
186 for zone in ${insecure_zones}; do
187 echo " domain-insecure: ${zone}"
188 done
189 fi
50005ad1 190
ab4ef40f
SS
191 # Read name servers.
192 nameservers=$(read_name_servers)
50005ad1 193
ab4ef40f
SS
194 # Only write forward zones if any nameservers are configured.
195 #
196 # Otherwise fall-back into recursor mode.
197 if [ -n "${nameservers}" ]; then
198
199 echo "forward-zone:"
200 echo " name: \".\""
201
202 # Force using TLS only
203 if [ "${PROTO}" = "TLS" ]; then
204 echo " forward-tls-upstream: yes"
205 fi
206
207 # Add upstream name servers
208 local ns
209 for ns in ${nameservers}; do
210 echo " forward-addr: ${ns}"
211 done
50005ad1
MT
212 fi
213
b8f5eda8
MT
214 ) > /etc/unbound/forward.conf
215}
216
b658a451
MT
217write_tuning_conf() {
218 # https://www.unbound.net/documentation/howto_optimise.html
219
b658a451
MT
220 # Determine amount of system memory
221 local mem=$(get_memory_amount)
222
223 # In the worst case scenario, unbound can use double the
224 # amount of memory allocated to a cache due to malloc overhead
225
4a0d69ca
MT
226 # Even larger systems with more than 8GB of RAM
227 if [ ${mem} -ge 8192 ]; then
228 mem=1024
229
230 # Extra large systems with more than 4GB of RAM
231 elif [ ${mem} -ge 4096 ]; then
232 mem=512
233
b658a451 234 # Large systems with more than 2GB of RAM
4a0d69ca 235 elif [ ${mem} -ge 2048 ]; then
128db1a3 236 mem=256
b658a451 237
4a0d69ca
MT
238 # Medium systems with more than 1GB of RAM
239 elif [ ${mem} -ge 1024 ]; then
240 mem=128
241
b658a451
MT
242 # Small systems with less than 256MB of RAM
243 elif [ ${mem} -le 256 ]; then
128db1a3 244 mem=16
b658a451
MT
245
246 # Everything else
247 else
128db1a3 248 mem=64
b658a451
MT
249 fi
250
251 (
252 config_header
253
b658a451
MT
254 # Slice up the cache
255 echo "rrset-cache-size: $(( ${mem} / 2 ))m"
256 echo "msg-cache-size: $(( ${mem} / 4 ))m"
257 echo "key-cache-size: $(( ${mem} / 4 ))m"
0a7dca2c
MT
258
259 # Increase parallel queries
260 echo "outgoing-range: 8192"
261 echo "num-queries-per-thread: 4096"
c20b2009
MT
262
263 # Use larger send/receive buffers
264 echo "so-sndbuf: 4m"
265 echo "so-rcvbuf: 4m"
b658a451
MT
266 ) > /etc/unbound/tuning.conf
267}
268
269get_memory_amount() {
270 local key val unit
271
272 while read -r key val unit; do
273 case "${key}" in
274 MemTotal:*)
275 # Convert to MB
276 echo "$(( ${val} / 1024 ))"
277 break
278 ;;
279 esac
280 done < /proc/meminfo
281}
b8f5eda8 282
a33489a7
MT
283fix_time_if_dns_fails() {
284 # If DNS is working, everything is fine
2ecb2784
AF
285 if resolve "0.ipfire.pool.ntp.org" &>/dev/null || \
286 resolve "1.ipfire.pool.ntp.org" &>/dev/null ; then
a33489a7 287 return 0
68fac98a 288 fi
a33489a7
MT
289
290 # Try to sync time with a known time server
935da8b7 291 boot_mesg "DNS not functioning... Trying to sync time with time.ipfire.org (81.3.27.46)..."
a33489a7 292 loadproc /usr/local/bin/settime 81.3.27.46
68fac98a
AF
293}
294
043e7aa5
MT
295resolve() {
296 local hostname="${1}"
f5fe5f47 297 local found=1
043e7aa5 298
54898bc6
MT
299 local answer
300 for answer in $(dig +short A "${hostname}"); do
301 # Filter out non-IP addresses
302 if [[ ! "${answer}" =~ \.$ ]]; then
f5fe5f47 303 found=0
54898bc6
MT
304 echo "${answer}"
305 fi
043e7aa5 306 done
f5fe5f47
AF
307
308 return ${found}
043e7aa5
MT
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
65ef52a3
MT
521 if [ "${ENABLE_SAFE_SEARCH}" = "on" ]; then
522 # Bing
523 unbound-control bing.com transparent >/dev/null
524 for address in $(resolve "strict.bing.com"); do
525 unbound-control local_data "www.bing.com ${LOCAL_TTL} IN A ${address}"
d7190078 526 done >/dev/null
661ab153 527
65ef52a3
MT
528 # DuckDuckGo
529 unbound-control local_zone duckduckgo.com typetransparent >/dev/null
530 for address in $(resolve "safe.duckduckgo.com"); do
531 unbound-control local_data "duckduckgo.com ${LOCAL_TTL} IN A ${address}"
d7190078 532 done >/dev/null
661ab153 533
65ef52a3
MT
534 # Google
535 local addresses="$(resolve "forcesafesearch.google.com")"
536 for domain in ${google_tlds[@]}; do
537 unbound-control local_zone "${domain}" transparent >/dev/null
538 for address in ${addresses}; do
539 unbound-control local_data "www.${domain} ${LOCAL_TTL} IN A ${address}"
540 done >/dev/null
541 done
542
543 # Yandex
544 for domain in yandex.com yandex.ru; do
545 unbound-control local_zone "${domain}" typetransparent >/dev/null
546 for address in $(resolve "familysearch.${domain}"); do
547 unbound-control local_data "${domain} ${LOCAL_TTL} IN A ${address}"
548 done >/dev/null
549 done
550
551 # YouTube
552 if [ "${ENABLE_SAFE_SEARCH_YOUTUBE}" = "on" ]; then
553 unbound-control local_zone youtube.com transparent >/dev/null
554 for address in $(resolve "restrictmoderate.youtube.com"); do
555 unbound-control local_data "www.youtube.com ${LOCAL_TTL} IN A ${address}"
556 done >/dev/null
557 fi
558 fi
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
6137797c 573 write_hosts_conf
b8f5eda8
MT
574 write_forward_conf
575
576 boot_mesg "Starting Unbound DNS Proxy..."
577 loadproc /usr/sbin/unbound || exit $?
578
d7190078
MT
579 # Install Safe Search rules when the system is already online
580 if [ -e "/var/ipfire/red/active" ]; then
581 update_safe_search
582 fi
b8f5eda8 583 ;;
d0e5f71f
ML
584
585 stop)
b8f5eda8
MT
586 boot_mesg "Stopping Unbound DNS Proxy..."
587 killproc /usr/sbin/unbound
588 ;;
d0e5f71f
ML
589
590 restart)
b8f5eda8
MT
591 $0 stop
592 sleep 1
593 $0 start
594 ;;
3b5131c1 595 reload|update-forwarders)
0c109477 596 # Update configuration files
0c109477 597 write_forward_conf
6137797c 598 write_hosts_conf
0c109477 599
60557503
AF
600 # Call unbound-control and perform the reload
601 /usr/sbin/unbound-control -q reload
602
d98bbcc8
AF
603 # Dummy Resolve to wait for unbound
604 resolve "ping.ipfire.org" &>/dev/null
605
606 if [ "$1" = "update-forwarders" ]; then
607 # Make sure DNS works at this point
608 fix_time_if_dns_fails
609 fi
610
0c109477
SS
611 # Update Safe Search rules if the system is online.
612 if [ -e "/var/ipfire/red/active" ]; then
613 update_safe_search
614 fi
0c109477 615 ;;
d0e5f71f
ML
616
617 status)
b8f5eda8 618 statusproc /usr/sbin/unbound
b8f5eda8
MT
619 ;;
620
043e7aa5 621 resolve)
f5fe5f47 622 resolve "${2}" || exit $?
043e7aa5
MT
623 ;;
624
d0e5f71f 625 *)
3b5131c1 626 echo "Usage: $0 {start|stop|restart|reload|status|resolve|update-forwarders}"
b8f5eda8
MT
627 exit 1
628 ;;
d0e5f71f 629esac