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 as follows: ``` zone "c1.k8s.ooo" { type forward; forward only; forwarders { 2a0a:e5c0:2:f::a; }; }; ``` ### Step 4: adjusting the zone file In case you are running an IPv6 only server, you need to configure the upstream DNS server. In our case this looks as follows: ``` ; The domain: c1.k8s.ooo c1 NS kube-dns.kube-system.svc.c1 ; The IPv6 only DNS server kube-dns.kube-system.svc.c1 AAAA 2a0a:e5c0:2:f::a ; The forwarding IPv4 server kube-dns.kube-system.svc.c1 A 194.5.220.43 ``` ## DNS, IPv6, Kubernetes? If you are curious to learn more about either of these topics, feel [free to join us on our chat](/u/projects/open-chat/).