Configuring my BIND/named DNS servers to operate from a hidden master via VPN for Let’s Encrypt

What is a hidden DNS master? If you need to ask that, this is not the blog post for you.

This post assumes you already know how to configure DNS and just want ideas for your own hidden master. It also assumes the networking, VPN, and firewall are pre-configured for this.

This blog post is mostly about named/BIND.

For the record, I am using bind99-9.9.10P1.

In my previous blog post, you’ll see how I configured my hidden DNS master to accept incoming updates from nsupdate. This was my first step in creating a centralized Let’s Encrypt solution, based on what I read in Peter Wemm’s blog post about Let’s Encrypt in the FreeBSD cluster.

In this post, I will outline how I altered my DNS servers to take orders from a hidden DNS master via VPN.

The master server options

My hidden DNS master sits on a VPN and is not accessible via any publicly-routable IP address. It is only reachable over RFC 1918 addresses.

I log. I log a lot. Some call it overkill. I call it being prepared. Details of what I log are in this gist and will not be discussed here.

My hidden DNS master contacts the primary DNS server over a VPN. When named detects a zone update, the standard procedure is to notify all the other name servers listed in that zone (i.e. the servers with NS records for that zone). I don’t want to do that. I don’t want the updates going out over the internet. I want them going over my VPN. The NS records are, in this case, publicly-routeable IP addresses.

To stop the notifications, I add this entry to the options clause in my /usr/local/etc/named.conf file (your file location may vary):

notify explicit;
allow-transfer { "none"; };
listen-on      {;; };

Line 1 says only notify those servers indicated in a notify statement (we will see such statements later in this blog post).

Line 2 says do not allow any zone transfers. Later, we will explicitly allow zone transfers on a zone-by-zone basis.

Line 3 says listen only on localhost and on the indicated IP address.

The nsupdate key

In my previous blog post, I talked about creating a key to allow only TXT records via nsupdate. Based on that work, here is the entry I added to my hidden master’s named.conf file:

key {
    algorithm HMAC-SHA512;
    secret "TgDiZn2IpmHjlF2B4qaHWHuBH3G4G76weISdPbt9iSNn8o9H5/yTDBNpJvw4y6wNz8+R5BpZ9r/wqnzeMphW8Q==";

The slaves

This clause lists the VPN IP addresses of the slaves which will be notified when a zone update occurs on the hidden master.

// this is usually kept in sync with acl SlaveServersVPN
// these IP addresses are those upon which named listens
masters SlaveServersToNotify {;;;

Where do zone transfers originate from?

In my case, zone transfers do not always originate from the same IP addresses as the ons upon which the slaves listen. In fact, the zone transfers originate from the VPN endpoints in some cases. That is why I need a separate clause for allowing zone transfers.

Watch your logs and they will let you know what you need to do.

// this is usually kept in sync with masters SlaveServersToNotify
// these IP address are often the VPN end-points.
// These are the IPs from which zone transfers will originate.
acl SlaveServersVPN {;;;

Who can initiate a transfer?

Slave DNS servers need to initiate a transfer. So do some of my other hosts. These are monitoring hosts or perhaps laptops/workstations from which you might want to do a zone transfer just to test or watch what’s going on.

acl AllowZoneTransfer {

I have not supplied the LocalTrustedBoxes definition but you can create one if required.

The zone declaration on the master

This is my zone declaration on the hidden master. Below it are some notes which may help.

zone "" {
        type master;
        file "zones/";
        allow-transfer { AllowZoneTransfer; };
        update-policy  { grant zonesub TXT; };
        notify yes;
        also-notify    { SlaveServersToNotify; };

Line 3 tells us where to find the zone file

Line 4 indicates who is allowed to do a zone transfer from this hidden master.

Line 5 says what key can be used to update this zone. Additionally, it restricts that key to TXT records only.

Line 6 says changes to this zone file should result in notifications.

Line 7 says who you should notify.

The slave server configuration

In my slave servers, I do not want them sending out notifications unless specified, so I added this to the options clause in named.conf:

notify explicit;

I think you might be able to get away without that declaration. Some of my domains have secondary DNS servers hosted by others. I needed that notify declaration for that situation.

I also want this slave accessible via the VPN, so I added this to the same options clause:

listen-on	{;; [REDACTED PUBLIC IP ADDRESS]; };

In this case, we listen on the specified IP addresses.

The zone and details associated with it are specified like this in the slave:

masters HiddenMaster {; };

acl AllowZoneTransfer {

zone "" {
        type slave;
        file "secondary/";
        masters { HiddenMaster; };
        allow-transfer { AllowZoneTransfer; };
        notify no;

Line 1 identifies the hidden master described previously in this article.

Line 3 indicates who can do a zone transfer from this slave. This is so I can test from selected hosts to verify what is on this particular slave.

Line 7 defines the zone and line 8 indicates it is a slave zone.

Line 10 lists the masters.

Line 11 says who can do a zone transfer from us.

Line 12 says not to notify the NS servers listed for this zone when a zone update occurs

What’s that you say?

The above took a few hours of trial and error, watching logs, and reading docs to figure out how to accomplish this over a VPN. So far, I’m happy with the results.

Website Pin Facebook Twitter Myspace Friendfeed Technorati Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top