For a long time, I served secondary DNS for Plesk domains using a non-Plesk server, but I was manually creating the zones on the secondary DNS machine. Too much “hands-on,” and too many places for human error. I took a closer look at automating the solution, using a Plesk server as primary DNS, and a non-Plesk server as secondary DNS. This article describes my solution.

To keep things simple, I’m describing the solution for a two server, master-to-slave setup. However, this can be easily adapted to a many-to-one or one-to-many solution.

Needed for this implementation:

1) A recent (v.10 or later) Plesk server, acting as a web host and primary DNS. My example is based on Plesk for Linux. I believe it will also work for a Plesk server running on a Windows server, but the firewall issues are probably more challenging, since the Plesk/Windows firewall implementation isn’t as granular as Plesk with iptables firewall rules on Linux.

2) A Linux server running BIND, acting as a secondary DNS. My own solution uses a dedicated CentOS 6.3 server, but this can be adapted to other Linux flavors running BIND, including virtual and cloud solutions.

3) Preferably, root access to the secondary DNS machine, since this automation requires creating a shell script, a PHP script that will run from the shell, firewall exceptions, and remote access the Plesk’s MySQL psa database on the Plesk Server from the secondary server.

Setting up appropriate firewall rules and a limited access MySQL user account is strongly recommended. If you don’t know how to safely open up the Plesk firewall to allow only the secondary DNS server to access the psa database, via a MySQL account with very limited permissions, do some additional study or hire an expert to do it for you. Taking security shortcuts here invites trouble.

Other than a Plesk firewall change to allows MySQL access from the secondary DNS machine, and the MySQL user setup, nothing needs to happen on the Plesk server where the hosting and primary DNS is taking place. You run it like any Plesk server, adding and deleting subscriptions/domains in the normal course of business. The secondary DNS machine will run scripts that will keep secondary DNS in synch with the Plesk server.

In the example I’ll show, 192.168.10.12 is our Plesk web server and a primary DNS. 10.10.1.2 is our CentOS server acting as the secondary DNS in a different data center.

We need to add one critical line to BIND’s named.conf file on the secondary server:

The added line to named.conf is line 17. That include statement tells BIND to include a file specified by the path/filename, as if it were part of named.conf.

With the include file, we have an easy way to manage a list of valid zones for the secondary DNS, without editing the secondary’s named.conf. We just need a process to build the include file with the domains we want to serve secondary DNS for.

How do we generate the list of domains into that include file? From the Plesk primary server’s MySQL database, which holds a list of domains on the Plesk server. We can query that database from the secondary server, build the include file, save it, and reload the secondary DNS zone file as often as needed, including on a scheduled basis.

Let’s examine the simple script that manages this process, called “check-dns-master.sh”:

The shell script calls a PHP script that does the database query and all of the include file building. It compares the Plesk domain list from the primary server’s MySQL psa database with the zones currently in the include file. If needed, it rebuilds the include file to account for any new or deleted domains. Here’s the build-dns-zones.php script:

Don’t let the length of the PHP script put you off. Much of the code is for comparing the Plesk psa database list of domains with the domains contained in the existing include, in order to determine if a change happened since the previous include file creations, indicating a new include file is needed.

In my own implementation, the shell script runs every five minutes on the secondary DNS. If a difference between the Plesk server’s domain list is found when compared to the zone include file, a new zone include file is built. When that happens, the shell script receives a return value of “1” from the PHP script, letting the shell script know to reload BIND’s zones. The new domain’s individual zone file, on the Plesk server, will be transferred to the secondary DNS during the BIND reload. You can examine the “messages” log file on the Plesk server (/var/log/messages on CentOS) to verify the zones are transferring to the secondary DNS.

Two-server Plesk implementations keep DNS synchronized without this type of automation, with both servers acting as masters their own zones, and slaves for the other server’s zones. However, one of the advantages of the solution described here is not needing a Plesk license for a secondary DNS server. It also allows use of a very low powered (and low cost) secondary server, since this process requires very little processing power, RAM or drive space. In fact, this could be an ideal setup for running a secondary DNS in a minimal cloud or virtual server, running Linux, PHP and BIND. You could easily use this to set up additional DNS slaves on inexpensive resources across a large geographic area, for operational resiliency.

There is also no reason why this setup couldn’t be used to completely offload DNS from Plesk. In my own operation, I find it convenient to use Plesk’s DNS management tools and template capabilities as a primary DNS, to manage zones. It’s ideal for reseller setups. But if your operation requires completely separating DNS from Plesk servers, these scripts can be adopted for that purpose.