Commit 141eac9f authored by mrazekales's avatar mrazekales Committed by Ales Mrazek

basic structure

parent a45ea51c
.cache
.eggs
*.pyc
bin
dist
docs/_build
include
lib
lib64
MANIFEST
pip-selfcheck.json
pyvenv.cfg
TAGS
*.egg-info
PROJECT = resolvers_yang
VERSION = 0.1
.PHONY = tags deps install-deps
tags:
find $(PROJECT) -name "*.py" | etags -
deps:
mv requirements.txt requirements.txt.old
pip freeze > requirements.txt
install-deps:
pip install -r requirements.txt
# resolvers-yang
YANG data models and tools for unified configuration of DNS resolvers
\ No newline at end of file
# Resolvers-YANG
YANG data models and tools for unified configuration of DNS resolvers
Data model and library for DNS resolvers:
* [Knot Resolver](https://www.knot-resolver.cz/)
* [Unbound](https://www.unbound.net/)
* [PowerDNS](https://www.powerdns.com/)
* [BIND](https://www.isc.org/downloads/bind/)
## Data Model
* [Current schema tree](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/raw/master/data-model/model.tree)
* [Example JSON data](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/raw/master/tests/complete/example-data.json)
#### YANG Modules
* [cznic-dns-types](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/raw/master/yang-modules/cznic-dns-types@2018-05-14.yang)
* [cznic-resolver-common](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/raw/master/yang-modules/cznic-resolver-common@2018-07-27.yang)
* [cznic-resolver-knot](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/raw/master/yang-modules/cznic-resolver-knot@2018-07-27.yang)
## Getting Started
### Get Clone
```bash
$ git clone git@gitlab.labs.nic.cz:labs/resolvers-yang.git
$ cd resolvers-yang
```
### Requirements
**Python 3.5** or newer
```bash
$ sudo apt-get install python3
```
### Development
The recommended way is to use a Python virtual environment ([installation instructions](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/wikis/devinstall))
Then install dependencies
```bash
$ make install-deps
```
Adding new dependencies
```bash
$ make deps
```
### Installation
```bash
$ git clone https://gitlab.labs.nic.cz/jetconf/jetconf-resolver
$ cd jetconf-resolver
$ python3 setup.py install
```
## Example library usages
* [JSON Validation, Generate configuration, Convert from unbound.conf](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/wikis/examples)
## Links
* [Official Documentation]()
* [Wiki](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/wikis/home)
* [Deckard config](https://gitlab.labs.nic.cz/jetconf/jetconf-resolver/wikis/deckard)
\ No newline at end of file
hello.xml
model.xsl
MODULES = cznic-resolver-common cznic-resolver-knot cznic-deckard
DATE ?= $(shell date +%F)
xsldir = ../../yangson/tools/xslt
yypars = --stringparam date $(DATE)
yams = $(addsuffix .yang, $(MODULES))
.PHONY: all
all: $(yams)
%.yang: %.yinx
@xsltproc --xinclude $(xsldir)/canonicalize.xsl $< | \
xsltproc --output $@ $(yypars) $(xsldir)/yin2yang.xsl -
model.tree: $(yams)
@pyang $(PYANG_OPTS) -f tree -o $@ $^
module cznic-deckard {
yang-version "1.1";
namespace "https://www.nic.cz/ns/yang/deckard";
prefix "dcd";
import cznic-resolver-common {
prefix "drc";
}
organization
"CZ.NIC, z. s. p. o.";
contact
"Editor:   Ladislav Lhotka
          <mailto:lhotka@nic.cz>";
description
"This YANG module defines data for deckard test tool.";
revision 2018-07-27 {
description
"Initial revision.";
}
/* Data nodes */
container deckard {
description
"Parameters for deckard test tool.";
leaf mock-data {
type drc:fs-path;
description
"Name of the file containing mock data for the test DNS
server and client instructions.
This data is copied to the resulting RPL file.";
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<module name="cznic-deckard"
xmlns="urn:ietf:params:xml:ns:yang:yin:1"
xmlns:dcd="https://www.nic.cz/ns/yang/deckard"
xmlns:h="http://www.w3.org/1999/xhtml">
<namespace uri="https://www.nic.cz/ns/yang/deckard"/>
<prefix value="dcd"/>
<yang-version value="1.1"/>
<import module="cznic-resolver-common">
<prefix value="drc"/>
</import>
<organization>
<text>CZ.NIC, z. s. p. o.</text>
</organization>
<contact>
<text>
<h:p>
Editor:   Ladislav Lhotka<h:br/>
          &lt;mailto:lhotka@nic.cz&gt;
</h:p>
</text>
</contact>
<description>
<text>
This YANG module defines data for deckard test tool.
</text>
</description>
<revision date="2018-06-06">
<description>
<text>Initial revision.</text>
</description>
</revision>
<!-- Data nodes -->
<container name="deckard">
<description>
<text>Parameters for deckard test tool.</text>
</description>
<leaf name="mock-data">
<type name="drc:fs-path"/>
<description>
<text>
<h:p>Name of the file containing mock data for the test DNS
server and client instructions.</h:p>
<h:p>This data is copied to the resulting RPL file.</h:p>
</text>
</description>
</leaf>
</container>
</module>
module cznic-dns-types {
yang-version "1.1";
namespace "https://www.nic.cz/ns/yang/dns-types";
prefix "dns";
organization
"CZ.NIC, z. s. p. o.";
contact
"Editor:   Ladislav Lhotka
          <mailto:lhotka@nic.cz>";
description
"This YANG module defines common types related to DNS.";
revision 2018-05-14 {
description
"Initial revision.";
reference
"TODO: put git tag here";
}
/* Typedefs */
typedef domain-name {
type string {
length "1..253";
pattern "((\\*\\.)?(([a-zA-Z0-9_]([a-zA-Z0-9\\-/_]){0,61})?[a-zA-Z0-9]\\.)*([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)|"
+ "\\.";
}
}
}
module cznic-resolver-common {
yang-version "1.1";
namespace "https://www.nic.cz/ns/yang/resolver-common";
prefix "drc";
import ietf-inet-types {
prefix "inet";
}
organization
"CZ.NIC, z. s. p. o.";
contact
"Editor:   Ladislav Lhotka
          <mailto:lhotka@nic.cz>";
description
"This YANG module defines the common part of a data model for DNS
resolvers.";
revision 2018-07-27 {
description
"Initial revision.";
reference
"TODO: put git tag here";
}
/* Features */
feature set-group {
description
"This feature indicates support for setting the group.";
}
/* Typedefs */
typedef fs-path {
type string;
description
"This type is used for specifying a filesystem path (absolute
or relative).
An implementation must check that the string satisfies all
rules of the underlying operating system.";
}
typedef l2-protocol-selection {
type bits {
bit ipv4 {
description
"Enable/disable IPv4.";
}
bit ipv6 {
description
"Enable/disable IPv6.";
}
}
default "ipv4 ipv6";
}
/* Groupings */
grouping static-hint {
description
"This grouping defines the content of a static hint.";
leaf name {
type inet:domain-name;
description
"Domain name of a root server.";
}
leaf-list values {
type inet:ip-address-no-zone;
min-elements "1";
description
"One or more IPv4/IPv6 addresses of the root server.";
}
}
/* Data definitions */
container dns-resolver {
description
"DNS resolver parameters.";
container server {
description
"Parameters of the resolver process.";
leaf user-name {
type string;
description
"After binding the network socket, drop the privileges and
run with effective user ID of this user.";
}
leaf group-name {
if-feature "set-group";
type string;
description
"After binding the network socket, drop the privileges and
run with effective group ID of this group.";
}
}
container network {
description
"Network connection parameters.";
list listen-interfaces {
key "name";
unique "ip-address port";
description
"Inet sockets to use for listening to queries.";
leaf name {
type string;
description
"Arbitrary name of the listening socket.";
}
leaf ip-address {
type inet:ip-address;
mandatory "true";
description
"IPv4 or IPv6 address.";
}
leaf port {
type inet:port-number;
default "53";
description
"Port number.";
}
}
container source-address {
leaf ipv4 {
type inet:ipv4-address-no-zone;
description
"IPv4 address to use as the source address in outgoing
queries.
If not configured, the resolver uses any address
provided by the operationg system.";
}
leaf ipv6 {
type inet:ipv6-address-no-zone;
description
"IPv6 address to use as the source address in outgoing
queries.
If not configured, the resolver uses any address
provided by the operationg system.";
}
}
container client-transport {
description
"Specify L2 and L3 protocols used for receiving and
answering client queries.";
leaf l2-protocols {
type l2-protocol-selection;
description
"L2 protocols used for receiving and answering client
queries.";
}
}
container recursion-transport {
description
"Specify L2 and L3 protocols used for recursive queries.";
leaf l2-protocols {
type l2-protocol-selection;
description
"L2 protocols used for recursive queries.";
}
}
leaf udp-payload-size {
type uint16 {
range "512..max";
}
units "octets";
default "4096";
description
"Largest UDP payload that the resolver can accept.
This value is advertized in EDNS0.";
reference
"RFC 2671: Extension Mechanisms for DNS (EDNS0)";
}
}
container resolver {
description
"Parameters affecting operation of the DNS resolver.";
list stub-zones {
key "domain";
description
"List of stub zones.";
leaf domain {
type inet:domain-name;
description
"Name of the stub zone.";
}
leaf nameserver {
type inet:host;
description
"Name or IP address of the stub zone nameserver.";
}
leaf port {
type inet:port-number;
default "53";
description
"Port number to use for communicating with the stub zone
nameserver.";
}
}
container hints {
description
"Configuration of static hints.";
list root-hint {
key "name";
description
"Each entry contains hints for one root server.
Records configured this way override the resolver
defaults and records set via 'root-zone-file'.
Root hints are used if and only if the root servers
cannot be resolved from the cache.";
uses static-hint;
}
leaf root-zone-file {
type fs-path;
description
"Path to a root zone file.
It is used only if root servers cannot be resolved the
cache and no root hints are set via 'root-hint'.";
}
}
container options {
description
"Fine-tuning parameters of resolver operation.";
leaf glue-checking {
type enumeration {
/* TODO: add descriptions of the enums */
enum strict;
enum normal;
enum permissive;
}
description
"Level of strictness in accepting glue records.";
}
leaf qname-minimisation {
type boolean;
description
"Send minimum amount of information in recursive queries
to enhance privacy.";
}
leaf query-loopback {
type boolean;
default "true";
description
"This flag permits queries to loopback addresses (prefix
127.0.0.0/8 for IPv4 and ::1/128 for IPv6).";
}
leaf reorder-rrset {
type boolean;
default "false";
description
"Controls whether resource records within a RRSet are
reordered each time it is served from the cache.";
}
}
}
container logging {
description
"Logging parameters.";
leaf verbosity {
type uint8 {
range "0..5";
}
default "1";
description
"Verbosity level.";
}
}
container dnssec {
presence "Enable DNSSEC";
description
"DNSSEC parameters";
container trust-anchors {
description
"Parameters of DNSSEC trust anchors.";
list key-files {
key "domain";
description
"DNSSEC trust anchor files.
Each file is expected to
These files should exist and contain trust anchors (DS
or DNSKEY recors) for a single domain. The only
exception is the file for the root domain (key '.'): if
it doesn't exist, it will be populated from the IANA
website.";
leaf domain {
type inet:domain-name;
description
"The domain for which the trust anchor file is used.";
}
leaf file {
type fs-path;
description
"Name of the trust anchor file.";
}
leaf read-only {
type boolean;
default "false";
description
"Setting this flag to true blocks updates according to
RFC 5011 for this file.";
}
}
}
leaf-list negative-trust-anchors {
type inet:domain-name;
description
"List of domain names representing negative trust
anchors.";
reference
"RFC 7646: Definition and Use of DNSSEC Negative Trust
Anchors.";
}
}
container cache {
description
"Parameters of the resolver cache.";
leaf max-size {
type uint64;
units "bytes";
description
"Maximum size of the cache.";
}
leaf current-size {
type uint64;
units "bytes";
config "false";
description
"Current size of the cache.";
}
leaf max-ttl {
type uint32;
units "seconds";
default "172800";
description
"Maximum time-to-live for cache entries.
This value overrides the original TTL specified for the
particular resource record if the latter is greater.";
}
leaf min-ttl {
type uint32;
units "seconds";
must ". <= ../max-ttl" {
error-message
"'min-ttl' must not be higher than 'max-ttl'";
}
default "0";
description
"Minimum time-to-live for cache entries.
This value overrides the original TTL specified for the
particular resource record if the latter is smaller.";
}
}
container dns64 {
presence "enable DNS64 functionality";
leaf prefix {
type inet:ipv6-prefix;
default "64:ff9b::/96";
description
"The DNS64 prefix to be used for synthesizing AAAA records.
The prefix must be /96 or shorter.";
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<module name="cznic-resolver-common"
xmlns="urn:ietf:params:xml:ns:yang:yin:1"
xmlns:drc="https://www.nic.cz/ns/yang/resolver-common"
xmlns:h="http://www.w3.org/1999/xhtml">
<namespace uri="https://www.nic.cz/ns/yang/resolver-common"/>
<prefix value="drc"/>
<yang-version value="1.1"/>
<import module="ietf-inet-types">
<prefix value="inet"/>
</import>
<organization>
<text>CZ.NIC, z. s. p. o.</text>
</organization>
<contact>
<text>
<h:p>
Editor:   Ladislav Lhotka<h:br/>
          &lt;mailto:lhotka@nic.cz&gt;
</h:p>
</text>
</contact>
<description>
<text>
This YANG module defines the common part of a data model for DNS
resolvers.
</text>
</description>
<revision date="2018-04-16">
<description>
<text>Initial revision.</text>
</description>
<reference>
<text>TODO: put git tag here</text>
</reference>
</revision>
<!-- Features -->
<feature name="set-group">
<description>
<text>This feature indicates support for setting the
group.</text>
</description>
</feature>
<!-- Typedefs -->
<typedef name="fs-path">
<description>
<text>
<h:p>This type is used for specifying a
filesystem path (absolute or relative).</h:p>
<h:p>An implementation must check that the string satisfies
all rules of the underlying operating system.</h:p>
</text>
</description>
<type name="string"/>
</typedef>
<typedef name="l2-protocol-selection">
<type name="bits">
<bit name="ipv4">
<description>
<text>Enable/disable IPv4.</text>
</description>
</bit>
<bit name="ipv6">
<description>
<text>Enable/disable IPv6.</text>
</description>
</bit>
</type>
<default value="ipv4 ipv6"/>
</typedef>
<!-- Groupings -->
<grouping name="static-hint">
<description>
<text>This grouping defines the content of a static hint.</text>
</description>
<leaf name="name">
<type name="inet:domain-name"/>
<description>
<text>Domain name of a root server.</text>
</description>
</leaf>
<leaf-list name="values">
<type name="inet:ip-address-no-zone"/>
<min-elements value="1"/>
<description>
<text>One or more IPv4/IPv6 addresses of the root
server.</text>
</description>
</leaf-list>
</grouping>
<!-- Data definitions -->
<container name="dns-resolver">
<description>
<text>DNS resolver parameters.</text>
</description>
<container name="server">
<description>
<text>Parameters of the resolver process.</text>
</description>
<leaf name="user-name">
<type name="string"/>
<description>
<text>After binding the network socket, drop the privileges
and run with effective user ID of this user.</text>
</description>
</leaf>
<leaf name="group-name">
<if-feature name="set-group"/>
<type name="string"/>
<description>
<text>After binding the network socket, drop the privileges