README.md 5.91 KB
Newer Older
ale's avatar
ale committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
zonetool
========

zonetool is a tool to reduce the pain of managing potentially large
collections of DNS zone files. It offers a simple declarative syntax,
and semantics to merge manual configuration and automated output from
arbitrary sources. It supports templates and inheritance as a way to
simplify large deployments.

The basic entity of the data model is a dictionary corresponding to a
DNS zone. The dictionary key/value pairs correspond to individual DNS
resource records. Some keys are special: they define attributes of the
zone itself - they are usually recognizable because they're uppercase
(while normal DNS record names are lowercase).

## Configuration

The zone configuration is stored in YAML format, usually spread into
multiple files, one per template or zone (though it is possible to store
the configuration for more than one zone in a single YAML file). By
default, the tool scans a given directory recursively looking for files
with the *.yml* extension. File names are ignored and only have a
mnemonic purpose.

### Record syntax

A DNS entry consists of a name and one or more resource records, so in
our model the dictionary values can be either strings, or lists of
strings (a single string is just a shorthand syntax for a list
containing a single element). All names are relative to the zone origin,
except for the special name consisting of a single underscore (`_`),
which stands for the zone origin itself.

Each resource record consists of a DNS RR type, and the associated data,
separated by a space (the resource data can contain further spaces). The
resource record will be written verbatim to the resulting zone file (the
*IN* namespace is assumed), for example:

```yaml
inventati.org:
  _:
    - A 1.2.3.4
    - AAAA 2001:1:2:3::4
    - MX 10 mx1.inventati.org.
```

describes three different DNS records, all for the zone origin: one IPv4
address, an IPv6 one, and a MX record for SMTP delivery.

Since A and AAAA records are usually the most common by far, a special
shorthand notation allows you to simply specify the IP address, and the
record type will be automatically determined. So, the above zone could
have been written as:

```yaml
inventati.org:
  _:
    - 1.2.3.4
    - 2001:1:2:3::4
    - MX 10 mx1.inventati.org.
```

### Templates and inheritance

Each zone can have an *EXTENDS* attribute, which contains a list of zone
names that will be merged into the current one. It is possible to use
this feature as a full-blown templating system by taking advantage of
the fact that zones whose name starts with a *@* are not going to be
present in the output. In fact, one such zone is always defined:
*@default* (empty by default), and it is automatically added to the
*EXTENDS* attribute of every zone that does **not** start with a *@*
character.

Perhaps some examples can clarify the mechanism:

```yaml
autistici.org:
  www: 1.2.3.4
inventati.org:
  www: 2.3.4.5
"@default":
  _:
    - NS ns1.example.com.
    - NS ns2.example.com.
```

In the above case, the two zones defined will both have NS records
pointing at *ns1.example.com* and *ns2.example.com*.

Another example:

```yaml
autistici.org:
  EXTENDS:
ale's avatar
ale committed
95
    - "@base"
ale's avatar
ale committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
  www: 1.2.3.4
"@base":
  _spf: TXT "v=spf1 -all"
"@default":
  _: NS ns1.example.com.
```

here the *autistici.org* zone will not only include the NS record from
*@default*, but it will also contain the *_spf* TXT record from the
*@base* template.

### Special zone attributes

Besides EXTENDS described above, there are a few other special
attributes that can be set on a zone. They are recognizable from normal
records because they are specified in uppercase:

* `TTL` sets the TTL for the zone
* `REFRESH` sets the SOA refresh time
* `RETRY` sets the SOA retry time
* `EXPIRE` sets the SOA expire time
ale's avatar
ale committed
117
* `NEG_CACHE` sets the SOA negative caching time
ale's avatar
ale committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

By default, generated zones will have a TTL of 1 hour.

### Variable substitution and configuration

Along with the zone dictionaries, it is also possible to specify
arbitrary resource records in a global *configuration*: these records
are not associated with a specific zone, and they can be substituted
in-place using a shell-like variable expansion syntax.

For instance, assume that you have a list of IPs which appear in
multiple records in your DNS zones: it would be nice to maintain the
full list in a single place. So, if your configuration contains:

```
FRONTENDS = ['1.2.3.4', '2.3.4.5']
```

it is then possible to define a zone as follows:

```yaml
autistici.org:
ale's avatar
ale committed
140 141
  _: $FRONTENDS
  www: $FRONTENDS
ale's avatar
ale committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155
```

The tool will try to do the right thing when expanding list variables,
whether within a list or not. For instance, a zone such as:

```yaml
autistici.org:
  _:
    - $SERVERS
    - MX 10 $SERVERS
```

will result in a zone containing an A record and an MX record for each
entry defined in *SERVERS*.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

## Usage

The *zonetool* command-line tool is invoked by passing the YAML zone
configs as arguments, e.g.:

```
zonetool zone1.yml zone2.yml
```

It's possible to specify a global configuration file to define global
variables with the *--config* flag.

This will by default generate the output Bind zone files in the
current directory, which is probably not what you want. To set the
output directory use the *--output-dir* option. If necessary, zonetool
can take over full control of the *--output-dir* directory, and delete
files in it that are no longer used (old zones that have been
removed), by specifying the *--delete* option.

For convenience, the tool will also generate a *named.conf* file to
load the zones, whose location can be controlled using the
*--named-conf* option. This makes certain assumptions on the Bind
setup: the generated config will create *master* zones with
*allow-query* set to *any*. It is possible to set *update-policy*
attributes on the zone configs by passing one or more
*--update-policy* flags: the same values will apply to all zones.

Finally, there are a number of options to control DNSSEC generation,
documented in more detail by *zonetool --help*.