Mysql based dns for the ability for web based control


First I would like to explain what I was trying to do before I continue on my walkthrough. I wanted two master dns servers that had mySQL backend. They software was required to run zone transfers to the front end ISC Bind 9.x servers. The image below shows a basic overview of how I wanted to setup my servers. I used Ubuntu server for the host operating system. These instructions should work for linux also.

Secure mysql master servers feed the public facing/insecure DNS servers via zone transfers.

I have 4 public dns servers. They are what the world queries to lookup the dns records I host. They have Bind 9.x installed on them and they are all slaves to both masters. I could have setup a master to slave relationship to one of the public servers, and had the other 3 public servers use that public server as a master. I wanted to make it simple to have a slave master was not a good idea.

The master servers run MyDNS, and mySQL 5.x. I have replication setup between the two master DNS servers. Master 1 is the mySQL master, and master 2 is the mySQL slave. If I want to change a dns record I change it on the server Master 1.

I have a website built that I cannot give to you in this guide. I have found a front end for managing the DNS server on Google Code. MyDNS-pfe Looks like it is pretty good, but if you are even remotely good at php, and html this will be easy to make.

My personal preference to Linux

Install the latest version of Ubuntu server with no packages but ssh. I prefer to have separate / and /var hard drives preferable a raid 1 drive for /var or at least /var/mysql.

After you have your server setup to your companies security standards, or your personal touch you want to upgrade the server with $> apt-get update and $> apt-get dist-upgrade.

Configuring the master DNS servers
$> apt-get install mysql-server-5.0 mydns-mysql

After it is install you need to configure mySQL first
Set the root password.
$> mysql
mysql> SET PASSWORD FOR ‘root’@'localhost’ = PASSWORD(‘changepassword’);
mysql> quit

I change the /etc/mysql/my.cnf file to listen on all ip addresses so I change the following line in the file.
bind-address = 127.0.0.1
to
bind-address = 0.0.0.0
This allows everyone to connect to the server, so I lock it down with iptables(firewall), and a hardware firewall. You may also want to setup the mysql config to allow for it to be the master replication server. Add the following lines to your /etc/mysql/my.cnf.
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
# WARNING: Using expire_logs_days without bin_log crashes the server! See README.Debian!
expire_logs_days = 10
max_binlog_size = 100M
You will also need to follow the instructions HERE

You will want to restart mysql before setting up the mydns server with the following command.
$> /etc/init.d/mysql restart

MyDNS Setup
You can look up the references to this software from their site.
$>mysql -uroot -pchangepassword
mysql>CREATE mydns;
mysql> GRANT SELECT ON mydns.* TO mysql@localhost IDENTIFIED BY ‘changepassword’;
mysql>FLUSH PRIVILEGES;
mysql>quit
$>mydns –create-tables | mysql -h host -u mydns -p mydns

Creating the MyDNS config
$>mydns –dump-config > /etc/mydns.conf
The defaults should be sufficient. Here is an example of my configuration.

db-host = localhost # SQL server hostname
db-user = mydns # SQL server username
db-password = changepassword # SQL server password
database = mydns # MyDNS database name
user = nobody # Run with the permissions of this user
group = nogroup # Run with the permissions of this group
listen = * # Listen on these addresses (‘*’ for all)
no-listen = # Do not listen on these addresses
zone-cache-size = 4192 # Maximum number of elements stored in the zone cache
zone-cache-expire = 60 # Number of seconds after which cached zones expires
reply-cache-size = 4192 # Maximum number of elements stored in the reply cache
reply-cache-expire = 30 # Number of seconds after which cached replies expire
log = LOG_DAEMON # Facility to use for program output (LOG_*/stdout/stderr)
pidfile = /var/run/mydns.pid # Path to PID file
timeout = 120 # Number of seconds after which queries time out
multicpu = 2 # Number of CPUs installed on your system
recursive = # Location of recursive resolver
allow-axfr = yes # Should AXFR be enabled?
allow-tcp = yes # Should TCP be enabled?
allow-update = yes # Should DNS UPDATE be enabled?
ignore-minimum = yes # Ignore minimum TTL for zone?
soa-table = soa # Name of table containing SOA records
rr-table = rr # Name of table containing RR data
soa-where = # Extra WHERE clause for SOA queries
rr-where = # Extra WHERE clause for RR queries

This is just a basic configuration, but you can change it however your setup requires.

Allowing for zone transfers is pretty simple.

$>mysql -umydns -pchangepassword
mysql> ALTER TABLE mydns.soa ADD COLUMN xfer CHAR(255) NOT NULL;
mysql> quit
When you add your zones all you have to do is just add the data to the xfer column like the following.
192.168.10.50/32,172.31.31.50/32,192.168.0.50/32,10.0.0.50/32
Commas separate the different servers. You could also add them for entire CIDR blocks, but I choose not to.

If you want to set active, and inactive zones you will need to do the following. I like this cause it allows me to turn off a client for not paying, or when I remove a client I can keep the data for a while.
$>mysql -umydns -pchangepassword
mysql> ALTER TABLE mydns.soa ADD COLUMN active ENUM(‘Y’,'N’) NOT NULL;
mysql> ALTER TABLE mydns.soa ADD INDEX (active);
mysql> quit

You should be all setup and ready to go. If you have an existing bind dns server you can import your data with the mydns import utility.
All utilities support the `–host’, `–database’, `–user’, and `–password’ options.
mydnsimport -hlocalhost -Dmydns -umydns -pchangepassword wantlinux.net

I wrote a script to easily import multiple zones from a bind 9.x named.conf file with axfr turned on. Here is a link to the perl script. To download the script click HERE or to view the script click HERE.

If you want to setup any more configuration examples please refer the MyDNS website.

Configuring the slave DNS servers
Configuring the slave DNS servers is an easy process with bind. Bind is my favorite DNS server. I can give you many reasons why I like it, but everyone should find what they like. Bind accepts AXFR zone transfers which is a good thing when you setup a master MyDNS server that does zone transfers with AXFR.

Install, and configure Bind

Install bind with the following command on Ubuntu.
$> apt-get install bind

After I install the server I set it up to not allow recursion for the ip addresses that are not allowed for it. Here is my basic config in /etc/bind/named.conf

include “/etc/bind/named.conf.options”;
zone “.” {
type hint;
file “/etc/bind/db.root”;
};
zone “localhost” {
type master;
file “/etc/bind/db.local”;
};
zone “127.in-addr.arpa” {
type master;
file “/etc/bind/db.127″;
};
zone “0.in-addr.arpa” {
type master;
file “/etc/bind/db.0″;
};
zone “255.in-addr.arpa” {
type master;
file “/etc/bind/db.255″;
};
include “/etc/bind/named.conf.local”;

Here is my example named.conf.options file also.
options {
directory “/var/cache/bind”;
// Your IP address here
listen-on port 53 { 192.168.1.50; 127.0.01; };
auth-nxdomain no; # conform to RFC1035
allow-recursion {192.168.1.0/24; 127.0.0.1; 192.168.2.0/24; };
allow-transfer {66.37.134.155;};
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { “rndc-key”; };
};
key “rndc-key” {
algorithm hmac-md5;
secret “YOURKEY”;
};

I have made a script that converts the mydns database to a named.conf.local file for use as a slave server. Make sure you change the ip addresses of the master servers in the script, and you have the perl modules for mysql(apt-get install libdbd-mysql-perl). It writes a file /etc/bind/named.conf.local that you can scp to your slave servers when you add a new domain, or delete a new one. If you want to download the script click HERE or if you wish to look at the script click HERE You will not have to move the file when you change records to a zone. Just when you add or delete zones. I use ssh keys, and scp the file over to the server, and run rndc reload and reconfig commands. I hope this article was helpful, and I look forward to your comments.

zimdar

  1. #1 by Shamsul Arefin at July 17th, 2009

    Hi,

    I have been trying to setup this environment. It works fine for the first time. But when I change the Master in the Master MyDNS server it does not propagate to the Slave Bind DNS server. It shows something like.
    “failed while receiving responses: end of file”

    Do you have any idea about this?
    Thanks in advance.

    • #2 by Milosz at October 28th, 2009

      I am experiencing same problem ;/

(will not be published)

  1. No trackbacks yet.