Hello,
This is a combination of posts I have used in the past and have adapted to provide an excellent DNS solutions.
The prerequisites for this are just Two Servers and in this implementation 4 IP's(2 per server) as it makes it more understandable. Also you will require a web accessible domain on each server.
Basically it will allow you to use a combination of two servers to do your DNS for you one being the primary and one the secondary. You could use this for every two sets of servers you own OR possibly adapt it so that all your servers use just the two sets.
It is my intention to eventually use this solution so that DJBDns is used instead of Bind because it is so flakey and buggy in my opinion.
DJB has a $500 reward for any exploits discovered thats how good it is!
Anyway enough chat lets get down to business....................
What we are aiming for is the following set up
NS1.JOELMOSS.COM PRIMARY NS FOR SERVER 1 ON SERVER 1
NS2.JOELMOSS.COM SECONDARY NS FOR SERVER 1 ON SERVER 2
NS3.JOELMOSS.COM PRIMARY NS FOR SERVER 2 ON SERVER 2
NS4.JOELMOSS.COM SECONDARY NS FOR SERVER 2 ON SERVER 1
ÂÂ
It might be an idea to plan out your IP addresses and write them down for each name server otherwise this is going to get confusing!! :)
STEP 1 Setting up the first server
===================================================================
step 1.1 creating the nameserver DNS records
If you don't have your 4 IP's go to the good old members section and request them. Remember 2 per server you need overall.
Once You have gained some additional IPs you will need to add these to the server. This is done by going to the server control panel in Plesk. Once the server option is loaded click IP Aliasing. Then add the IPs you have been given, making sure to use the correct submask.
Next you will need to be able to add a domain. I made myself a client so i could do the following
-Create the domain you want to use for DNS (i.e., if you want your customers to use ns1.joelmoss.com and ns2.joelmoss.com, then create an account for joelmoss.com). This domain doesnt have to be hosted on the box don't worry its for internal use
- Go the the DNS of joelmoss.com and add the following records:
(You select the DNS record, A and then click Add, then you enter ns1 in the first box and the IP you want as first nameserver in the second box, press update)
*NOTE Use an IP on the box your configuring for this one
ns1.joelmoss.com A <IP> //Primary NS for Server 1
(You select the DNS record, A and then click Add, then you enter ns2 in the first box and the IP you want as second nameserver in the second box, press update. Please note that the IP for ns1 and ns2 must be different. You cannot have two nameservers with the same IP, but you can have an IP ised for both a site and a nameserver).
*NOTE Use an IP on the box your configuring for this one.
ns4.joelmoss.com A <IP> //Secondary NS for Server 2
(Select NS as record type and leave the first box empty, enter the full name server in the second box, do the same for the second nameserver).
joelmoss.com NS ns1.joelmoss.com
joelmoss.com NS ns4.joelmoss.com
(Now you also need PTR records for the name servers. Someone may correct me but i believe you need PTRs for all 4 NS.)
Select PTR record and ADD
Fill in ns1 in the lower box and in the IP field the same IP you used for the A record for NS1
Fill in ns4 in the lower box and in the IP field the same IP you used for the A record for NS4 (This ip should be located on your second server remember!)
Repeat the PTR's for NS2 and NS3 also using the IPs you plan to use for them
=================================================================================================================
Step 1.2 Creating DNS template for domains hosted on server 1
- Go to Server --> DNS and add the following records:
(Select NS as record type and leave the first box empty, enter the full nameserver as in ns1.joelmoss.com in the second box and press update. Do the same for the second nameserver).
<domain> NS ns1.joelmoss.com
<domain> NS ns2.joelmoss.com
While your in there remove the PTR Record
Okay thats the easy bit :)just take a minute to double check your IP's with what where aiming to achieve at top of post.
We have just created a template so that every domain is created with ns1.joelmoss.com and ns2.joelmoss.com as their name servers
Remember ns1 is primary on first server and ns2 is secondary on the second server. So you can see we are taking advantage of both boxes here and also load balancing ;)
The hard bit is keeping track of what ns is on what box while your reading through this! :)
==================================================================================================================
Step 1.3 creating the special script
This script takes your primary name server records and creates the following for each domain
zone "domain.com" {
type slave;
masters {;xx.xxx.xx.xx;};
file "sec.domain.com";
};
The reason why we dont just type these into the secondarys named.conf is that we would simply have to do every time we created a domain. Every time a reseller created a domain and if anybody deleted a domain we would have to remove it. This script will keep all that in check for us by converting psa's dns database for us and downloading it.
Open an SSH session to the same server we have been working on.
We now need to change directory to our web accessible domain we have on this server
cd /usr/local/psa/home/vhosts/yourdomain.com/httpdocs
We also need to create a folder to make this more secure(you will see why in a minute)
mkdir backup
cd backup
Now we will create the clever script that will create our secondary DNS records needed to go in named.conf.........
pico dns.php
Make sure you have your SSH session in full screen then copy and paste the following into it(select->copy then right click on your ssh window to paste)
<?
header("Content-Type: text/plain");
// serverpath can be the path to the mysql.sock or "localhost:xxxx"
$serverpath = "localhost";
$dbusername = "admin";
$dbpassword = "Your PSA Password";
$psadb = "psa";
$psaip = "xx.xxx.xx.xx"; //ip of THIS server (name-based ip)
$debug = 1; //set to 1 to print debug info
if (!($dblink = mysql_pconnect($serverpath, $dbusername, $dbpassword))) {
if ($debug) print "Unable to connect to $serverpath as $dbusername";
exit();
}
if (!(mysql_select_db($psadb, $dblink))) {
if ($debug) print "Unable to select $psadb database <BR>";
if ($debug) sprintf("%d:%s", mysql_errno($dblink), mysql_error($dblink));
exit();
}
$query = "Select name from domains where status=\"true\" and dns_zone=\"true\"";
$domainresult = mysql_query($query, $dblink);
while($row = mysql_fetch_object($domainresult)){
$name = $row->name;
if($name<>'joelmoss.com')
{
echo "zone \"$name\" {\n".
"\ttype slave;\n".
"\tmasters { $psaip;};\n".
"\tfile \"sec.$name\";\n".
"};\n\n";
}
}
mysql_free_result($domainresult);
?>
You will need to change the following in that file:
$dbpassword = "Your PSA Password";
$psaip = "xx.xxx.xx.xx";
if($name<>'joelmoss.com')
The last one "joelmoss.com" is important because if your are using the same domain.com for the name servers, on both servers, you will end up with duplicate zones! So obviously replace joelmoss.com with the domain your using for your name servers and it will exclude it on the import
Okay now press
ctrl o to write the file
ctrl x to quit
==================================================================================================
Step 1.4 making that file secure
.htaccess files allow us to protect folders on the web server and we dont want anyone browsing to this folder other than our 2nd server
pico .htaccess (you should still be in the backup folder)
<Limit GET>
order allow,deny
allow from xx.xxx.xx.xx
deny from *
</Limit>
copy the above into the .htaccess file replacing xx.xxx.xx.xx with the 2nd servers IP address
ctrl o
ctrl x
Now only the 2nd server can access that folder so no one can go stealing your name server info ;)
==================================================================================================
Step 1.5 permissions and ownerships
Just to keep things nice and tidy and to allow the PHP script to execute we need to sort out the permissions of files we've created at the minute they will be owned by root which is never good :)
Okay now we just need to set permissions on these
chmod 755 dns.php (needs to run PHP can we go lower?)
cd ..
chmod 755 backup (needs to run PHP can we go lower?)
We also need to set an owner for those files so Find the current owner of files in that area if you dont know it
ls -l (you will see something like "user psacln"
chown -R user:psacln backup //replacing user with the name you see
====================================================================================================
step 1.6 setting the server to allow zone transfers from recognised sources only
This will stop someone downloading on DNS records directly from bind and only allow on 2nd server too
pico /etc/named.conf
Look for where it says "options" just a few lines down
Type in the following above it replacing xx.xxx.xx.xx with the 2nd servers main IP
acl trusted { xx.xxx.xx.xx/24;};
Directly below auth-nxdomain type in:
allow-transfer {trusted;};
At the bottom of the file just above the in-addr arpa blocks find some clear space and type the following replacing the xxxxxxxx with the primary NS IP of server 2 i.e. NS3. I didn't use any full stops between the xx as i didnt know if that is allowed. Im using the IP as the file name so we know what it is and where it came from
include "xxxxxxxxx.include";
Ok now
ctrl->o
ctrl->x
=======================================================================================================
Step 1.7 creating a cron to fetch the dns records by executing the script on server 2 and dumping the page it produces to a file
ok as we are still on server 1 you have to appreciate some of what we are doing is setting things up for server 2. This is going to fetch the records from server 2's script which we havent created there yet(remember we've done server 1's script). It just saves switching between machines! Might as well do one in its entirety then move over to 2nd.
ok
xxxxxxxx in the following is again the IP of NS3 primary of 2nd server
pico /etc/cron.hourly/updateDNS.sh
Type in the following:
#!/bin/bash
# pull domains.include from plesk
lynx -dump http://domain-on-server-2.com/backup/dns.php > /usr/local/psa/named/run-root/var/xxxxxxxxx.include
#reload the name server
/usr/local/psa/named/sbin/rndc reload
ctrl o
ctrl x
chmod 755 /etc/cron.hourly/updateDNS.sh
=======================================================================================================================
step 1.7 a few odd permissions to sort out
Also we are going to run in a few permission problems here so we need to do the following
chmod 666 /usr/local/psa/named/run-root/var/ (i believe i used 666)
chown bind:bind /usr/local/psa/named/run-root/var/
Don't worry about restarting any services yet it'll probably just cause problems until we do server 2
Okay lets recap what we have done
=======================================================================================================================
* We have created DNS entries for our primary name server and our secondary name server
* We have created a script to create secondary records from the PSA database to be used by the 2nd server and secured it. We need to repeat these steps to create one on the 2nd server so this server can use it but thats coming
* We have edited the name server config to allow the 2nd server only to update NS4's secondary zones from ns1 on this server
* We have created a cron to execute dns.php on the 2nd server so that it converts NS2's(2nd servers primary dns) records to secondary zones and writes them into an include file.
* We have edited the name server config so that we can include that include file into it so in there will be primary zones of NS1 and secondary zones for NS3(secondary NS of server2 located on server1)
* We have also just altered some permissions so that the secondary zones can be transferred into run-root/var otherwise bind wouldnt have had permission to write in there!
This is complicated :)!
Believe it or not that is one server set up but it wont work fully until we do the 2nd! Basically what we have to do now is all that again but replacing NS1 with NS2 and NS4 with NS3 and vise versa.
I will write it out again for those who are lost because it is complicated :)
ÂÂ
STEP 2 Setting up the second server
===================================================================
step 2.1 creating the nameserver DNS records
If you don't have your 4 IP's go to the good old members section and request them. Remember 2 per server you need overall.
Once You have gained some additional IPs you will need to add these to the server. This is done by going to the server control panel in Plesk. Once the server option is loaded click IP Aliasing. Then add the IPs you have been given, making sure to use the correct submask.
Next you will need to be able to add a domain. I made myself a client so i could do the following
-Create the domain you want to use for DNS (i.e., if you want your customers to use ns1.joelmoss.com and ns2.joelmoss.com, then create an account for joelmoss.com). This domain doesnt have to be hosted on the box don't worry its for internal use
- Go the the DNS of joelmoss.com and add the following records:
(You select the DNS record, A and then click Add, then you enter ns1 in the first box and the IP you want as first nameserver in the second box, press update)
*NOTE Use an IP on the box your configuring for this one
ns3.joelmoss.com A <IP> //Primary NS for Server 2
(You select the DNS record, A and then click Add, then you enter ns2 in the first box and the IP you want as second nameserver in the second box, press update. Please note that the IP for ns1 and ns2 must be different. You cannot have two nameservers with the same IP, but you can have an IP ised for both a site and a nameserver).
*NOTE Use an IP on the box your configuring for this one.
ns2.joelmoss.com A <IP> //Secondary NS for Server 1
(Select NS as record type and leave the first box empty, enter the full name server in the second box, do the same for the second nameserver).
joelmoss.com NS ns3.joelmoss.com
joelmoss.com NS ns2.joelmoss.com
(Now you also need PTR records for the name servers. Someone may correct me but i believe you need PTRs for all 4 NS.) These pointer records just turn an IP address into a name when the IP address is queried
Select PTR record and ADD
Fill in ns3 in the lower box and in the IP field the same IP you used for the A record for NS3
Fill in ns2 in the lower box and in the IP field the same IP you used for the A record for NS2 (This ip should be located on your second server remember!)
Repeat the PTR's for NS2 and NS3 also using the IPs you plan to use for them
=================================================================================================================
Step 2.2 Creating DNS template for domains hosted on server 2
- Go to Server --> DNS and add the following records:
(Select NS as record type and leave the first box empty, enter the full nameserver as in ns3.joelmoss.com in the second box and press update. Do the same for the second nameserver).
<domain> NS ns3.joelmoss.com
<domain> NS ns4.joelmoss.com
While your in there remove the PTR Record
Okay thats the easy bit :)just take a minute to double check your IP's with what where aiming to achieve at top of post.
We have just created a template so that every domain is created with ns3.joelmoss.com and ns4.joelmoss.com as their name servers
Remember ns3 is primary on 2nd server and ns4 is secondary on the first server. So you can see we are taking advantage of both boxes here and also load balancing ;)
The hard bit is keeping track of what ns is on what box while your reading through this! :)
==================================================================================================================
Step 2.3 creating the special script
This script takes your primary name server records and creates the following for each domain
zone "domain.com" {
type slave;
masters {;xx.xxx.xx.xx;};
file "sec.domain.com";
};
The reason why we dont just type these into the secondarys named.conf is that we would simply have to do every time we created a domain. Every time a reseller created a domain and if anybody deleted a domain we would have to remove it. This script will keep all that in check for us by converting psa's dns database for us and downloading it.
Open an SSH session to the same server we have been working on(the 2nd server remember we've done with the first)
We now need to change directory to our web accessible domain we have on this server
cd /usr/local/psa/home/vhosts/yourdomain.com/httpdocs
We also need to create a folder to make this more secure(you will see why in a minute)
mkdir backup
cd backup
Now we will create the clever script that will create our secondary DNS records needed to go in named.conf.........
pico dns.php
Make sure you have your SSH session in full screen then copy and paste the following into it(select->copy then right click on your ssh window to paste)
<?
header("Content-Type: text/plain");
// serverpath can be the path to the mysql.sock or "localhost:xxxx"
$serverpath = "localhost";
$dbusername = "admin";
$dbpassword = "Your PSA Password";
$psadb = "psa";
$psaip = "xx.xxx.xx.xx"; //ip of THIS server (name-based ip)
$debug = 1; //set to 1 to print debug info
if (!($dblink = mysql_pconnect($serverpath, $dbusername, $dbpassword))) {
if ($debug) print "Unable to connect to $serverpath as $dbusername";
exit();
}
if (!(mysql_select_db($psadb, $dblink))) {
if ($debug) print "Unable to select $psadb database <BR>";
if ($debug) sprintf("%d:%s", mysql_errno($dblink), mysql_error($dblink));
exit();
}
$query = "Select name from domains where status=\"true\" and dns_zone=\"true\"";
$domainresult = mysql_query($query, $dblink);
while($row = mysql_fetch_object($domainresult)){
$name = $row->name;
if($name<>'joelmoss.com')
{
echo "zone \"$name\" {\n".
"\ttype slave;\n".
"\tmasters { $psaip;};\n".
"\tfile \"sec.$name\";\n".
"};\n\n";
}
}
mysql_free_result($domainresult);
?>
You will need to change the following in that file:
$dbpassword = "Your PSA Password";
$psaip = "xx.xxx.xx.xx";
if($name<>'joelmoss.com')
The last one "joelmoss.com" is important because if your are using the same domain.com for the name servers, on both servers, you will end up with duplicate zones! So obviously replace joelmoss.com with the domain your using for your name servers and it will exclude it on the import
Okay now press
ctrl o to write the file
ctrl x to quit
==================================================================================================
Step 2.4 making that file secure
.htaccess files allow us to protect folders on the web server and we dont want anyone browsing to this folder other than our 1st server
pico .htaccess (you should still be in the backup folder)
<Limit GET>
order allow,deny
allow from xx.xxx.xx.xx
deny from *
</Limit>
copy the above into the .htaccess file replacing xx.xxx.xx.xx with the 1st servers IP address
ctrl o
ctrl x
Now only the 1st server can access that folder so no one can go stealing your name server info ;)
==================================================================================================
Step 2.5 permissions and ownerships
Just to keep things nice and tidy and to allow the PHP script to execute we need to sort out the permissions of files we've created at the minute they will be owned by root which is never good :)
Okay now we just need to set permissions on these
chmod 755 dns.php (needs to run PHP can we go lower?)
cd ..
chmod 755 backup (needs to run PHP can we go lower?)
We also need to set an owner for those files so Find the current owner of files in that area if you dont know it
ls -l (you will see something like "user psacln"
chown -R user:psacln backup //replacing user with the name you see
====================================================================================================
step 2.6 setting the server to allow zone transfers from recognised sources only
This will stop someone downloading on DNS records directly from bind and only allow on 1st server to
pico /etc/named.conf
Look for where it says "options" just a few lines down
Type in the following above it replacing xx.xxx.xx.xx with the 1st servers IP
acl trusted { xx.xxx.xx.xx/24;};
Directly below auth-nxdomain type in:
allow-transfer {trusted;};
At the bottom of the file just above the in-addr arpa blocks find some clear space and type the following replacing the xxxxxxxx with the primary NS IP of server 2 i.e. NS3. I didn't use any full stops between the xx as i didnt know if that is allowed. Im using the IP as the file name so we know what it is and where it came from
include "xxxxxxxxx.include";
Ok now
ctrl->o
ctrl->x
=======================================================================================================
Step 2.7 creating a cron to fetch the dns records by executing the script on server 1 and dumping the page it produces to a file
ok we are now going to be able to execute the script from server 1 we created much earlier we are getting there ;)
ÂÂ
xxxxxxxx in the following is again the IP of NS1 primary of 1st server
pico /etc/cron.hourly/updateDNS.sh
Type in the following:
#!/bin/bash
# pull domains.include from plesk
lynx -dump http://domain-on-server-1.com/backup/dns.php > /usr/local/psa/named/run-root/var/xxxxxxxxx.include
#reload the name server
/usr/local/psa/named/sbin/rndc reload
ctrl o
ctrl x
chmod 755 /etc/cron.hourly/updateDNS.sh
Okay we can test this bit now you can also cross check it from server one
type
sh /etc/cron.hourly/updateDNS.sh // this executes the script above and creates the file in /run-root/var
type the following replacing the xxxxxxxxx with the IP of NS1 no periods(full stops) remember! :)
pico /usr/local/psa/named/run-root/var/xxxxxxxxx.include
just check theres no errors in there! You probably wont have any zones in there but thats ok :) so long as the file existed and no errors your ok
If there were errors revisit 1.3 working on the first server. The errors should help u identify the problem
=======================================================================================================================
Step 2.7 a few odd permissions to sort out
Also we are going to run in a few permission problems here so we need to do the following
chmod 666 /usr/local/psa/named/run-root/var/ (i believe i used 666)
chown bind:bind /usr/local/psa/named/run-root/var/
Don't worry about restarting any services yet it'll probably just cause problems until we do server 2
Okay lets recap what we have done
Now later on when it comes to running this thing with domains on the servers(place some test ones on later) if you get errors at the end of /var/log/messages saying
(tail /var/log/messages --lines=50)
error cannot dump file permission denied or something it will be caused by 2.7 if the log is on 2nd server or 1.7 if log on first
=======================================================================================================================
ÂÂ
Ok - Restart PSA ( /usr/local/psa/rc.d/psa restart ) on both machines NOT simultaneously. Wait for one to restart before the other ;)
- Register the four NS at your domain registrar.
People hosting on the first server should be given
ns1.joelmoss.com
ns2.joelmoss.com
People hosting on the 2nd
ns3.joelmoss.com
ns4.joelmoss.com
Add some domains to both servers
Go to SSH on a server
type sh /etc/cron.hourly/updateDNS.sh
pico /usr/local/psa/named/run-root/var/xxxxxxxxx.include //xxxxxxx replaced by the other servers primary IP without periods (except .include) ;)
just check theres no errors in there!
You should also see some of these
zone "domain.com" {
type slave;
masters {;xx.xxx.xx.xx;};
file "sec.domain.com";
};
They will relate to the test domains you just created on the other server
Check your log
tail /var/log/messages --lines=50
Aug 20 19:46:04 servdns named[3718]: zone domain.net/IN: sending notifies (serial 1023065848)
Aug 20 19:46:04 servdns named[3718]: zone domain.net/IN: transfered serial 1026437961
Aug 20 19:46:04 servdns named[3718]: transfer of 'domain.net/IN' from 64.246.15.49#53: end of transfer
ÂÂ
Those means brilliant youve done it! Now check the other server
If you get these you have messed up at either 1.7 or 2.7 depending on what server u r on :)
And these are normal
Aug 20 14:44:35 servdns named[3718]: loading configuration from '/etc/named.conf'
Aug 20 14:44:35 servdns named[3718]: no IPv6 interfaces found
Some parts of this taken from the following posts and adapted by myself. The rest is wholly my work :)
Thanks to the authors involved as it couldn't have been done without them!
http://forum.plesk.com/showthread.php?s=25cec8961a98550a46a1e73808fd4377&threadid=1384&perpage=15&highlight=dumping%20master%20file&pagenumber=4s
http://forum.rackshack.net/showthread.php?s=&threadid=4549&highlight=plesk+dns
Please do NOT reproduce this and pass it off as your own.
You may only post links to this document as it took a long time to produce and we will consider this to be offensive.
Finally any changes or errors please email [email protected] stating clearly where the errors are and why