diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2495aaac206c1cc1765ef41d7150e00316faa456..c4a23f4beb6db4239f945394698c4eaa9a8a81b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/ci/Dockerfile b/ci/Dockerfile index 7a72190aaa4177570c00154fa9394b986cf0fe99..86dba2022314ae37bcb9a983e18155cf98136fc2 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -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 diff --git a/ci/respdiff/kresd.config b/ci/respdiff/kresd.config index e7827b00c240ffe93ceeebb7acd2d8793ddc3e3a..98d62f17f29f7a65a7688a719899e83b48f644bd 100644 --- a/ci/respdiff/kresd.config +++ b/ci/respdiff/kresd.config @@ -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 diff --git a/ci/respdiff/run-respdiff-tests.sh b/ci/respdiff/run-respdiff-tests.sh index b85d412560794d9e2f7265d8693c9e74958aab6d..f99fdd732409321ad4b6d31180b89a51ccf3842e 100755 --- a/ci/respdiff/run-respdiff-tests.sh +++ b/ci/respdiff/run-respdiff-tests.sh @@ -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 diff --git a/client/kresc.c b/client/kresc.c index 5f38d4f83ac9b588e7c096bc4e2b2f8ba106123f..42dba3454aa8c031de9efa1b461d894860a998f8 100644 --- a/client/kresc.c +++ b/client/kresc.c @@ -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); } } diff --git a/config.mk b/config.mk index ac3bac985914212f34e421b0edb3c293b0ddad4c..77b15a79bd2e5c3b040a064c6cfac6ba236ea00f 100644 --- a/config.mk +++ b/config.mk @@ -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 diff --git a/daemon/README.rst b/daemon/README.rst index 5e4d63ec4f2d0923a60c36817655cb49a73299fd..902e8ac3c113933572f8b9ef09e5d1a88968c36b 100644 --- a/daemon/README.rst +++ b/daemon/README.rst @@ -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 =============== diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh index 3599e9b3aa4f3f7ff52d626fb2f8c4ed60b1fc56..ff673a517cf3b7b9590ab8f22e7f5b6bbc8e5b70 100755 --- a/daemon/lua/kres-gen.sh +++ b/daemon/lua/kres-gen.sh @@ -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 diff --git a/daemon/main.c b/daemon/main.c index 560aec2a7f0a1c571dde1de8c1d06c16dc6a66fe..046a19a279ba22aeea043d9aa50031a87d814ea3 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -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; } diff --git a/doc/build.rst b/doc/build.rst index 6ac99ba759adbf279b0370ac692c000012c117d4..6da43b3a3c290bd645efda26b1b9a95782cd3140 100644 --- a/doc/build.rst +++ b/doc/build.rst @@ -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 ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/doc.mk b/doc/doc.mk index 26a52bf6325e4bbd344eff98441a59b281eecdd2..58c299e3411a327a6ddad8627baa9e787af7dec3 100644 --- a/doc/doc.mk +++ b/doc/doc.mk @@ -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) diff --git a/doc/index.rst b/doc/index.rst index d5ac52459bfdcabe33c11602976f8140297c3e1b..b38d5de5d8b4941ecf7cbb20730ef9481a626763 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -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 diff --git a/etc/config.cluster b/etc/config.cluster index f434be8f5446db5ee12af55c689efd8eb194b88b..bc1cf60a5bb64258f398bf2fb281ac7f46c3eacc 100644 --- a/etc/config.cluster +++ b/etc/config.cluster @@ -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 = { diff --git a/etc/config.isp b/etc/config.isp index 344de7e15ecdfc52fbf53821dc815b88be86bd07..f050bd883f0f410c55135092d6ccf632e4a8eac7 100644 --- a/etc/config.isp +++ b/etc/config.isp @@ -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 = { diff --git a/etc/config.personal b/etc/config.personal index a46af4d847f83d21b2bacf34f89ae98f4001ad37..490798e22120da32742379923bc21317893a63fc 100644 --- a/etc/config.personal +++ b/etc/config.personal @@ -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' diff --git a/etc/config.splitview b/etc/config.splitview index 2d5f66d6ec5f2f5fc52c11db74b03057d4b2b31e..1706a498a61a1d9841917b0af6051029f2b15ae4 100644 --- a/etc/config.splitview +++ b/etc/config.splitview @@ -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')})) diff --git a/lib/utils.c b/lib/utils.c index 97df669e16c701b384a7f02ec876f1141121e178..6b1c2eac5743aa35c1265f2a917e2827a99f3866 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -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); diff --git a/modules/etcd/README.rst b/modules/etcd/README.rst index d25b369a4c3bceddd78cd211715ebb82efdd3cf0..5de55c216a13ca9895a00b93dfeead1e786f62e6 100644 --- a/modules/etcd/README.rst +++ b/modules/etcd/README.rst @@ -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' } } diff --git a/modules/etcd/etcd.lua b/modules/etcd/etcd.lua index 08348529dac9e394d4badff2936a9dda418063c0..4d4bbfba0788f9ace0a90da1c56fe90cbd016129 100644 --- a/modules/etcd/etcd.lua +++ b/modules/etcd/etcd.lua @@ -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() diff --git a/modules/policy/README.rst b/modules/policy/README.rst index 499d15f15623ae948ec8bfc48edd9a5a32e0e8db..722819dbedc62ea2b918189bcf184cb8fcdee3be 100644 --- a/modules/policy/README.rst +++ b/modules/policy/README.rst @@ -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 diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua index 95010d4f07ed35576279ae607537ece685c5ff7a..21209b88af8ebd3003bf1c9a2425fc7f3fbf40c9 100644 --- a/modules/policy/policy.lua +++ b/modules/policy/policy.lua @@ -57,8 +57,15 @@ local function addr2sock(target, default_port) return sock end +-- policy functions are defined below +local policy = {} + +function policy.PASS(state, _) + return state +end + -- Mirror request elsewhere, and continue solving -local function mirror(target) +function policy.MIRROR(target) local addr, port = addr_split_port(target, 53) local sink, err = socket_client(addr, port) if not sink then panic('MIRROR target %s is not a valid: %s', target, err) end @@ -84,7 +91,7 @@ local function set_nslist(qry, list) end -- Forward request, and solve as stub query -local function stub(target) +function policy.STUB(target) local list = {} if type(target) == 'table' then for _, v in pairs(target) do @@ -105,7 +112,7 @@ local function stub(target) end -- Forward request and all subrequests to upstream; validate answers -local function forward(target) +function policy.FORWARD(target) local list = {} if type(target) == 'table' then for _, v in pairs(target) do @@ -188,7 +195,7 @@ local function tls_forward_target_check_syntax(idx, list_entry) end -- Forward request and all subrequests to upstream over TLS; validate answers -local function tls_forward(target) +function policy.TLS_FORWARD(target) local sockaddr_c_list = {} local sockaddr_config = {} -- items: { string_addr=<addr string>, auth_type=<auth type> } local ca_files = {} @@ -255,7 +262,7 @@ local function tls_forward(target) end -- Rewrite records in packet -local function reroute(tbl, names) +function policy.REROUTE(tbl, names) -- Import renumbering rules local ren = require('renumber') local prefixes = {} @@ -267,7 +274,7 @@ local function reroute(tbl, names) end -- Set and clear some query flags -local function flags(opts_set, opts_clear) +function policy.FLAGS(opts_set, opts_clear) return function(_, req) local qry = req:current() ffi.C.kr_qflags_set (qry.flags, kres.mk_qflags(opts_set or {})) @@ -280,8 +287,8 @@ local function mkauth_soa(answer, dname, mname) if mname == nil then mname = dname end - return answer:put(dname, 900, answer:qclass(), kres.type.SOA, - mname .. '\6nobody\7invalid\0\0\0\0\0\0\0\14\16\0\0\3\132\0\9\58\128\0\0\3\132') + return answer:put(dname, 10800, answer:qclass(), kres.type.SOA, + mname .. '\6nobody\7invalid\0\0\0\0\1\0\0\14\16\0\0\4\176\0\9\58\128\0\0\42\48') end local dname_localhost = todname('localhost.') @@ -367,15 +374,6 @@ local function localhost_reversed(_, req) return kres.DONE end -local policy = { - -- Policies - PASS = 1, DENY = 2, DROP = 3, TC = 4, QTRACE = 5, - FORWARD = forward, TLS_FORWARD = tls_forward, - STUB = stub, REROUTE = reroute, MIRROR = mirror, FLAGS = flags, - -- Special values - ANY = 0, -} - -- All requests function policy.all(action) return function(_, _) return action end @@ -450,8 +448,9 @@ local function rpz_parse(action, path) return rules end +-- RPZ policy set -- Create RPZ from zone file -local function rpz_zonefile(action, path) +function policy.rpz(action, path) local rules = rpz_parse(action, path) collectgarbage() return function(_, query) @@ -465,9 +464,48 @@ local function rpz_zonefile(action, path) end end --- RPZ policy set -function policy.rpz(action, path) - return rpz_zonefile(action, path) +function policy.DENY_MSG(msg) + if msg and (type(msg) ~= 'string' or #msg >= 255) then + error('DENY_MSG: optional msg must be string shorter than 256 characters') + end + + return function (_, req) + -- Write authority information + local answer = req.answer + ffi.C.kr_pkt_make_auth_header(answer) + answer:rcode(kres.rcode.NXDOMAIN) + answer:begin(kres.section.AUTHORITY) + mkauth_soa(answer, answer:qname()) + if msg then + answer:begin(kres.section.ADDITIONAL) + answer:put('\11explanation\7invalid', 10800, answer:qclass(), kres.type.TXT, + string.char(#msg) .. msg) + + end + return kres.DONE + end +end +policy.DENY = policy.DENY_MSG() -- compatibility with < 2.0 + +function policy.DROP(_, _) + return kres.FAIL +end + +function policy.TC(state, req) + local answer = req.answer + if answer.max_size ~= 65535 then + answer:tc(1) -- ^ Only UDP queries + return kres.DONE + else + return state + end +end + +function policy.QTRACE(_, req) + local qry = req:current() + req.options.TRACE = true + qry.flags.TRACE = true + return -- this allows to continue iterating over policy list end -- Evaluate packet in given rules to determine policy action @@ -478,7 +516,7 @@ function policy.evaluate(rules, req, query, state) local action = rule.cb(req, query) if action ~= nil then rule.count = rule.count + 1 - local next_state = policy.enforce(state, req, action) + local next_state = action(state, req) if next_state then -- Not a chain rule, return next_state -- stop on first match end @@ -488,35 +526,6 @@ function policy.evaluate(rules, req, query, state) return end --- Enforce policy action -function policy.enforce(state, req, action) - if action == policy.DENY then - -- Write authority information - local answer = req.answer - ffi.C.kr_pkt_make_auth_header(answer) - answer:rcode(kres.rcode.NXDOMAIN) - answer:begin(kres.section.AUTHORITY) - mkauth_soa(answer, '\7blocked\0') - return kres.DONE - elseif action == policy.DROP then - return kres.FAIL - elseif action == policy.TC then - local answer = req.answer - if answer.max_size ~= 65535 then - answer:tc(1) -- ^ Only UDP queries - return kres.DONE - end - elseif action == policy.QTRACE then - local qry = req:current() - req.options.TRACE = true - qry.flags.TRACE = true - return -- this allows to continue iterating over policy list - elseif type(action) == 'function' then - return action(state, req) - end - return state -end - -- Top-down policy list walk until we hit a match -- the caller is responsible for reordering policy list -- from most specific to least specific. @@ -607,7 +616,7 @@ local private_zones = { '100.51.198.in-addr.arpa.', '113.0.203.in-addr.arpa.', '255.255.255.255.in-addr.arpa.', - -- RFC7796 + -- RFC7793 '64.100.in-addr.arpa.', '65.100.in-addr.arpa.', '66.100.in-addr.arpa.', @@ -690,14 +699,22 @@ policy.rules = {} policy.postrules = {} policy.special_names = { { - cb=policy.suffix_common(policy.DENY, private_zones, todname('arpa.')), + cb=policy.suffix_common(policy.DENY_MSG( + 'Blocking is mandated by standards, see references on ' + .. 'https://www.iana.org/assignments/' + .. 'locally-served-dns-zones/locally-served-dns-zones.xhtml'), + private_zones, todname('arpa.')), count=0 }, { - cb=policy.suffix(policy.DENY, { - todname('test.'), - todname('invalid.'), - todname('onion.'), -- RFC7686, 2.4 + cb=policy.suffix(policy.DENY_MSG( + 'Blocking is mandated by standards, see references on ' + .. 'https://www.iana.org/assignments/' + .. 'special-use-domain-names/special-use-domain-names.xhtml'), + { + todname('test.'), + todname('onion.'), + todname('invalid.'), }), count=0 }, diff --git a/modules/stats/README.rst b/modules/stats/README.rst index f6755ac3236f7417c70e23335d1b5fd44086200a..8f5280641f6ba02ae91f1be3eb9d0034b90099ad 100644 --- a/modules/stats/README.rst +++ b/modules/stats/README.rst @@ -7,7 +7,7 @@ This modules gathers various counters from the query resolution and server inter and offers them as a key-value storage. Any module may update the metrics or simply hook in new ones. -.. code-block:: lua +.. code-block:: none -- Enumerate metrics > stats.list() diff --git a/modules/stats/stats.c b/modules/stats/stats.c index cff04b24b00c08c16d494f85fecbed370460b3ca..525175422034b9e10c21875eeeaa887c4bd62c15 100644 --- a/modules/stats/stats.c +++ b/modules/stats/stats.c @@ -313,7 +313,7 @@ static char* stats_list(void *env, struct kr_module *module, const char *args) size_t args_len = args ? strlen(args) : 0; for (unsigned i = 0; i < metric_const_end; ++i) { struct const_metric_elm *elm = &const_metrics[i]; - if (strncmp(elm->key, args, args_len) == 0) { + if (args && strncmp(elm->key, args, args_len) == 0) { json_append_member(root, elm->key, json_mknumber(elm->val)); } } diff --git a/modules/view/view.lua b/modules/view/view.lua index f2837fc595661755c40c76319c8b903fabbd7b58..dad097aff25962d0d3f4333fb660fb4da26de19b 100644 --- a/modules/view/view.lua +++ b/modules/view/view.lua @@ -1,5 +1,4 @@ local kres = require('kres') -local policy = require('policy') local ffi = require('ffi') local C = ffi.C @@ -91,7 +90,12 @@ view.layer = { local match_cb = evaluate(view, req) if match_cb ~= nil then local action = match_cb(req, req:current()) - return policy.enforce(state, req, action) or state + if action then + local next_state = action(state, req) + if next_state then -- Not a chain rule, + return next_state -- stop on first match + end + end end return state end diff --git a/platform.mk b/platform.mk index f2657ed15326889adae88e6f4a74d1cfbc2e57cd..d42c66e4ce6429c442f58ac57052be1dad3705e1 100644 --- a/platform.mk +++ b/platform.mk @@ -36,6 +36,7 @@ else PLATFORM := Darwin LIBEXT := .dylib MODTYPE := dynamiclib + LDFLAGS += -Wl,-export_dynamic # OS X specific hardening since -pie doesn't work ifneq ($(HARDENING),no) BINFLAGS += -Wl,-pie @@ -45,14 +46,18 @@ else SOVER = $(if $(1), -compatibility_version $(2) -current_version $(1),) else PLATFORM := POSIX - LDFLAGS += -pthread -lm -Wl,-E + LDFLAGS += -pthread -lm -Wl,--export-dynamic # ELF hardening options ifneq ($(HARDENING),no) BINFLAGS += -pie LDFLAGS += -Wl,-z,relro,-z,now endif ifeq ($(UNAME),Linux) - LDFLAGS += -ldl + LDFLAGS += -ldl + endif + ifeq ($(firstword $(shell $(CC) --version)),gcc) + # Otherwise Fedora is making kresd symbols inaccessible for modules? + CFLAGS += -rdynamic endif endif endif diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 2ab7c7e66ce624c3f2513a6ece6fb19047ce78cf..f0399f0853a1e4499cc4f9304472232afad8a8f4 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -1,23 +1,25 @@ FROM alpine:edge -MAINTAINER Marek Vavrusa <marek.vavrusa@nic.cz> +MAINTAINER Knot Resolver team <knot-resolver-users@lists.nic.cz> # Environment ENV BUILD_PKGS build-base automake autoconf libtool pkgconfig git luajit-dev libuv-dev gnutls-dev jansson-dev userspace-rcu-dev curl vim bsd-compat-headers -ENV RUN_PKGS luajit libuv gnutls jansson bash +ENV RUN_PKGS luajit libuv gnutls jansson bash libstdc++ lua5.1-cqueues lua5.1-http lua5.1-sec lua5.1-socket ENV BUILD_IGNORE gmp nettle jansson gnutls lua libuv cmocka ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig ENV CFLAGS -O2 -ftree-vectorize -fstack-protector -g ENV LDFLAGS -Wl,--as-needed -# Expose port -EXPOSE 53 +# export DNS over UDP & TCP, DNS-over-TLS, web interface +EXPOSE 53/UDP 53/TCP 853/TCP 8053/TCP # Select entrypoint WORKDIR /data -CMD ["/usr/local/sbin/kresd"] +COPY "config.docker" "/data" +CMD ["/usr/local/sbin/kresd", "-c", "/data/config.docker"] # Install dependencies and sources RUN \ +apk add -t lua5.1-compat5.3 lua5.1-compat53 && \ apk --update add ${RUN_PKGS} && \ apk add --virtual build-dep ${BUILD_PKGS} && \ git clone --depth 1 --recurse-submodules=modules/policy/lua-aho-corasick \ diff --git a/scripts/config.docker b/scripts/config.docker new file mode 100644 index 0000000000000000000000000000000000000000..58d8d13b606828bcafaa11e6d6f16fda822badd0 --- /dev/null +++ b/scripts/config.docker @@ -0,0 +1,41 @@ +-- Refer to manual: https://knot-resolver.readthedocs.io/en/latest/daemon.html#configuration + +-- Listen on all interfaces (localhost would not work in Docker) +net.listen('0.0.0.0') +net.listen('0.0.0.0', 853, {tls=true}) + +-- Auto-maintain root TA +trust_anchors.file = '/data/root.keys' + +-- Load Useful modules +modules = { + 'policy', -- Block queries to local zones/bad sites + 'stats', -- Track internal statistics + -- Load HTTP module with defaults + http = { + host = '0.0.0.0', + port = 8053, + } +} + +-- Smaller cache size +cache.size = 10 * MB + +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, 853, and 8053 to some other numbers, see\n' + .. '$ docker ps\n' + .. '(column PORTS)\n' + .. '80 -> DNS protocol over UDP and TCP\n' + .. '853 -> DNS-over-TLS protocol\n' + .. '8053 -> web interface\n' + .. '\n' + .. 'For verbose logging enter following command to prompt below:\n' + .. 'verbose(true)\n') +end +print_help() +event.after(11000, print_help) diff --git a/scripts/kresd.apparmor b/scripts/kresd.apparmor index 2b5b5f7ff86829531fbc89d88c4f41016e96948f..ad6f911a06202c72ddd7e31f2fd684cc110faff3 100644 --- a/scripts/kresd.apparmor +++ b/scripts/kresd.apparmor @@ -7,7 +7,7 @@ capability net_bind_service, capability setgid, capability setuid, - # seems to be needed during start to read /var/lib/kresd + # seems to be needed during start to read /var/lib/knot-resolver # while we still run as root. capability dac_override, @@ -15,9 +15,9 @@ network udp, /proc/sys/net/core/somaxconn r, - /etc/kresd/* r, - /var/lib/kresd/ r, - /var/lib/kresd/** rwlk, + /etc/knot-resolver/* r, + /var/lib/knot-resolver/ r, + /var/lib/knot-resolver/** rwlk, # modules /usr/lib{,64}/kdns_modules/*.lua r,