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

doc/daemon: written config documentation

parent 14780a2d
************************
Knot DNS Resolver daemon
************************
Requirements
============
* libuv_ 1.0+ (a multi-platform support library with a focus on asynchronous I/O)
* Lua_ 5.1+ (embeddable scripting language, LuaJIT_ is preferred)
Running
=======
There is a separate resolver library in the `lib` directory, and a minimalistic daemon in
the `daemon` directory.
.. code-block:: bash
$ ./daemon/kresolved -h
Interacting with the daemon
---------------------------
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.
.. code-block:: bash
$ kresolved /var/run/knot-resolver
[system] started in interactive mode, type 'help()'
> cache.count()
53
.. role:: lua(code)
:language: lua
Configuration
=============
.. contents::
:depth: 2
:local:
In it's simplest form it requires just a working directory in which it can set up persistent files like
cache and the process state. If you don't provide the working directory by parameter, it is going to make itself
comfortable in the current working directory.
.. code-block:: sh
$ kresolved /var/run/kresolved
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.
Configuration example
---------------------
.. code-block:: lua
-- 10MB cache
cache.open(10*MB)
-- static hints
modules = {
hints = true,
cachectl = true
}
-- interfaces
net.listen('127.0.0.1')
Configuration syntax
--------------------
The configuration is kept in the ``config`` file in the daemon working directory, and it's going to get loaded automatically.
If there isn't one, the daemon is going to start with sane defaults, listening on `localhost`.
The syntax for options is like follows: ``group.option = value`` or ``group.action(parameters)``.
You can also comment using a ``--`` prefix.
A simple example would be to load static hints.
.. code-block:: lua
modules = {
cachectl = true -- no configuration
}
If the module accepts accepts configuration, you can provide a table.
The syntax for table is ``{ key1 = value, key2 = value }``, and it represents the unpacked `JSON-encoded`_ string, that
the modules use as the :ref:`input configuration <mod-properties>`.
.. code-block:: lua
modules = {
cachectl = true,
hints = {
file = '/etc/hosts'
}
}
The possible simple data types are strings, integers or floats and boolean.
.. tip:: The configuration and CLI syntax is Lua language, with which you may already be familiar with.
If not, you can read the `Learn Lua in 15 minutes`_ for a syntax overview. Spending just a few minutes
will allow you to break from static configuration, write more efficient configuration with iteration, and
leverage events and hooks. Lua is heavily used for scripting in applications ranging from embedded to game engines,
but in DNS world notably in `PowerDNS Recursor`_. Knot DNS Resolver does not simply use Lua modules, but it is
the heart of the daemon for everything from configuration, internal events and user interaction.
Dynamic configuration
^^^^^^^^^^^^^^^^^^^^^
Knowing that the the configuration is a valid Lua script enables you to write dynamic rules, and also avoid
additional configuration templating. One example is to differentiate between internal and external
interfaces based on environment variable.
.. code-block:: lua
if hostname() == 'hidden' then
net.listen(net.eth0)
else
net.listen(net.eth1.addr[1])
end
Another example would show how it is possible to bind to all interfaces, using iteration.
.. code-block:: lua
for name, addr_list in pairs(net.interfaces()) do
net.listen(addr_list)
end
You can also use third-party packages (available for example through LuaRocks_) as on this example
to download cache from parent, to avoid cold-cache start.
.. code-block:: lua
local http = require('socket.http')
local ltn12 = require('ltn12')
if cache.count() == 0 then
-- download cache from parent
http.request {
url = 'http://parent/cache.mdb',
sink = ltn12.sink.file(io.open('cache.mdb', 'w'))
}
-- reopen cache with 100M limit
cache.open('.', 100*MB)
end
Events and services
^^^^^^^^^^^^^^^^^^^
The Lua supports a concept called closures, this is extremely useful for scripting actions upon various events.
.. note:: Work in progress, come back later!
* Timers and events
* File watchers
* Data I/O
Configuration reference
-----------------------
This is a reference for variables and functions available to both configuration file and CLI.
Environment
^^^^^^^^^^^
.. envvar:: env (table)
Return environment variable.
.. code-block:: lua
env.USER -- equivalent to $USER in shell
.. function:: hostname()
:return: Machine hostname.
Network configuration
^^^^^^^^^^^^^^^^^^^^^
.. function:: net.listen(address, [port = 53])
:return: boolean
Listen on address, port is optional.
.. function:: net.listen({address1, ...}, [port = 53])
:return: boolean
Listen on list of addresses.
.. function:: net.listen(interface, [port = 53])
:return: boolean
Listen on all addresses belonging to an interface.
Example:
.. code-block:: lua
net.listen(net.eth0) -- listen on eth0
.. function:: net.close(address, [port = 53])
:return: boolean
Close opened address/port pair, noop if not listening.
.. function:: net.list()
:return: Table of bound interfaces.
Example output:
.. code-block:: lua
[127.0.0.1] => {
[port] => 53
[tcp] => true
[udp] => true
}
.. function:: net.interfaces()
:return: Table of available interfaces and their addresses.
Example output:
.. code-block:: lua
[lo0] => {
[addr] => {
[1] => ::1
[2] => 127.0.0.1
}
[mac] => 00:00:00:00:00:00
}
[eth0] => {
[addr] => {
[1] => 192.168.0.1
}
[mac] => de:ad:be:ef:aa:bb
}
.. tip:: You can use ``net.<iface>`` as a shortcut for specific interface, e.g. ``net.eth0``
Modules configuration
^^^^^^^^^^^^^^^^^^^^^
The daemon provides an interface for dynamic loading of :ref:`daemon modules <modules-implemented>`.
.. tip:: Use syntactic sugar for module loading. Declaring a variable ``modules`` equals to loading a table of modules.
.. code-block:: lua
modules = { hints = {file = '/etc/hosts'} }
Equals to:
.. code-block:: lua
modules.load('cachectl')
cachectl.config({file = '/etc/hosts'})
.. function:: modules.list()
:return: List of loaded modules.
.. function:: modules.load(name)
:param string name: Module name, e.g. "hints"
:return: boolean
Load a module by name.
.. function:: modules.unload(name)
:param string name: Module name
:return: boolean
Unload a module by name.
Cache configuration
^^^^^^^^^^^^^^^^^^^
The cache in Knot DNS Resolver is persistent with LMDB backend, this means that the daemon doesn't lose
the cached data on restart or crash to avoid cold-starts. Interestingly the cache may be reused between cache
daemons or manipulated from other processes, making for example synchronisation between load-balanced recursors possible.
.. function:: cache.open(max_size)
:param number max_size: Maximum cache size in bytes.
:return: boolean
Open cache with size limit. The cache will be reopened if already open.
Note that the max_size cannot be lowered, only increased due to how cache is implemented.
.. tip:: Use ``kB, MB, GB`` constants as a multiplier, e.g. ``100*MB``.
.. function:: cache.count()
:return: Number of entries in the cache.
.. function:: cache.close()
:return: boolean
Close the cache.
.. _`JSON-encoded`: http://json.org/example
.. _`Learn Lua in 15 minutes`: http://tylerneylon.com/a/learn-lua/
.. _`PowerDNS Recursor`: https://doc.powerdns.com/md/recursor/scripting/
.. _LuaRocks: https://rocks.moonscript.org/
.. _libuv: https://github.com/libuv/libuv
.. _Lua: http://www.lua.org/about.html
.. _LuaJIT: http://luajit.org/luajit.html
\ No newline at end of file
Daemon configuration
--------------------
The Knot DNS Resolver daemon has no traditional concept of static configuration.
In it's simplest form it requires just a working directory in which it can set up persistent files like
cache and the process state.
.. code-block:: sh
$ kresolved /var/run/kresolved
And you're good to go!
Introduction
~~~~~~~~~~~~
There are several choices on how you can configure the daemon, a RPC interface a CLI or a configuration file,
but fortunately all share a common syntax and are transparent to each other, e.g. if you change a knob, you're going to
see it projected to other interfaces as well.
.. note:: Expect this page to change a lot, as it's still just a proof of concept implementation.
Configuration 101
~~~~~~~~~~~~~~~~~
If there is a `config` file in the daemon working directory, it's going to get loaded automatically, if there isn't one
the daemon is going to start with sane defaults and listening on `localhost`. The syntax for options is like follows: ``group.option = value``
or ``group.action(parameters)``. You can also comment using a ``--`` prefix.
A simple example would be to increase the cache size.
.. code-block:: lua
-- increase the cache to 100MB
cache.open(".", 100*1024*1024)
Dynamic configuration
~~~~~~~~~~~~~~~~~~~~~
Packages and services
~~~~~~~~~~~~~~~~~~~~~
The Lua supports a concept called closures, this is extremely useful for scripting actions upon various events.
.. note:: TODO, come back later!
* Timers and events
* File watchers
* Serialization
* Data I/O
Knot DNS Resolver daemon
========================
Requirements
------------
* libuv_ 1.0+ (a multi-platform support library with a focus on asynchronous I/O)
Starting the daemon
-------------------
There is a separate resolver library in the `lib` directory, and a minimalistic daemon in
the `daemon` directory. The daemon accepts a few CLI parameters, and there's no support for configuration
right now.
.. code-block:: bash
$ ./daemon/kresolved -h
$ ./daemon/kresolved -a 127.0.0.1#53
.. _libuv: https://github.com/libuv/libuv
Interacting with the daemon
---------------------------
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.
.. code-block:: bash
$ kresolved /var/run/knot-resolver
...
[system] started in interactive mode, type 'help()'
> modules.load('cachectl')
> return cachectl.size()
{ "size": 53 }
\ No newline at end of file
.. include:: ../daemon/README.rst
\ No newline at end of file
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