103 lines
2.7 KiB
Text
103 lines
2.7 KiB
Text
|
title: Configuring bind to only forward DNS to a specific zone
|
||
|
---
|
||
|
pub_date: 2021-07-25
|
||
|
---
|
||
|
author: ungleich
|
||
|
---
|
||
|
twitter_handle: ungleich
|
||
|
---
|
||
|
_hidden: no
|
||
|
---
|
||
|
_discoverable: yes
|
||
|
---
|
||
|
abstract:
|
||
|
Want to use BIND for proxying to another server? This is how you do it.
|
||
|
---
|
||
|
body:
|
||
|
|
||
|
## Introduction
|
||
|
|
||
|
In this article we'll show you an easy solution to host DNS zones on
|
||
|
IPv6 only or private DNS servers. The method we use here is **DNS
|
||
|
forwarding** as offered in ISC BIND, but one could also see this as
|
||
|
**DNS proxying**.
|
||
|
|
||
|
## Background
|
||
|
|
||
|
Sometimes you might have a DNS server that is authoritative for DNS
|
||
|
data, but is not reachable for all clients. This might be the case for
|
||
|
instance, if
|
||
|
|
||
|
* your DNS server is IPv6 only: it won't be directly reachable from
|
||
|
the IPv4 Internet
|
||
|
* your DNS server is running in a private network, either IPv4 or IPv6
|
||
|
|
||
|
In both cases, you need something that is publicly reachable, to
|
||
|
enable clients to access the zone, like show in the following picture:
|
||
|
|
||
|
![](dns-proxy-forward.png)
|
||
|
|
||
|
## The problem: Forwarding requires recursive queries
|
||
|
|
||
|
ISC Bind allows to forward queries to another name server. However to
|
||
|
do so, it need to be configured to allow handling recursive querying.
|
||
|
However, if we allow recursive querying by any client, we basically
|
||
|
create an [Open DNS resolver, which can be quite
|
||
|
dangerous](https://www.ncsc.gov.ie/emailsfrom/DDoS/DNS/).
|
||
|
|
||
|
## The solution
|
||
|
|
||
|
ISC Bind by default has a root hints file compiled in, which allows it
|
||
|
to function as a resolver without any additional configuration
|
||
|
files. That is great, but not if you want to prevent it to work as
|
||
|
forwarder as described above. But we can easily fix that problem. Now,
|
||
|
let's have a look at a real world use case, step-by-step:
|
||
|
|
||
|
### Step 1: Global options
|
||
|
|
||
|
In the first step, we need to set the global to allow recursion from
|
||
|
anyone, as follows:
|
||
|
|
||
|
```
|
||
|
options {
|
||
|
directory "/var/cache/bind";
|
||
|
|
||
|
listen-on-v6 { any; };
|
||
|
|
||
|
allow-recursion { ::/0; 0.0.0.0/0; };
|
||
|
};
|
||
|
```
|
||
|
|
||
|
However as mentioned above, this would create an open resolver. To
|
||
|
prevent this, let's disable the root hints:
|
||
|
|
||
|
### Step 2: Disable root hints
|
||
|
|
||
|
The root hints are served in the root zone, also know as ".". To
|
||
|
disable it, we give bind an empty file to use:
|
||
|
|
||
|
```
|
||
|
zone "." {
|
||
|
type hint;
|
||
|
file "/dev/null";
|
||
|
};
|
||
|
```
|
||
|
|
||
|
Note: in case you do want to allow recursive function for some
|
||
|
clients, **you can create multiple DNS views**.
|
||
|
|
||
|
### Step 3: The actual DNS file
|
||
|
|
||
|
In our case, we have a lot of IPv6 only kubernetes clusters, which are
|
||
|
named `xx.k8s.ooo` and have a world wide rachable CoreDNS server built
|
||
|
in. In this case, we want to allow the domain c1.k8s.ooo to be world
|
||
|
reachable, so we configure the dual stack server
|
||
|
|
||
|
```
|
||
|
zone "c1.k8s.ooo" {
|
||
|
type forward;
|
||
|
forward only;
|
||
|
forwarders { 2a0a:e5c0:2:f::a; };
|
||
|
};
|
||
|
```
|