Commit d515cb64 authored by Marek Vavruša's avatar Marek Vavruša

doc: updated documentation and examples

parent d86e6f7e
......@@ -3,50 +3,85 @@
Knot DNS Resolver daemon
************************
Requirements
============
The server is in the `daemon` directory, it works out of the box without any configuration.
* libuv_ 1.0+ (a multi-platform support library with a focus on asynchronous I/O)
* Lua_ 5.1+ (embeddable scripting language, LuaJIT_ is preferred)
.. code-block:: bash
Running
=======
$ kresd -h # Get help
$ kresd -a ::1
There is a separate resolver library in the `lib` directory, and a server in the `daemon` directory.
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 at least _one_ trust anchor. This step is not automatic, as you're supposed to obtain
the trust anchor `using a secure channel <http://jpmens.net/2015/01/21/opendnssec-rfc-5011-bind-and-unbound/>`_.
From there, the Knot DNS Resolver can perform automatic updates for you.
1. Check the current TA published on `IANA website <https://data.iana.org/root-anchors/root-anchors.xml>`_
2. Fetch current keys, verify
3. Deploy them
.. code-block:: bash
$ kresd -h
$ kdig DNSKEY . @a.root-servers.net +noall +answer | grep 257 > root.keys
$ ldns-key2ds -n root.keys
... verify that digest matches TA published by IANA ...
$ kresd -k root.keys
You've just enabled DNSSEC!
Interacting with the daemon
---------------------------
CLI interface
=============
The daemon features a CLI interface if launched interactively, type ``help`` to see the list of available commands.
You can load modules this way and use their properties to get information about statistics and such.
The daemon features a CLI interface, type ``help`` to see the list of available commands.
.. code-block:: bash
$ kresd /var/run/knot-resolver
[system] started in interactive mode, type 'help()'
> cache.count()
53
$ kresd /var/run/knot-resolver
[system] started in interactive mode, type 'help()'
> cache.count()
53
.. role:: lua(code)
:language: lua
Running in forked mode
----------------------
Verbose output
--------------
If the debug logging is compiled in, 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
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 on runtime based on the load.
.. code-block:: bash
$ kresd -f 2 rundir > kresd.log
$ 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)
.. 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 the kernel doesn't support it, you can still fork multiple processes on different ports, and do load balancing externally (on firewall or with `dnsdist <http://dnsdist.org/>`_).
Notice it isn't interactive, but you can attach to the the consoles for each process, they are in ``rundir/tty/PID``.
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
......@@ -59,16 +94,6 @@ of running processes, and you can test the process for liveliness by connecting
.. warning:: This is very basic way to orchestrate multi-core deployments and doesn't scale in multi-node clusters. Keep an eye on the prepared ``hive`` module that is going to automate everything from service discovery to deployment and consistent configuration.
Verbose output
--------------
If the debug logging is compiled in, 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
Configuration
=============
......@@ -86,11 +111,8 @@ comfortable in the current working directory.
And you're good to go for most use cases! If you want to use modules or configure daemon behavior, read on.
There are several choices on how you can configure the daemon, a RPC interface a CLI and a configuration file.
Fortunately all share common syntax and are transparent to each other, e.g. changes made during the runtime are kept
in the redo log and are immediately visible.
.. warning:: Redo log is not yet implemented, changes are visible during the process lifetime only.
There are several choices on how you can configure the daemon, a RPC interface, a CLI, and a configuration file.
Fortunately all share common syntax and are transparent to each other.
Configuration example
---------------------
......@@ -99,9 +121,9 @@ Configuration example
-- 10MB cache
cache.size = 10*MB
-- load some modules
modules = { 'hints', 'cachectl' }
modules = { 'policy', 'cachectl' }
-- interfaces
net = { '127.0.0.1' }
net = { '127.0.0.1', '::1' }
Configuration syntax
--------------------
......@@ -347,24 +369,6 @@ For when listening on ``localhost`` just doesn't cut it.
Trust anchors and 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 at least _one_ trust anchor. This step is not automatic, as you're supposed to obtain
the trust anchor using a secure channel. From there, the Knot DNS Resolver can perform automatic updates for you if you
run in managed mode.
The recommended way is as follows:
1. Check the current TA published on `IANA website <https://data.iana.org/root-anchors/root-anchors.xml>`_
2. Fetch current keys, verify and use
.. code-block:: bash
$ kdig dnskey . @a.root-servers.net +noall +answer | grep 257 > root.keys
$ ldns-key2ds -n root.keys
... verify that digest matches TA published by IANA ...
$ kresd -k root.keys
You've just enabled DNSSEC, congratulations!
.. function:: trust_anchors.config(keyfile)
:param string keyfile: File containing DNSKEY records, should be writeable.
......@@ -378,18 +382,6 @@ You've just enabled DNSSEC, congratulations!
> trust_anchors.config('root.keys')
[trust_anchors] key: 19036 state: Valid
.. function:: trust_anchors.add(rr_string)
:param string rr_string: DS/DNSKEY records in presentation format (e.g. `. 3600 IN DS 19036 8 2 49AAC11...`)
Inserts DS/DNSKEY record(s) into current keyset. These will not be managed or updated.
Example output:
.. code-block:: lua
> trust_anchors.add('. 3600 IN DS 19036 8 2 49AAC11...')
.. function:: trust_anchors.set_insecure(nta_set)
:param table nta_list: List of domain names (text format) representing NTAs.
......@@ -408,6 +400,18 @@ You've just enabled DNSSEC, congratulations!
[1] => bad.boy
[2] => example.com
.. function:: trust_anchors.add(rr_string)
:param string rr_string: DS/DNSKEY records in presentation format (e.g. `. 3600 IN DS 19036 8 2 49AAC11...`)
Inserts DS/DNSKEY record(s) into current keyset. These will not be managed or updated.
Example output:
.. code-block:: lua
> trust_anchors.add('. 3600 IN DS 19036 8 2 49AAC11...')
Modules configuration
^^^^^^^^^^^^^^^^^^^^^
......
......@@ -30,7 +30,7 @@ The following is a list of software required to build Knot DNS Resolver from sou
"`GNU Make`_ 3.80+", "*all*", "*(build only)*"
"`pkg-config`_", "*all*", "*(build only)* [#]_"
"C compiler", "*all*", "*(build only)* [#]_"
"libknot_ 2.0+", "*all*", "Knot DNS library."
"libknot_ 2.0+", "*all*", "Knot DNS library (requires autotools, GnuTLS and Jansson)."
"LuaJIT_ 2.0+", "``daemon``", "Embedded scripting language (Lua_ 5.1+ with limitations)."
"libuv_ 1.0+", "``daemon``", "Multiplatform I/O and services."
......@@ -43,7 +43,6 @@ There are also *optional* packages that enable specific functionality in Knot DN
"hiredis_", "``modules/redis``", "To build redis backend module."
"cmocka_", "``unit tests``", "Unit testing framework."
"Python_", "``integration tests``", "For test scripts."
"GCCGO_", "``modules/go``", "For building Go modules, see modules documentation."
"Doxygen_", "``documentation``", "Generating API documentation."
"Sphinx_", "``documentation``", "Building this HTML/PDF documentation."
"breathe_", "``documentation``", "Exposing Doxygen API doc to Sphinx."
......
......@@ -13,6 +13,7 @@ Modular architecture of the library keeps the core tiny and efficient, and provi
lib
daemon
modules
modules_api
Indices and tables
......
.. include:: ../modules/README.rst
.. _modules-implemented:
Implemented modules
===================
*************************
Knot DNS Resolver modules
*************************
.. contents::
:depth: 1
......@@ -18,4 +17,4 @@ Implemented modules
.. include:: ../modules/kmemcached/README.rst
.. include:: ../modules/redis/README.rst
.. include:: ../modules/ketcd/README.rst
.. include:: ../modules/cachectl/README.rst
.. include:: ../modules/cachectl/README.rst
\ No newline at end of file
.. include:: ../modules/README.rst
\ No newline at end of file
****************************
Knot DNS Resolver extensions
****************************
.. _modules-api:
Writing extensions
==================
*********************
Modules API reference
*********************
.. contents::
:depth: 2
:depth: 1
:local:
Supported languages
-------------------
===================
Currently modules written in C and Lua are supported.
There is also a rudimentary support for writing modules in Go |---|
......@@ -19,7 +18,7 @@ There is also a rudimentary support for writing modules in Go |---|
(3) no coroutines and no garbage collecting thread, as the Go code is called from C threads.
The anatomy of an extension
---------------------------
===========================
A module is a shared object or script defining specific functions, here's an overview.
......@@ -45,61 +44,8 @@ This doesn't apply for Go, as it for now always implements `main` and requires c
If the module exports a layer implementation, it is automatically discovered by :c:func:`kr_resolver` on resolution init and plugged in. The order in which the modules are registered corresponds to the call order of layers.
Writing a module in C
---------------------
As almost all the functions are optional, the minimal module looks like this:
.. code-block:: c
#include "lib/module.h"
/* Convenience macro to declare module API. */
KR_MODULE_EXPORT(mymodule);
Let's define an observer thread for the module as well. It's going to be stub for the sake of brevity,
but you can for example create a condition, and notify the thread from query processing by declaring
module layer (see the :ref:`Writing layers <lib-layers>`).
.. code-block:: c
static void* observe(void *arg)
{
/* ... do some observing ... */
}
int mymodule_init(struct kr_module *module)
{
/* Create a thread and start it in the background. */
pthread_t thr_id;
int ret = pthread_create(&thr_id, NULL, &observe, NULL);
if (ret != 0) {
return kr_error(errno);
}
/* Keep it in the thread */
module->data = thr_id;
return kr_ok();
}
int mymodule_deinit(struct kr_module *module)
{
/* ... signalize cancellation ... */
void *res = NULL;
pthread_t thr_id = (pthread_t) module->data;
int ret = pthread_join(thr_id, res);
if (ret != 0) {
return kr_error(errno);
}
return kr_ok();
}
This example shows how a module can run in the background, this enables you to, for example, observe
and publish data about query resolution.
Writing a module in Lua
-----------------------
=======================
The probably most convenient way of writing modules is Lua since you can use already installed modules
from system and have first-class access to the scripting engine. You can also tap to all the events, that
......@@ -179,8 +125,61 @@ Since the modules are like any other Lua modules, you can interact with them thr
.. tip:: The module can be placed anywhere in the Lua search path, in the working directory or in the MODULESDIR.
Writing a module in C
=====================
As almost all the functions are optional, the minimal module looks like this:
.. code-block:: c
#include "lib/module.h"
/* Convenience macro to declare module API. */
KR_MODULE_EXPORT(mymodule);
Let's define an observer thread for the module as well. It's going to be stub for the sake of brevity,
but you can for example create a condition, and notify the thread from query processing by declaring
module layer (see the :ref:`Writing layers <lib-layers>`).
.. code-block:: c
static void* observe(void *arg)
{
/* ... do some observing ... */
}
int mymodule_init(struct kr_module *module)
{
/* Create a thread and start it in the background. */
pthread_t thr_id;
int ret = pthread_create(&thr_id, NULL, &observe, NULL);
if (ret != 0) {
return kr_error(errno);
}
/* Keep it in the thread */
module->data = thr_id;
return kr_ok();
}
int mymodule_deinit(struct kr_module *module)
{
/* ... signalize cancellation ... */
void *res = NULL;
pthread_t thr_id = (pthread_t) module->data;
int ret = pthread_join(thr_id, res);
if (ret != 0) {
return kr_error(errno);
}
return kr_ok();
}
This example shows how a module can run in the background, this enables you to, for example, observe
and publish data about query resolution.
Writing a module in Go
----------------------
======================
.. note:: At the moment only a limited subset of Go is supported. The reason is that the Go functions must run inside the goroutines, and *presume* the garbage collector and scheduler are running in the background. `GCCGO`_ compiler can build dynamic libraries, and also allow us to bootstrap basic Go runtime, including a trampoline to call Go functions. The problem with the ``layer()`` and callbacks is that they're called from C threads, that Go runtime has no knowledge of. Thus neither garbage collection or spawning routines can work. The solution could be to register C threads to Go runtime, or have each module to run inside its world loop and use IPC instead of callbacks |---| alas neither is implemented at the moment, but may be in the future.
......@@ -253,14 +252,14 @@ Now we can add the implementations for the ``Begin`` and ``Finish`` functions, a
See the CGO_ for more information about type conversions and interoperability between the C/Go.
Configuring modules
-------------------
===================
There is a callback ``X_config()`` that you can implement, see hints module.
.. _mod-properties:
Exposing C/Go module properties
-------------------------------
===============================
A module can offer NULL-terminated list of *properties*, each property is essentially a callable with free-form JSON input/output.
JSON was chosen as an interchangeable format that doesn't require any schema beforehand, so you can do two things - query the module properties
......@@ -309,7 +308,8 @@ Here's an example how a module can expose its property:
KR_MODULE_EXPORT(cache)
Once you load the module, you can call the module property from the interactive console:
Once you load the module, you can call the module property from the interactive console.
*Note* |---| the JSON output will be transparently converted to Lua tables.
.. code-block:: bash
......@@ -318,7 +318,7 @@ Once you load the module, you can call the module property from the interactive
[system] started in interactive mode, type 'help()'
> modules.load('cached')
> cached.get_size()
{ "size": 53 }
[size] => 53
*Note* |---| this relies on function pointers, so the same ``static inline`` trick as for the ``Layer()`` is required for C/Go.
......@@ -328,9 +328,6 @@ Special properties
If the module declares properties ``get`` or ``set``, they can be used in the Lua interpreter as
regular tables.
.. warning:: This is not yet completely implemented, as the module I/O format may change to map_t a/o
embedded JSON tokenizer.
.. _`not present in Go`: http://blog.golang.org/gos-declaration-syntax
.. _CGO: http://golang.org/cmd/cgo/
.. _GCCGO: https://golang.org/doc/install/gccgo
......
Markdown is supported
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