1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

NEW FEATURE: Support Split Horizon DNS (#1034)

* Implement main feature
* BIND: Permit printf-like file name formats
* BIND: Make filenameformat work forwards and backwards.
* Fix extrator test cases
This commit is contained in:
Tom Limoncelli
2021-02-05 12:12:45 -05:00
committed by GitHub
parent 36289f7157
commit c547beacc0
11 changed files with 612 additions and 24 deletions

View File

@@ -42,6 +42,56 @@ D("example.com", REGISTRAR, DnsProvider(r53),
CNAME("test", "foo.example2.com."),
GOOGLE_APPS_DOMAIN_MX
);
{%endhighlight%}
{% include endExample.html %}
# Split Horizon DNS
DNSControl supports Split Horizon DNS. Simply
define the domain two or more times, each with
their own unique parameters.
To differentiate the different domains, specify the domains as
`domain.tld!tag`, such as `example.com!inside` and
`example.com!outside`.
{% include startExample.html %}
{% highlight js %}
var REG = NewRegistrar("Third-Party", "NONE");
var DNS_INSIDE = NewDnsProvider("Cloudflare", "CLOUDFLAREAPI");
var DNS_OUTSIDE = NewDnsProvider("bind", "BIND");
D("example.com!inside", REG, DnsProvider(DNS_INSIDE),
A("www", "10.10.10.10")
);
D("example.com!outside", REG, DnsProvider(DNS_OUTSIDE),
A("www", "20.20.20.20")
);
D_EXTEND("example.com!inside",
A("internal", "10.99.99.99")
);
{%endhighlight%}
{% include endExample.html %}
A domain name without a `!` is assigned a tag that is the empty
string. For example, `example.com` and `example.com!` are equivalent.
However, we strongly recommend against using the empty tag, as it
risks creating confusion. In other words, if you have `domain.tld`
and `domain.tld!external` you now require humans to remember that
`domain.tld` is the external one. I mean... the internal one. You
may have noticed this mistake, but will your coworkers? Will you in
six months? You get the idea.
DNSControl command line flag `--domains` is an exact match. If you
define domains `example.com!george` and `example.com!john` then:
* `--domains=example.com` will not match either domain.
* `--domains='example.com!george'` will match only match the first.
* `--domains='example.com!george',example.com!john` will match both.
NOTE: The quotes are required if your shell treats `!` as a special
character, which is probably does. If you see an error that mentions
`event not found` you probably forgot the quotes.

View File

@@ -18,11 +18,13 @@ you can specify a `directory` where the provider will look for and create zone f
{% highlight json %}
{
"bind": {
"directory": "myzones"
"directory": "myzones",
"filenameformat": "%U.zone" << The default
}
}
{% endhighlight %}
The BIND accepts some optional metadata via your DNS config when you create the provider:
In this example we set the default SOA settings and NS records.
@@ -46,15 +48,55 @@ var BIND = NewDnsProvider('bind', 'BIND', {
})
{% endhighlight %}
# filenameformat
The `filenameformat` parameter specifies the file name to be used when
writing the zone file. The default is acceptable in most cases: the
name as specified in the `D()` function, plus ".zone".
The filenameformat is a string with a few printf-like `%` verbs:
* `%U` the domain name as specified in `D()`
* `%D` the domain name without any split horizon tag
* `%T` the split horizon tag, or "", see `D()`
* `%?x` this returns `x` if the split horizon tag is non-null, otherwise nothing. `x` can be any printable.
* `%%` `%`
* ordinary characters (not `%`) are copied unchanged to the output stream
* FYI: format strings must not end with an incomplete `%` or `%?`
* FYI: `/` or other filesystem separators result in undefined behavior
Typical values:
* `%U.zone` (The default)
* `example.com.zone` or `example.com!tag.zone`
* `%T%*U%D.zone` (optional tag and `_` + domain + `.zone`)
* `tag_example.com.zone` or `example.com.zone`
* `db_%T%?_%D`
* `db_inside_example.com` or `db_example.com`
* `db_%D`
* `db_example.com`
The last example will generate the same name for both
`D("example.tld!inside")` and `D("example.tld!outside")`. This
assumes two BIND providers are configured in `creds.json`, eacch with
a different `directory` setting. Otherwise `dnscontrol` will write
both domains to the same file, flapping between the two back and
forth.
# FYI: get-zones
When used with "get-zones", specifying "all" scans the directory for
The dnscontrol `get-zones all` subcommand scans the directory for
any files named `*.zone` and assumes they are zone files.
```
dnscontrol get-zones --format=nameonly - BIND all
```
If `filenameformat` is defined, `dnscontrol` makes an guess at which
filenames are zones but doesn't try to hard to get it right, which is
mathematically impossible in all cases. Feel free to file an issue if
your format string doesn't work. I love a challenge!
# FYI: SOA Records
DNSControl assumes that SOA records are managed by the provider. Most