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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user