summaryrefslogtreecommitdiffstats
path: root/etc/config
diff options
context:
space:
mode:
Diffstat (limited to 'etc/config')
-rw-r--r--etc/config/config.cluster36
-rw-r--r--etc/config/config.docker97
-rw-r--r--etc/config/config.internal18
-rw-r--r--etc/config/config.isp64
-rw-r--r--etc/config/config.personal21
-rw-r--r--etc/config/config.privacy36
-rw-r--r--etc/config/config.splitview30
-rw-r--r--etc/config/meson.build35
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