diff options
Diffstat (limited to 'etc/config')
-rw-r--r-- | etc/config/config.cluster | 36 | ||||
-rw-r--r-- | etc/config/config.docker | 97 | ||||
-rw-r--r-- | etc/config/config.internal | 18 | ||||
-rw-r--r-- | etc/config/config.isp | 64 | ||||
-rw-r--r-- | etc/config/config.personal | 21 | ||||
-rw-r--r-- | etc/config/config.privacy | 36 | ||||
-rw-r--r-- | etc/config/config.splitview | 30 | ||||
-rw-r--r-- | etc/config/meson.build | 35 |
8 files changed, 337 insertions, 0 deletions
diff --git a/etc/config/config.cluster b/etc/config/config.cluster new file mode 100644 index 0000000..3bd12dd --- /dev/null +++ b/etc/config/config.cluster @@ -0,0 +1,36 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Config file example useable for larger resolver farms +-- In this case cache should be made as large as possible, and prefetching turned off +-- as the resolver is busy most of the time. +-- Alternative is using `etcd` as a configuration backend. +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('::1', 53, { kind = 'dns'}) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +net.listen('::1', 853, { kind = 'tls' }) +net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 443, { kind = 'doh2'}) + +-- Refer to manual for optimal cache size +cache.size = 16 * GB + +-- Load Useful modules +modules = { + 'hints > iterate', -- Allow loading /etc/hosts or custom root hints + 'stats', -- Track internal statistics + graphite = { -- Send statistics to local InfluxDB + -- Address of the Graphite/InfluxDB server + host = '192.168.1.2', + }, +} + +-- Use local root server copy for performance reasons +hints.root({ + ['j.root-servers.net.'] = { '192.168.1.4', '2001:503:c27::2:30', '192.58.128.30' } +}) + +-- Apply RPZ for all clients, default rule is DENY +policy.add(policy.rpz(policy.DENY, 'blacklist.rpz')) diff --git a/etc/config/config.docker b/etc/config/config.docker new file mode 100644 index 0000000..f631a54 --- /dev/null +++ b/etc/config/config.docker @@ -0,0 +1,97 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ +print('Knot Resolver ' .. package_version()) + +-- Smaller cache size +cache.size = 10 * MB + +local ffi = require('ffi') + +function interactive_mode() + -- Listen on all interfaces (localhost would not work in Docker) + net.listen('0.0.0.0', 53, { kind = 'dns' }) + net.listen('0.0.0.0', 853, { kind = 'tls' }) + net.listen('0.0.0.0', 443, { kind = 'doh2' }) + net.listen('0.0.0.0', 8453, { kind = 'webmgmt' }) + + -- Load Useful modules + modules = { + 'stats', -- Track internal statistics + 'http', + } + + function print_help() + print('\nUsage\n' + .. '=====\n' + .. 'Run this container using command:\n' + .. '$ docker run -Pti cznic/knot-resolver\n' + .. '\n' + .. 'Docker will map ports 53, 443, 853, and 8453 to some other numbers, see\n' + .. '$ docker ps\n' + .. '(column PORTS)\n' + .. '53 -> DNS protocol over UDP and TCP\n' + .. '443 -> DNS-over-HTTPS protocol\n' + .. '853 -> DNS-over-TLS protocol\n' + .. '8453 -> web interface\n' + .. '\n' + .. 'For verbose logging enter following command to prompt below:\n' + .. 'log_level("debug")\n') + end + print_help() +end + +function debug_mode(qname, qtype) + event.after(20*sec, function() + print('ERROR: timeout which cannot happen actually happened, exiting') + os.exit(1) + end) + env.KRESD_NO_LISTEN = 1 + + -- limit noise in verbose logs + modules.unload('detect_time_skew') + modules.unload('priming') + modules.unload('ta_signal_query') + modules.unload('ta_update') + + -- always empty cache so this config works reliably outside Docker + cache.clear() + + local cqueues = require('cqueues') + + -- execute query right after start up and exit when the query is finished + event.after(0, function() + log_level('info') + policy.add(policy.all(policy.DEBUG_ALWAYS)) + log_info(ffi.C.LOG_GRP_RESOLVER, 'starting DNS query for %s %s', qname, kres.tostring.type[qtype]) + local starttime = cqueues.monotime() + resolve({ + name = qname, + type = qtype, + options = {'DNSSEC_WANT'}, + finish = function(pkt) + -- delay exit after packet is finished + -- to prevent us from losing policy.DEBUG finish callback + event.after(1, -- millisecond + function() + local endtime = cqueues.monotime() + log_info(ffi.C.LOG_GRP_RESOLVER, 'request finished in %f ms', (endtime - starttime) * 1000) + os.exit() + end) + end + }) + end) +end + +local qname = os.getenv('QNAME') +local qtype = os.getenv('QTYPE') +if qname and qtype then + qtypenum = kres.type[qtype] + if not qtypenum then + log_error(ffi.C.LOG_GRP_RESOLVER, 'ERROR: unsupported query type "%s", use TYPE12345 notation', qtype) + os.exit() + end + debug_mode(qname, qtypenum) +else + interactive_mode() +end diff --git a/etc/config/config.internal b/etc/config/config.internal new file mode 100644 index 0000000..46bbf17 --- /dev/null +++ b/etc/config/config.internal @@ -0,0 +1,18 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Config file example usable for multi-user ISP resolver +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('::1', 53, { kind = 'dns'}) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +net.listen('::1', 853, { kind = 'tls' }) +net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 443, { kind = 'doh2' }) + +-- define list of internal-only domains +internalDomains = policy.todnames({'company.example', 'internal.example'}) + +-- forward all queries below 'internalDomains' to '192.168.1.2' +policy.add(policy.suffix(policy.FORWARD({'192.168.1.2'}), internalDomains)) diff --git a/etc/config/config.isp b/etc/config/config.isp new file mode 100644 index 0000000..d4e2f9a --- /dev/null +++ b/etc/config/config.isp @@ -0,0 +1,64 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Config file example usable for ISP resolver +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('::1', 53, { kind = 'dns'}) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +net.listen('::1', 853, { kind = 'tls' }) +net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 443, { kind = 'doh2' }) + +-- Refer to manual for optimal cache size +cache.size = 4 * GB + +-- load modules +modules = { + 'view', + 'stats' +} + +local ffi = require('ffi') + +-- log statistics every second +local stat_id = event.recurrent(1 * second, function(evid) + log_info(ffi.C.LOG_GRP_STATISTICS, table_print(stats.list())) +end) + +-- stop printing statistics after first minute +event.after(1 * minute, function(evid) + event.cancel(stat_id) +end) + +-- speed_monitor definition +-- prints warning if more than 5% of total answers was slow +function speed_monitor() + local previous = stats.list() -- store statistics in persistent variable + return function(evid) + local now = stats.list() -- save actual statistics to variable + -- number of total answers between 'now' and 'previous' states + local total_increment = now['answer.total'] - previous['answer.total'] + -- number of slow answers between 'now' and 'previous' states + local slow_increment = now['answer.slow'] - previous['answer.slow'] + -- if percentage of slow answers is bigger than 5%, print warning + if slow_increment / total_increment > 0.05 then + log_warn(ffi.C.LOG_GRP_STATISTICS, 'WARNING! More than 5 %% of queries was slow!') + end + previous = now + end +end + +-- execute speed_monitor every minute +local monitor_id = event.recurrent(1 * minute, speed_monitor()) + +-- apply RPZ for all clients, default rule is DENY +policy.add(policy.rpz(policy.DENY, 'blacklist.rpz')) + +-- whitelist queries identified by subnet +view:addr(''192.168.1.0/24'', policy.all(policy.PASS)) + +-- drop everything that hasn't matched +view:addr('0.0.0.0/0', policy.all(policy.DROP)) + diff --git a/etc/config/config.personal b/etc/config/config.personal new file mode 100644 index 0000000..961a2f6 --- /dev/null +++ b/etc/config/config.personal @@ -0,0 +1,21 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Refer to manual: https://knot-resolver.readthedocs.org/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +--net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 53, { kind = 'dns', freebind = true }) +net.listen('::1', 853, { kind = 'tls', freebind = true }) +--net.listen('::1', 443, { kind = 'doh2' }) + +-- Load useful modules +modules = { + 'hints > iterate', -- Allow loading /etc/hosts or custom root hints + 'stats', -- Track internal statistics + 'predict', -- Prefetch expiring/frequent records +} + +-- Cache size +cache.size = 100 * MB diff --git a/etc/config/config.privacy b/etc/config/config.privacy new file mode 100644 index 0000000..6c14d74 --- /dev/null +++ b/etc/config/config.privacy @@ -0,0 +1,36 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Config file example usable for privacy-preserving resolver +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('::1', 53, { kind = 'dns'}) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +net.listen('::1', 853, { kind = 'tls' }) +net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 443, { kind = 'doh2' }) + +-- TLS server configuration +-- use this to configure your TLS certificates +-- net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem") + +-- Refer to manual if you would like to use non-persistent cache + +-- forwarding to multiple targets +-- splits the entire DNS namespace into distinct slices +policy.add(policy.slice( + -- slicing function + policy.slice_randomize_psl(), + -- forward over TLS + policy.TLS_FORWARD({ + {'2001:DB8::d0c', hostname='res.example.com'}, + {'192.0.2.1', pin_sha256={'YQ=='}}, + }), + policy.TLS_FORWARD({ + -- multiple servers can be specified for a single slice + -- the one with lowest round-trip time will be used + {'193.17.47.1', hostname='odvr.nic.cz'}, + {'185.43.135.1', hostname='odvr.nic.cz'}, + }) +)) diff --git a/etc/config/config.splitview b/etc/config/config.splitview new file mode 100644 index 0000000..a8a9344 --- /dev/null +++ b/etc/config/config.splitview @@ -0,0 +1,30 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- vim:syntax=lua:set ts=4 sw=4: +-- Config file with split-view for internal zone +-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/ + +-- Network interface configuration +net.listen('127.0.0.1', 53, { kind = 'dns' }) +net.listen('::1', 53, { kind = 'dns'}) +net.listen('127.0.0.1', 853, { kind = 'tls' }) +net.listen('::1', 853, { kind = 'tls' }) +net.listen('127.0.0.1', 443, { kind = 'doh2' }) +net.listen('::1', 443, { kind = 'doh2' }) + +-- Load Useful modules +modules = { + 'hints > iterate', -- Allow loading /etc/hosts or custom root hints + 'stats', -- Track internal statistics + graphite = { -- Send statistics to local InfluxDB + -- Address of the Graphite/InfluxDB server + host = '192.168.1.2', + }, + -- Use DNS64 with specified NAT64 address + dns64 = 'fe80::21b:77ff:0:0', +} + +-- Refer to manual for optimal cache size +cache.size = 4 * GB + +-- Forward everything below `company.cz` to `192.168.1.3` +policy.add(policy.suffix(policy.FORWARD('192.168.1.3'), {todname('company.cz')})) diff --git a/etc/config/meson.build b/etc/config/meson.build new file mode 100644 index 0000000..ca88808 --- /dev/null +++ b/etc/config/meson.build @@ -0,0 +1,35 @@ +# etc: config examples +# SPDX-License-Identifier: GPL-3.0-or-later + +# Install config examples +example_configs = [ + 'config.cluster', + 'config.docker', + 'config.isp', + 'config.internal', + 'config.privacy', + 'config.personal', + 'config.splitview', +] + +install_data( + sources: example_configs, + install_dir: examples_dir, +) + + +# kresd.conf +install_kresd_conf = get_option('install_kresd_conf') == 'enabled' +if get_option('install_kresd_conf') == 'auto' + if run_command(['test', '-r', etc_dir / 'kresd.conf'], check: false).returncode() == 1 + install_kresd_conf = true + endif +endif + +if install_kresd_conf + install_data( + sources: 'config.personal', + rename: 'kresd.conf', + install_dir: etc_dir, + ) +endif |