Skip to content
This repository has been archived by the owner on Sep 12, 2020. It is now read-only.

Commit

Permalink
rewrite for knot version 2.x. closes #3
Browse files Browse the repository at this point in the history
This rewrite breaks compatitiblity with Knot versions < 2.
It uses the new YAML configuration syntax and supports all
new features of versin 2.x. Including automatic DNSSEC
signing.
To upgrade from version 1 to version 2, all parameters need
to be checked and updated for version 2.
  • Loading branch information
tobru committed Dec 29, 2015
1 parent 0ee8082 commit 879e46e
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 410 deletions.
136 changes: 92 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ This Puppet module manages the [Knot DNS](https://www.knot-dns.cz/) server.
[![Build Status](https://travis-ci.org/tobru/puppet-knot.svg?branch=master)](https://travis-ci.org/tobru/puppet-knot)
[![tobru-knot](https://img.shields.io/puppetforge/v/tobru/knot.svg)](https://forge.puppetlabs.com/tobru/knot)

**Info: Module version 2.x is only compatible with Knot 2.x. If you're still on Knot 1.x, please
use the module version 1.x.**

## Module Description

Knot DNS server is a "High-performance authoritative-only DNS server". This Puppet module
Expand All @@ -33,19 +36,22 @@ It also manages the installation of the package and starting/restarting the syst
### What knot affects

* Package `knot` installation. If `manage_package_repo` is true, it also adds the
[official apt repository](https://www.knot-dns.cz/documentation/html/installation.html#installing-knot-dns-packages-on-debian) by using the [puppetlabs/apt](https://forge.puppetlabs.com/puppetlabs/apt) module
[official apt repository](https://www.knot-dns.cz/docs/2.0/html/installation.html#os-specific-installation) by using the [puppetlabs/apt](https://forge.puppetlabs.com/puppetlabs/apt) module
* Service `knot` starting and restarting on configuration change
* Writing of configuration files:
* `/etc/knot/knot.conf.puppet`
* `/etc/knot/zones.conf.puppet`
* Creation of the folders and managing of the user and group rights
on $zone_storage and $dnssec_keydir
on `$default_storage` and `$dnssec_keydir`
* Creation of Signing Policies

### Beginning with knot

A simple `include knot` installs Knot DNS from the default package source and creates a configuration
file with sane defaults. When starting Knot DNS it complains `warning: no zones loaded`, this tells
us that it would make sense to add some zones.
Please note: Your distro will most likely not yet include Knot 2.x. So you should set at least
the parameter `manage_package_repo` to true.

Adding zones is as simple as follows:
```
Expand All @@ -58,15 +64,13 @@ class { 'knot':
}
```

Zones will be added to `/etc/knot/zones.conf` with `file "mydomain.tld.zone";`.
This means that Knot DNS expects to find a standard zone file ([Wikipedia](http://en.wikipedia.org/wiki/Zone_file#File_format))
under `/var/lib/knot` (`storage` configuration directive under the `zones` section).
Zones will be added to `/etc/knot/zones.conf`.

*Note*: The paramter `zones` is a [hash](https://docs.puppetlabs.com/puppet/latest/reference/lang_datatypes.html#hashes)

## Usage

All parameter defaults are defined in `params.pp`. To pass a parameter to
All parameter defaults are defined in `params.pp` and `init.pp`. To pass a parameter to
the module, they need to be passed to the main class.
Here is a usage example for some parameters which most likely will be
changed by the module user:
Expand All @@ -79,9 +83,7 @@ $zones = {
'notify-out' => 'server1' },
}
class { 'knot':
manage_package_repo => false,
system => { 'version' => 'off' },
groups => { 'admins' => 'server0' },
manage_package_repo => true,
keys => { 'key0.server0' => {
'algorithm' => 'hmac-md5',
'key' => 'Wg==' }
Expand All @@ -100,61 +102,107 @@ to pass parameters to the module:

```
knot::manage_package_repo: true
knot::package_distcodename: 'wheezy'
knot::dnssec_enable: false
knot::system:
version: 'off'
knot::groups:
admins: 'server0'
knot::zones:
myzone.ch:
template: dnssec
_signing_policy: default_rsa
myotherzone.ch: {}
knot::server:
identity: 'noidentityhere'
knot::acls:
myacl1:
action: transfer
knot::control:
acl: myacl1
knot::remotes:
myremote1:
address: 127.0.0.1
key: key1
knot::templates:
dnssec:
dnssec-signing: on
storage: /var/lib/knot
zonefile-sync: -1
kasp-db: /var/lib/knot/kasp
file: /var/lib/knot/zones/%s.zone
_signing_policy: default_rsa
default:
storage: /var/lib/knot
file: /var/lib/knot/zones/%s.zone
knot::log:
syslog:
any: 'warning'
stderr:
any: 'error, warning'
server: 'info'
any: debug
knot::keys:
key0.server0:
algorithm: 'hmac-md5'
key: 'Wg=='
knot::remotes:
server0:
address: '127.0.0.1'
port: '53531'
key: 'key0.server0'
via: 'all_ipv4'
server1:
address: '127.0.0.1@53001'
knot::zone_defaults:
xfr-out: 'server0'
notify-out: 'server0'
knot::zones:
myzone.net:
myotherzone.com:
xfr-out: 'server1'
knot::manage_zones: true
key1:
algorithm: hmac-md5
secret: c0570d4931593d46333c9ddf15894a8550e131f4
key2:
algorithm: hmac-sha1
secret: c0570d4931593d46333c9ddf15894a8550e131f4
knot::signing_policies:
default_rsa:
algorithm: RSASHA256
zsk-size: 1024
ksk-size: 2048
knot::modules:
dnstap:
sink: unix://var/run/sink
synth-record:
type: forward
prefix: bla
origin: blubb.ch
```

*Note*: This is not a fully functional configuration, it's just here for an example
on how to use Hiera.

### Managing zones (and defaults for all zones)

Zones are passed to the main class in the `zones` hash. The configuration get's
written to `/etc/knot/zones.conf`.
To pass default values to all zones, the hash `zone_defaults` exists. Everything
in this hash is applied to all zones. If a parameter needs to be overwritten for
a single zone, just add this parameter to the zone, the zone parameters wins.
Since Knot 2.x gained the template functionality, this feature will most likely
only be used for setting a default template for all zones.

### Automatic DNSSEC signing

For an overview on how automatic DNSSEC signing works in Knot, see [official docs](https://www.knot-dns.cz/docs/2.0/html/configuration.html#automatic-dnssec-signing).
The Puppet module prepares the `DNSSEC KASP database` and is able to create signing
policies. Just pass a hash of policies to the parameter `signing_policies`.
Setting the special (Puppet module only) parameter `_signing_policy` to a name
of a signing policy under a zone or template will configure this policy to a zone.

Overview of file locations with the following template configured:
```
knot::templates:
dnssec:
dnssec-signing: on
storage: /var/lib/knot
zonefile-sync: -1
kasp-db: /var/lib/knot/kasp
file: /var/lib/knot/zones/%s.zone
_signing_policy: default_rsa
```

* Zonefiles: `/var/lib/knot/zones/%s.zone`
* KASP DB: `/var/lib/knot/kasp`
* Zone keys: `/var/lib/knot/kasp/keys`
* Timers: `/var/lib/knot/timers`
* Signed zones: Only in memory (`zonefile-sync` is -1) and under `/var/lib/knot/<zone>.db`

Using this configuration the directory `/var/lib/knot/zones` can be savely managed
with git.

## Reference

All parameters are documented inline. Have a look at `init.pp`

## Testing

The module has some small [smoke tests](https://docs.puppetlabs.com/guides/tests_smoke.html) available under the
`tests/` subdirectory. To execute them invoke Puppet using the following simple command
in the modules root path: `puppet apply --modulepath .. --noop tests/init.pp`

There are also rspec-puppet tests available. To run them you first need to install all
There are rspec-puppet tests available. To run them you first need to install all
needed GEMs by running bundler. Then a rake task executes the Rspec tests: `bundle exec rake spec`.

## Limitations
Expand Down
87 changes: 60 additions & 27 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,46 @@
class knot::config {

# get variables from the toplevel manifest for usage in the template
$config_file = $::knot::main_config_file
$zones_file = $::knot::zones_config_file
$keys = $::knot::keys
$remotes = $::knot::remotes
$groups = $::knot::groups
$zone_storage = $::knot::zone_storage
$config_file = $::knot::main_config_file
$default_storage = $::knot::default_storage
$dnssec_enable = $::knot::dnssec_enable
$dnssec_keydir = $::knot::dnssec_keydir
$service_user = $::knot::service_user
$manage_zones = $::knot::manage_zones
$service_group = $::knot::service_group
$service_user = $::knot::service_user
$signing_policies = $::knot::signing_policies
$zone_defaults = $::knot::zone_defaults
$zone_options = $::knot::zone_options
$zones = $::knot::zones
$manage_zones = $::knot::manage_zones
$zone_options = $::knot::zone_options
$zones_file = $::knot::zones_config_file

# knot configuration sections
$acls = $::knot::acls
$control = $::knot::control
$keys = $::knot::keys
$modules = $::knot::modules
$remotes = $::knot::remotes
$templates = $::knot::templates
$zones = $::knot::zones

# merge two hashes:
# * the configuration hash from the user calling $knot::config_*
# * the hash containing the default values in $knot::params::config_*
# When there is a duplicate key, the key in the user specified hash (rightmost) "wins"
# Note: this is not a deep merge, it merges only the toplevel keys
$system = merge($::knot::params::system, $::knot::system)
$log = merge($::knot::params::log, $::knot::log)
$interfaces = merge($::knot::params::interfaces, $::knot::interfaces)
$control = merge($::knot::params::control, $::knot::control)
$server = merge($::knot::params::server, $::knot::server)
$log = merge($::knot::params::log, $::knot::log)

file {
$config_file:
ensure => file,
owner => $service_user,
group => $service_group,
content => template('knot/knot.conf.erb');
$zone_storage:
ensure => directory,
owner => $service_user,
group => $service_group;
file { $config_file:
ensure => file,
owner => $service_user,
group => $service_group,
content => template('knot/knot.conf.erb'),
}
file { $default_storage:
ensure => directory,
owner => $service_user,
group => $service_group,
recurse => true,
}

if $manage_zones == false {
Expand All @@ -55,13 +60,41 @@
group => $service_group,
content => template('knot/zones.conf.erb');
}
if $dnssec_enable {
$_all_zones = keys($zones)
::knot::zone_policy { $_all_zones:
zones => $zones,
templates => $templates,
dnssec_keydir => $dnssec_keydir,
user => $service_user,
group => $service_group,
require => Exec['initialize_kasp'],
}
}
}

if $dnssec_enable {
$_signing_policy_names = keys($signing_policies)

file { $dnssec_keydir:
ensure => directory,
owner => $service_user,
group => $service_group,
ensure => directory,
owner => $service_user,
group => $service_group,
recurse => true,
} ->
exec { 'initialize_kasp':
command => '/usr/sbin/keymgr init',
creates => "${dnssec_keydir}/keys",
cwd => $dnssec_keydir,
user => $service_user,
group => $service_group,
require => Package[$::knot::package_name],
} ->
::knot::signing_policy { $_signing_policy_names:
data => $signing_policies,
dnssec_keydir => $dnssec_keydir,
user => $service_user,
group => $service_group,
}
}

Expand Down
Loading

0 comments on commit 879e46e

Please sign in to comment.