Skip to content
Snippets Groups Projects
Verified Commit fa3ba9f6 authored by Vladimír Čunát's avatar Vladimír Čunát
Browse files

Merge branch 'master' into cache-aggr-wip

parents 32825801 8adcd8b1
Branches
Tags
1 merge request!422Aggressive use of cache DNSSEC-validated cache
......@@ -99,6 +99,20 @@ installcheck:linux:amd64:
- linux
- amd64
doc:
stage: test
script:
- SPHINXFLAGS="-W" make doc
dependencies: []
artifacts:
expire_in: 1 hour
paths:
- ./doc/*
tags:
- docker
deckard:linux:amd64:
stage: test
script:
......@@ -184,6 +198,7 @@ respdiff:iter:udp:linux:amd64:
expire_in: '1 week'
paths:
- results/*.txt
- results/respdiff.db/data.mdb.xz
- ./*.info
tags:
- docker
......@@ -208,6 +223,7 @@ respdiff:iter:tcp:linux:amd64:
expire_in: '1 week'
paths:
- results/*.txt
- results/respdiff.db/data.mdb.xz
- ./*.info
tags:
- docker
......@@ -232,6 +248,7 @@ respdiff:iter:tls:linux:amd64:
expire_in: '1 week'
paths:
- results/*.txt
- results/respdiff.db/data.mdb.xz
- ./*.info
tags:
- docker
......
......@@ -10,6 +10,8 @@ RUN apt-get upgrade -y -qqq
# Knot and Knot Resolver dependecies
RUN apt-get install -y -qqq make cmake pkg-config git build-essential bsdmainutils libtool autoconf make pkg-config liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev libidn11-dev protobuf-c-compiler libfstrm-dev pkg-config libuv1-dev libcmocka-dev libluajit-5.1-dev lua-sec lua-socket lua-http
# documentation dependecies
RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
# Python packags required for Deckard CI
# Python: grab latest versions from PyPi
......@@ -46,6 +48,7 @@ RUN apt-get install luarocks -y -qqq
RUN luarocks install luacheck
# respdiff for kresd CI
RUN apt-get install lmdb-utils -y -qqq
RUN pip3 install dnspython python-augeas
RUN git clone --depth=1 https://gitlab.labs.nic.cz/knot/resolver-benchmarking.git /tmp/resolver-benchmarking
RUN mv /tmp/resolver-benchmarking/response_differences/respdiff /var/opt/respdiff
......
......@@ -6,7 +6,7 @@ net.listen('127.0.0.1', 8853, { tls = true })
net.listen('::1', 8853, { tls = true })
-- Auto-maintain root TA
trust_anchors.file = '.local/etc/kresd/root.keys'
trust_anchors.file = '.local/etc/knot-resolver/root.keys'
-- Large cache size, so we don't need to flush often
-- This can be larger than available RAM, least frequently accessed
......
......@@ -12,3 +12,7 @@ CONFIG="$(pwd)/ci/respdiff/respdiff-${1}.conf"
time /var/opt/respdiff/orchestrator.py respdiff.db -c "${CONFIG}"
time /var/opt/respdiff/msgdiff.py respdiff.db -c "${CONFIG}"
/var/opt/respdiff/diffsum.py respdiff.db -c "${CONFIG}" > results/respdiff.txt
: minimize LMDB size so it can be effectively archived
mkdir results/respdiff.db
mdb_copy -c respdiff.db results/respdiff.db
xz -9 results/respdiff.db/data.mdb
......@@ -90,7 +90,7 @@ const char *get_type_name(const char *value)
static void complete_function(EditLine * el)
{
//Add left parenthesis to function name.
//Add left parenthesis to function name.
el_insertstr(el, "(");
}
......@@ -392,7 +392,7 @@ static int interact()
//Create necessary folders.
char *dirs[3] =
{ afmt("%s/.local", home), afmt("%s/.local/share", home),
afmt("%s/.local/share/kresd/", home)
afmt("%s/.local/share/knot-resolver/", home)
};
bool ok = true;
for (int i = 0; i < 3; i++) {
......@@ -403,12 +403,12 @@ static int interact()
}
if (ok) {
hist_file =
afmt("%s/.local/share/kresd/" HISTORY_FILE, home);
afmt("%s/.local/share/knot-resolver/" HISTORY_FILE, home);
}
} else {
if (!mkdir(afmt("%s/kresd/", data_home), 0755)
if (!mkdir(afmt("%s/knot-resolver/", data_home), 0755)
|| errno == EEXIST) {
hist_file = afmt("%s/kresd/" HISTORY_FILE, data_home);
hist_file = afmt("%s/knot-resolver/" HISTORY_FILE, data_home);
}
}
......
......@@ -18,7 +18,7 @@ PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
MANDIR ?= $(PREFIX)/share/man
INCLUDEDIR ?= $(PREFIX)/include
MODULEDIR ?= $(LIBDIR)/kdns_modules
ETCDIR ?= $(PREFIX)/etc/kresd
ETCDIR ?= $(PREFIX)/etc/knot-resolver
ROOTHINTS ?= $(ETCDIR)/root.hints
COVERAGE_STAGE ?= gcov
COVERAGE_STATSDIR ?= $(CURDIR)/coverage.stats
......@@ -40,11 +40,6 @@ BUILD_CFLAGS += -I$(abspath .) -I$(abspath lib/generic) -I$(abspath contrib)
BUILD_CFLAGS += -DPACKAGE_VERSION="\"$(VERSION)\"" -DPREFIX="\"$(PREFIX)\"" -DMODULEDIR="\"$(MODULEDIR)\""
BUILD_CFLAGS += -fvisibility=hidden
# Otherwise Fedora is making kresd symbols inaccessible for modules
# TODO: clang needs different flag name, etc.
BUILD_CFLAGS += -rdynamic
BUILD_LDFLAGS += -export-dynamic
ifeq (,$(findstring -O,$(CFLAGS)))
BUILD_CFLAGS += -O2
endif
......
......@@ -9,144 +9,6 @@ The server is in the `daemon` directory, it works out of the box without any con
$ kresd -h # Get help
$ kresd -a ::1
Enabling DNSSEC
===============
The resolver supports DNSSEC including :rfc:`5011` automated DNSSEC TA updates and :rfc:`7646` negative trust anchors.
To enable it, you need to provide trusted root keys. Bootstrapping of the keys is automated, and kresd fetches root trust anchors set `over a secure channel <http://jpmens.net/2015/01/21/opendnssec-rfc-5011-bind-and-unbound/>`_ from IANA. From there, it can perform :rfc:`5011` automatic updates for you.
.. note:: Automatic bootstrap requires luasocket_ and luasec_ installed.
.. code-block:: none
$ kresd -k root-new.keys # File for root keys
[ ta ] keyfile 'root-new.keys': doesn't exist, bootstrapping
[ ta ] Root trust anchors bootstrapped over https with pinned certificate.
You SHOULD verify them manually against original source:
https://www.iana.org/dnssec/files
[ ta ] Current root trust anchors are:
. 0 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
. 0 IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
[ ta ] next refresh for . in 24 hours
Alternatively, you can set it in configuration file with ``trust_anchors.file = 'root.keys'``. If the file doesn't exist, it will be automatically populated with root keys validated using root anchors retrieved over HTTPS.
This is equivalent to `using unbound-anchor <https://www.unbound.net/documentation/howto_anchor.html>`_:
.. code-block:: bash
$ unbound-anchor -a "root.keys" || echo "warning: check the key at this point"
$ echo "auto-trust-anchor-file: \"root.keys\"" >> unbound.conf
$ unbound -c unbound.conf
.. warning:: Bootstrapping of the root trust anchors is automatic, you are however **encouraged to check** the key over **secure channel**, as specified in `DNSSEC Trust Anchor Publication for the Root Zone <https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.html#sigs>`_. This is a critical step where the whole infrastructure may be compromised, you will be warned in the server log.
Configuration is described in :ref:`dnssec-config`.
Manually providing root anchors
-------------------------------
The root anchors bootstrap may fail for various reasons, in this case you need to provide IANA or alternative root anchors. The format of the keyfile is the same as for Unbound or BIND and contains DS/DNSKEY records.
1. Check the current TA published on `IANA website <https://data.iana.org/root-anchors/root-anchors.xml>`_
2. Fetch current keys (DNSKEY), verify digests
3. Deploy them
.. code-block:: bash
$ kdig DNSKEY . @k.root-servers.net +noall +answer | grep "DNSKEY[[:space:]]257" > root.keys
$ ldns-key2ds -n root.keys # Only print to stdout
... verify that digest matches TA published by IANA ...
$ kresd -k root.keys
You've just enabled DNSSEC!
.. note:: Bootstrapping and automatic update need write access to keyfile direcory. If you want to manage root anchors manually you should use ``trust_anchors.add_file('root.keys', true)``.
CLI interface
=============
The daemon features a CLI interface, type ``help()`` to see the list of available commands.
.. code-block:: bash
$ kresd /var/cache/knot-resolver
[system] started in interactive mode, type 'help()'
> cache.count()
53
.. role:: lua(code)
:language: lua
Verbose output
--------------
If the verbose logging is compiled in, i.e. not turned off by ``-DNOVERBOSELOG``, you can turn on verbose tracing of server operation with the ``-v`` option.
You can also toggle it on runtime with ``verbose(true|false)`` command.
.. code-block:: bash
$ kresd -v
To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example:
.. code-block:: bash
$ nohup ./daemon/kresd -a 127.0.0.1 -f 1 -v &
Scaling out
===========
The server can clone itself into multiple processes upon startup, this enables you to scale it on multiple cores.
Multiple processes can serve different addresses, but still share the same working directory and cache.
You can add, start and stop processes during runtime based on the load.
.. code-block:: bash
$ kresd -f 4 rundir > kresd.log &
$ kresd -f 2 rundir > kresd_2.log & # Extra instances
$ pstree $$ -g
bash(3533)─┬─kresd(19212)─┬─kresd(19212)
│ ├─kresd(19212)
│ └─kresd(19212)
├─kresd(19399)───kresd(19399)
└─pstree(19411)
$ kill 19399 # Kill group 2, former will continue to run
bash(3533)─┬─kresd(19212)─┬─kresd(19212)
│ ├─kresd(19212)
│ └─kresd(19212)
└─pstree(19460)
.. _daemon-reuseport:
.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, use only one daemon process.
Notice the absence of an interactive CLI. You can attach to the the consoles for each process, they are in ``rundir/tty/PID``.
.. code-block:: bash
$ nc -U rundir/tty/3008 # or socat - UNIX-CONNECT:rundir/tty/3008
> cache.count()
53
The *direct output* of the CLI command is captured and sent over the socket, while also printed to the daemon standard outputs (for accountability). This gives you an immediate response on the outcome of your command.
Error or debug logs aren't captured, but you can find them in the daemon standard outputs.
This is also a way to enumerate and test running instances, the list of files in ``tty`` corresponds to the list
of running processes, and you can test the process for liveliness by connecting to the UNIX socket.
.. _daemon-supervised:
Running supervised
==================
Knot Resolver can run under a supervisor to allow for graceful restarts, watchdog process and socket activation. This way the supervisor binds to sockets and lends them to the resolver daemon. If the resolver terminates or is killed, the sockets remain open and no queries are dropped.
The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. You should have a look at `real process managers`_.
The daemon also supports `systemd socket activation`_, it is automatically detected and requires no configuration on users's side.
Configuration
=============
......@@ -434,7 +296,7 @@ Environment
> user('baduser')
invalid user name
> user('kresd', 'netgrp')
> user('knot-resolver', 'netgrp')
true
> user('root')
Operation not permitted
......@@ -605,9 +467,9 @@ For when listening on ``localhost`` just doesn't cut it.
.. code-block:: lua
> net.tls("/etc/kresd/server-cert.pem", "/etc/kresd/server-key.pem")
> net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
> net.tls()
("/etc/kresd/server-cert.pem", "/etc/kresd/server-key.pem")
("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
> net.listen("::", 853)
> net.listen("::", 443, {tls = true})
......@@ -1141,6 +1003,144 @@ specified worker count and process rank.
print(worker.stats().concurrent)
Running supervised
==================
Knot Resolver can run under a supervisor to allow for graceful restarts, watchdog process and socket activation. This way the supervisor binds to sockets and lends them to the resolver daemon. If the resolver terminates or is killed, the sockets remain open and no queries are dropped.
The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. You should have a look at `real process managers`_.
The daemon also supports `systemd socket activation`_, it is automatically detected and requires no configuration on users's side.
Enabling DNSSEC
===============
The resolver supports DNSSEC including :rfc:`5011` automated DNSSEC TA updates and :rfc:`7646` negative trust anchors.
To enable it, you need to provide trusted root keys. Bootstrapping of the keys is automated, and kresd fetches root trust anchors set `over a secure channel <http://jpmens.net/2015/01/21/opendnssec-rfc-5011-bind-and-unbound/>`_ from IANA. From there, it can perform :rfc:`5011` automatic updates for you.
.. note:: Automatic bootstrap requires luasocket_ and luasec_ installed.
.. code-block:: none
$ kresd -k root-new.keys # File for root keys
[ ta ] keyfile 'root-new.keys': doesn't exist, bootstrapping
[ ta ] Root trust anchors bootstrapped over https with pinned certificate.
You SHOULD verify them manually against original source:
https://www.iana.org/dnssec/files
[ ta ] Current root trust anchors are:
. 0 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
. 0 IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
[ ta ] next refresh for . in 24 hours
Alternatively, you can set it in configuration file with ``trust_anchors.file = 'root.keys'``. If the file doesn't exist, it will be automatically populated with root keys validated using root anchors retrieved over HTTPS.
This is equivalent to `using unbound-anchor <https://www.unbound.net/documentation/howto_anchor.html>`_:
.. code-block:: bash
$ unbound-anchor -a "root.keys" || echo "warning: check the key at this point"
$ echo "auto-trust-anchor-file: \"root.keys\"" >> unbound.conf
$ unbound -c unbound.conf
.. warning:: Bootstrapping of the root trust anchors is automatic, you are however **encouraged to check** the key over **secure channel**, as specified in `DNSSEC Trust Anchor Publication for the Root Zone <https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.html#sigs>`_. This is a critical step where the whole infrastructure may be compromised, you will be warned in the server log.
Configuration is described in :ref:`dnssec-config`.
Manually providing root anchors
-------------------------------
The root anchors bootstrap may fail for various reasons, in this case you need to provide IANA or alternative root anchors. The format of the keyfile is the same as for Unbound or BIND and contains DS/DNSKEY records.
1. Check the current TA published on `IANA website <https://data.iana.org/root-anchors/root-anchors.xml>`_
2. Fetch current keys (DNSKEY), verify digests
3. Deploy them
.. code-block:: bash
$ kdig DNSKEY . @k.root-servers.net +noall +answer | grep "DNSKEY[[:space:]]257" > root.keys
$ ldns-key2ds -n root.keys # Only print to stdout
... verify that digest matches TA published by IANA ...
$ kresd -k root.keys
You've just enabled DNSSEC!
.. note:: Bootstrapping and automatic update need write access to keyfile direcory. If you want to manage root anchors manually you should use ``trust_anchors.add_file('root.keys', true)``.
CLI interface
=============
The daemon features a CLI interface, type ``help()`` to see the list of available commands.
.. code-block:: bash
$ kresd /var/cache/knot-resolver
[system] started in interactive mode, type 'help()'
> cache.count()
53
.. role:: lua(code)
:language: lua
Verbose output
--------------
If the verbose logging is compiled in, i.e. not turned off by ``-DNOVERBOSELOG``, you can turn on verbose tracing of server operation with the ``-v`` option.
You can also toggle it on runtime with ``verbose(true|false)`` command.
.. code-block:: bash
$ kresd -v
To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example:
.. code-block:: bash
$ nohup ./daemon/kresd -a 127.0.0.1 -f 1 -v &
Scaling out
===========
The server can clone itself into multiple processes upon startup, this enables you to scale it on multiple cores.
Multiple processes can serve different addresses, but still share the same working directory and cache.
You can add, start and stop processes during runtime based on the load.
.. code-block:: bash
$ kresd -f 4 rundir > kresd.log &
$ kresd -f 2 rundir > kresd_2.log & # Extra instances
$ pstree $$ -g
bash(3533)─┬─kresd(19212)─┬─kresd(19212)
│ ├─kresd(19212)
│ └─kresd(19212)
├─kresd(19399)───kresd(19399)
└─pstree(19411)
$ kill 19399 # Kill group 2, former will continue to run
bash(3533)─┬─kresd(19212)─┬─kresd(19212)
│ ├─kresd(19212)
│ └─kresd(19212)
└─pstree(19460)
.. _daemon-reuseport:
.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, use only one daemon process.
Notice the absence of an interactive CLI. You can attach to the the consoles for each process, they are in ``rundir/tty/PID``.
.. code-block:: bash
$ nc -U rundir/tty/3008 # or socat - UNIX-CONNECT:rundir/tty/3008
> cache.count()
53
The *direct output* of the CLI command is captured and sent over the socket, while also printed to the daemon standard outputs (for accountability). This gives you an immediate response on the outcome of your command.
Error or debug logs aren't captured, but you can find them in the daemon standard outputs.
This is also a way to enumerate and test running instances, the list of files in ``tty`` corresponds to the list
of running processes, and you can test the process for liveliness by connecting to the UNIX socket.
.. _daemon-supervised:
Using CLI tools
===============
......
......@@ -6,7 +6,7 @@
# (Avoid typos, accidental mismatches, etc.)
#
# To regenerate the C definitions for lua:
# - you need to have debugging symbols for knot-dns and kresd;
# - you need to have debugging symbols for knot-dns and knot-resolver;
# you get those by compiling with -g; for knot-dns it might be enough
# to just install it with debugging symbols included (in your distro way)
# - remove file ./kres-gen.lua and run make as usual
......
......@@ -475,7 +475,10 @@ static void args_init(struct args *args)
args->quiet = false;
}
int parse_args(int argc, char **argv, struct args *args)
/** Process arguments into struct args.
* @return >=0 if main() should be exited immediately.
*/
static int parse_args(int argc, char **argv, struct args *args)
{
/* Long options. */
int c = 0, li = 0;
......@@ -554,11 +557,11 @@ int parse_args(int argc, char **argv, struct args *args)
help(argc, argv);
return EXIT_FAILURE;
}
}
}
if (optind < argc) {
args->rundir = argv[optind];
}
return EXIT_SUCCESS;
return -1;
}
static int bind_fds(struct network *net, fd_array_t *fd_set, bool tls) {
......@@ -595,7 +598,7 @@ int main(int argc, char **argv)
int ret = 0;
struct args args;
args_init(&args);
if ((ret = parse_args(argc, argv, &args)) != EXIT_SUCCESS) {
if ((ret = parse_args(argc, argv, &args)) >= 0) {
return ret;
}
......@@ -651,7 +654,7 @@ int main(int argc, char **argv)
* sockets etc. before forking, but at the same time can't touch it before
* forking otherwise it crashes, so it's a chicken and egg problem.
* Disabling until https://github.com/libuv/libuv/pull/846 is done. */
if (forks > 1 && fd_set.len == 0 && tls_fd_set.len == 0) {
if (args.forks > 1 && args.fd_set.len == 0 && args.tls_fd_set.len == 0) {
kr_log_error("[system] forking >1 workers supported only on Linux 3.9+ or with supervisor\n");
return EXIT_FAILURE;
}
......
......@@ -108,7 +108,7 @@ Most of the dependencies can be resolved from packages, here's an overview for s
brew install pkg-config libuv luajit cmocka
Building from sources
Building from sources
---------------------
Initialize git submodules first.
......@@ -195,7 +195,7 @@ All paths are prefixed with ``PREFIX`` variable by default if not specified othe
"library", "``LIBDIR``", "``$(PREFIX)/lib``", "pkg-config is auto-generated [#]_"
"daemon", "``SBINDIR``", "``$(PREFIX)/sbin``", ""
"configuration", "``ETCDIR``", "``$(PREFIX)/etc/kresd``", "Configuration file, templates."
"configuration", "``ETCDIR``", "``$(PREFIX)/etc/knot-resolver``", "Configuration file, templates."
"modules", "``MODULEDIR``", "``$(LIBDIR)/kdns_modules``", "Runtime directory for loading dynamic modules [#]_."
"trust anchor file", "``KEYFILE_DEFAULT``", "*(none)*", "Path to read-only trust anchor file, which is used as fallback when no other file is specified. [#]_"
"work directory", "", "the current directory", "Run directory for daemon. (Only relevant during run time, not e.g. during installation.)"
......@@ -216,7 +216,7 @@ By default the resolver library is built as a dynamic library with versioned ABI
$ make BUILDMODE=dynamic # Default, create dynamic library
$ make BUILDMODE=static # Create static library
When the library is linked statically, it usually produces a smaller binary. However linking it to various C modules might violate ODR and increase the size.
When the library is linked statically, it usually produces a smaller binary. However linking it to various C modules might violate ODR and increase the size.
Resolving dependencies
~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -2,7 +2,7 @@ ifeq ($(HAS_doxygen)|$(HAS_sphinx-build), yes|yes)
doc-doxygen:
@cd doc && $(doxygen_BIN)
doc-html: doc-doxygen
@cd doc && $(sphinx-build_BIN) -b html . html
@cd doc && $(sphinx-build_BIN) $(SPHINXFLAGS) -b html . html
else
doc-html:
$(error doxygen and sphinx must be installed)
......
......@@ -9,10 +9,10 @@ Modular architecture of the library keeps the core tiny and efficient, and provi
.. toctree::
:maxdepth: 2
build
lib
daemon
modules
build
lib
modules_api
......
......@@ -8,7 +8,7 @@
net = { '127.0.0.1', '::1', '192.168.1.1' }
-- Drop root privileges
user('kresd', 'kresd')
user('knot-resolver', 'knot-resolver')
-- Auto-maintain root TA
trust_anchors.file = 'root.keys'
......@@ -16,7 +16,7 @@ trust_anchors.file = 'root.keys'
-- Large cache size, so we don't need to flush ever
-- This can be larger than available RAM, least frequently accessed
-- records will be paged out as long as there's enough disk space to back it
cache.size = 100 * GB
cache.size = 100 * GB
-- Load Useful modules
modules = {
......
......@@ -5,7 +5,7 @@
net = { '127.0.0.1', '::1', '192.168.1.1' }
-- Drop root privileges
user('kresd', 'kresd')
user('knot-resolver', 'knot-resolver')
-- Auto-maintain root TA
trust_anchors.file = 'root.keys'
......@@ -13,7 +13,7 @@ trust_anchors.file = 'root.keys'
-- Large cache size, so we don't need to flush often
-- This can be larger than available RAM, least frequently accessed
-- records will be paged out
cache.size = 4 * GB
cache.size = 4 * GB
-- Load Useful modules
modules = {
......
......@@ -7,7 +7,7 @@
-- net = { '127.0.0.1', '::1' }
-- Drop root privileges
user('kresd', 'kresd')
user('knot-resolver', 'knot-resolver')
-- Auto-maintain root TA
trust_anchors.file = 'root.keys'
......
......@@ -5,7 +5,7 @@
net = { '127.0.0.1', '::1', '192.168.1.1' }
-- Drop root privileges
user('kresd', 'kresd')
user('knot-resolver', 'knot-resolver')
-- Auto-maintain root TA
trust_anchors.file = 'root.keys'
......@@ -28,7 +28,7 @@ modules = {
-- Large cache size, so we don't need to flush often
-- This can be larger than available RAM, least frequently accessed
-- records will be paged out
cache.size = 4 * GB
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')}))
......@@ -143,7 +143,10 @@ char* kr_strcatdup(unsigned n, ...)
for (unsigned i = 0; i < n; ++i) {
char *item = va_arg(vl, char *);
const size_t new_len = total_len + strlen_safe(item);
if (unlikely(new_len < total_len)) return NULL;
if (unlikely(new_len < total_len)) {
va_end(vl);
return NULL;
}
total_len = new_len;
}
va_end(vl);
......
......@@ -4,15 +4,15 @@ Etcd module
-----------
The module connects to Etcd peers and watches for configuration change.
By default, the module looks for the subtree under ``/kresd`` directory,
By default, the module looks for the subtree under ``/knot-resolver`` directory,
but you can change this `in the configuration <https://github.com/mah0x211/lua-etcd#cli-err--etcdnew-optiontable->`_.
The subtree structure corresponds to the configuration variables in the declarative style.
.. code-block:: bash
$ etcdctl set /kresd/net/127.0.0.1 53
$ etcdctl set /kresd/cache/size 10000000
$ etcdctl set /knot-resolvevr/net/127.0.0.1 53
$ etcdctl set /knot-resolver/cache/size 10000000
Configures all listening nodes to following configuration:
......@@ -28,7 +28,7 @@ Example configuration
modules = {
etcd = {
prefix = '/kresd',
prefix = '/knot-resolver',
peer = 'http://127.0.0.1:7001'
}
}
......
......@@ -27,7 +27,7 @@ end
function etcd.init()
etcd.Etcd = require('etcd.luasocket')
etcd.defaults = { prefix = '/kresd' }
etcd.defaults = { prefix = '/knot-resolver' }
end
function etcd.deinit()
......
......@@ -4,11 +4,15 @@ Query policies
--------------
This module can block, rewrite, or alter inbound queries based on user-defined policies.
By default, if no rule applies to a query, rules for special-use domain names are applied, as required by :rfc:`6761`.
You can however extend it e.g. to deflect `Slow drip DNS attacks <https://secure64.com/water-torture-slow-drip-dns-ddos-attack>`_ or gray-list resolution of misbehaving zones.
Each policy *rule* has two parts: a *filter* and an *action*. A *filter* selects which queries will be affected by the policy, and *action* which modifies queries matching the associated filter. Typically a rule is defined as follows: ``filter(action(action parameters), filter parameters)``. For example, a filter can be ``suffix`` which matches queries whose suffix part is in specified set, and one of possible actions is ``DENY``, which denies resolution. These are combined together into ``policy.suffix(policy.DENY, {todname('badguy.example.')})``. The rule is effective when it is added into rule table using ``policy.add()``, please see `Policy examples`_.
There are several policy filters available in the ``policy.`` table:
By default, if no rule applies to a query, built-in rules for `special-use <https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml>`_ and `locally-served <http://www.iana.org/assignments/locally-served-dns-zone>`_ domain names are applied. These built-in rules can be overriden using action ``PASS``, see `Policy examples`_ below.
Filters
^^^^^^^
A *filter* selects which queries will be affected by specified *action*. There are several policy filters available in the ``policy.`` table:
* ``all(action)``
- always applies the action
......@@ -22,10 +26,13 @@ There are several policy filters available in the ``policy.`` table:
- implements a subset of RPZ_ in zonefile format. See below for details: :any:`policy.rpz`.
* custom filter function
There are several actions available in the ``policy.`` table:
Actions
^^^^^^^
An *action* is function which modifies DNS query. There are several actions available in the ``policy.`` table:
* ``PASS`` - let the query pass through; it's useful to make exceptions before wider rules
* ``DENY`` - reply NXDOMAIN authoritatively
* ``DENY_MSG(msg)`` - reply NXDOMAIN authoritatively and add explanatory message to additional section
* ``DROP`` - terminate query resolution and return SERVFAIL to the requestor
* ``TC`` - set TC=1 if the request came through UDP, forcing client to retry with TCP
* ``FORWARD(ip)`` - resolve a query via forwarding to an IP while validating and caching locally;
......@@ -40,6 +47,8 @@ There are several actions available in the ``policy.`` table:
Most actions stop the policy matching on the query, but "chain actions" allow to keep trying to match other rules, until a non-chain action is triggered.
Also, it is possible to write your own action (i.e. Lua function). It is possible to implement complex heuristics, e.g. to deflect `Slow drip DNS attacks <https://secure64.com/water-torture-slow-drip-dns-ddos-attack>`_ or gray-list resolution of misbehaving zones.
.. warning:: The policy module currently only looks at whole DNS requests. The rules won't be re-applied e.g. when following CNAMEs.
.. note:: The module (and ``kres``) expects domain names in wire format, not textual representation. So each label in name is prefixed with its length, e.g. "example.com" equals to ``"\7example\3com"``. You can use convenience function ``todname('example.com')`` for automatic conversion.
......@@ -76,14 +85,13 @@ TLS Examples
{'2001:DB8::d0c', hostname='res.example.', ca_file='/etc/knot-resolver/tlsca.crt'}
})
.. _policy_examples:
Other examples
^^^^^^^^^^^^^^
Policy examples
^^^^^^^^^^^^^^^
.. code-block:: lua
-- Load default policies
modules = { 'policy' }
-- Whitelist 'www[0-9].badboy.cz'
policy.add(policy.pattern(policy.PASS, '\4www[0-9]\6badboy\2cz'))
-- Block all names below badboy.cz
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment