summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
Diffstat (limited to 'etc')
-rw-r--r--etc/config/config.cluster36
-rw-r--r--etc/config/config.docker96
-rw-r--r--etc/config/config.internal18
-rw-r--r--etc/config/config.isp62
-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
-rw-r--r--etc/icann-ca.pem82
-rw-r--r--etc/meson.build37
-rw-r--r--etc/root.hints92
-rw-r--r--etc/root.keys1
12 files changed, 546 insertions, 0 deletions
diff --git a/etc/config/config.cluster b/etc/config/config.cluster
new file mode 100644
index 0000000..dd10a74
--- /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', -- Load /etc/hosts and allow 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..f036fd5
--- /dev/null
+++ b/etc/config/config.docker
@@ -0,0 +1,96 @@
+-- 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
+
+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'
+ .. 'verbose(true)\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()
+ -- ultra verbose log
+ verbose(true)
+ policy.add(policy.all(policy.DEBUG_ALWAYS))
+ log('INFO: 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, -- milisecond
+ function()
+ local endtime = cqueues.monotime()
+ log('\nrequest 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: 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..3dc3e7f
--- /dev/null
+++ b/etc/config/config.isp
@@ -0,0 +1,62 @@
+-- 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'
+}
+
+-- log statistics every second
+local stat_id = event.recurrent(1 * second, function(evid)
+ log(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('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..e6803a1
--- /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', -- Load /etc/hosts and allow 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..d36f3a2
--- /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..1054af5
--- /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', -- Load /etc/hosts and allow 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..a4a9c50
--- /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']).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
diff --git a/etc/icann-ca.pem b/etc/icann-ca.pem
new file mode 100644
index 0000000..0ae28d6
--- /dev/null
+++ b/etc/icann-ca.pem
@@ -0,0 +1,82 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Validity
+ Not Before: Nov 10 00:00:00 2006 GMT
+ Not After : Nov 10 00:00:00 2031 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (2048 bit)
+ Modulus (2048 bit):
+ 00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2:
+ 8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20:
+ cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d:
+ e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf:
+ df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f:
+ 7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c:
+ 39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7:
+ 74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e:
+ c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9:
+ a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27:
+ 6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf:
+ a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37:
+ 91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3:
+ 14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42:
+ d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58:
+ 3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16:
+ f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3:
+ af:27
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+ X509v3 Authority Key Identifier:
+ keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+
+ Signature Algorithm: sha1WithRSAEncryption
+ cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae:
+ 04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe:
+ f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70:
+ a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff:
+ 63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e:
+ 63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5:
+ ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e:
+ 79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac:
+ e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53:
+ cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78:
+ 3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2:
+ 91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df:
+ 47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9:
+ f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5:
+ 95:95:6d:de
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/etc/meson.build b/etc/meson.build
new file mode 100644
index 0000000..31859ba
--- /dev/null
+++ b/etc/meson.build
@@ -0,0 +1,37 @@
+# etc
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+etc_files = []
+
+if install_root_hints
+ etc_files += 'root.hints'
+endif
+
+if managed_ta
+ etc_files += 'icann-ca.pem'
+endif
+
+if install_root_keys
+ root_keys_path = keyfile_default.split('/')
+ root_keys_filename = root_keys_path[-1]
+ root_keys_dir = []
+ foreach el : root_keys_path
+ if el != root_keys_filename
+ root_keys_dir += el
+ endif
+ endforeach
+ install_data(
+ sources: 'root.keys',
+ rename: root_keys_filename,
+ install_dir: '/'.join(root_keys_dir)
+ )
+endif
+
+
+subdir('config')
+
+
+install_data(
+ sources: etc_files,
+ install_dir: etc_dir
+)
diff --git a/etc/root.hints b/etc/root.hints
new file mode 100644
index 0000000..e4d8d99
--- /dev/null
+++ b/etc/root.hints
@@ -0,0 +1,92 @@
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+; (e.g. reference this file in the "cache . <file>"
+; configuration file of BIND domain name servers).
+;
+; This file is made available by InterNIC
+; under anonymous FTP as
+; file /domain/named.cache
+; on server FTP.INTERNIC.NET
+; -OR- RS.INTERNIC.NET
+;
+; last update: October 24, 2017
+; related version of root zone: 2017102400
+;
+; FORMERLY NS.INTERNIC.NET
+;
+. 3600000 NS A.ROOT-SERVERS.NET.
+A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
+A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
+;
+; FORMERLY NS1.ISI.EDU
+;
+. 3600000 NS B.ROOT-SERVERS.NET.
+B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201
+B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b
+;
+; FORMERLY C.PSI.NET
+;
+. 3600000 NS C.ROOT-SERVERS.NET.
+C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
+C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c
+;
+; FORMERLY TERP.UMD.EDU
+;
+. 3600000 NS D.ROOT-SERVERS.NET.
+D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13
+D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d
+;
+; FORMERLY NS.NASA.GOV
+;
+. 3600000 NS E.ROOT-SERVERS.NET.
+E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
+E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e
+;
+; FORMERLY NS.ISC.ORG
+;
+. 3600000 NS F.ROOT-SERVERS.NET.
+F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
+F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f
+;
+; FORMERLY NS.NIC.DDN.MIL
+;
+. 3600000 NS G.ROOT-SERVERS.NET.
+G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
+G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d
+;
+; FORMERLY AOS.ARL.ARMY.MIL
+;
+. 3600000 NS H.ROOT-SERVERS.NET.
+H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53
+H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53
+;
+; FORMERLY NIC.NORDU.NET
+;
+. 3600000 NS I.ROOT-SERVERS.NET.
+I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
+I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53
+;
+; OPERATED BY VERISIGN, INC.
+;
+. 3600000 NS J.ROOT-SERVERS.NET.
+J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30
+J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30
+;
+; OPERATED BY RIPE NCC
+;
+. 3600000 NS K.ROOT-SERVERS.NET.
+K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129
+K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1
+;
+; OPERATED BY ICANN
+;
+. 3600000 NS L.ROOT-SERVERS.NET.
+L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42
+L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42
+;
+; OPERATED BY WIDE
+;
+. 3600000 NS M.ROOT-SERVERS.NET.
+M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33
+M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35
+; End of file \ No newline at end of file
diff --git a/etc/root.keys b/etc/root.keys
new file mode 100644
index 0000000..e292b5a
--- /dev/null
+++ b/etc/root.keys
@@ -0,0 +1 @@
+. IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D