DNS Sanity with Hawk
If you are a DNS administrator for anything more than a few dozen
hosts, its easy for your database to get out of sync with
whats really on your network. The GPL software tool, Hawk,
is designed to help administrators track which hosts in DNS are
really on your network and, just as importantly, which hosts are
on your network but not in DNS. Hawk can help take the mystery out
of DNS maintenance, resulting in a much cleaner, up-to-date database.
Hawk consists of three components: a monitor written in Perl,
a MySQL database backend, and a PHP Web interface. The monitor periodically
checks whether hosts on your network appear in DNS and are answering
on your network. It checks for existence on the network by way of
an ICMP ping. I mention ICMP because by default, the Perl Net::Ping
module pings by attempting a UDP connection to a hosts
echo port. With the various types of hosts possible on a typical
network, this is probably not desirable. As each IP address on your
network is polled, the monitor records or updates in the database
the current IP address and the hostname, if one exists. If the ping
is successful, this timestamp is also recorded in the database.
The Hawk interface consists of a Web page that allows you to choose
which network to view and how to sort the results. You
can also choose whether to view addresses that are neither in DNS
nor have responded to pings. These are typically uninteresting,
so by default they are not displayed. Each host displayed on the
page has a hostname (if available), a last ping time, and a colored
LED indicating the current status of the address. The
LED color will indicate one of five states:
Green Address exists in DNS, and is currently answering
Yellow Address exists in DNS, but has not answered in more
than 24 hours (configurable).
Red Address exists in DNS, but has not answered in more than
1 week (configurable).
Blue Address does not exist in DNS, however it is answering
pings. This could indicate an unauthorized use of an address, or
it could indicate something such as a DHCP assigned address
that has no DNS entry.
Purple Address does not exist in DNS, and does not answer
pings. This is generally uninteresting to us, so by default these
hosts are not displayed. See Figure 1.
As previously mentioned, Hawk has three components. These components
may each be hosted on separate machines or the same machine, depending
on your environment. The monitor should run happily with any version
of Perl 5. But the following additional modules will need to be
installed: Net::Netmask, Net::Ping, DBI, and DBD::mysql. You can
install these modules as follows:
# perl -MCPAN -e "install Net::Netmask"
# perl -MCPAN -e "install Net::Ping"
# perl -MCPAN -e "install DBI"
# perl -MCPAN -e "install DBD::mysql"
The database used for storing Hawks data is MySQL. Hawk
was originally written using MySQL 3.23, but since the database
requirements are minimal, you can probably get away with older versions,
and certainly newer ones. Before the Perl backend and PHP frontend
can communicate with the database, you must create the appropriate
database and table to store the data. Next, you need to create a
database user to allow read and write access to the data from the
scripts. Connect to the database as follows:
# mysql --user=<mysql admin user> --password --host=<mysql server>
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8 to server version: 3.23.40-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
Create the database hawk and table ip using
the following SQL statements:
create database hawk;
create table ip (
ip char(16) NOT NULL default '0',
hostname char(255) default NULL,
lastping int(10) default NULL,
primary key (ip),
unique key ip (ip),
key ip_2 (ip)
) type=MyISAM comment='Table for last ping time of hosts';
Create the user hawk using the following SQL:
identified by 'hawk';
identified by 'hawk';
This will give permission for the user hawk to do basic
selects and updates from any host on the network. For added security,
you can limit this to a given host by changing the % to
a specific hostname.
For managing MySQL, you may want to consider installing phpMyAdmin,
which is available from:
phpMyAdmin is a Web-based tool for administering MySQL databases.
It can be used to add/drop databases, create/drop/alter tables, delete/edit/add
fields, execute SQL, manage keys, and import/export data. You can
use this tool later in the installation process to verify that your
database is being populated with data.
The interface was written using PHP 4.0.6 under Apache 1.3.22.
Later versions of PHP should work fine, and any version of Apache
will probably work. If your Web server is running on the same machine
as the Hawk monitor, you can simply make a symbolic link in the
Apache document root to the PHP directory of hawk as follows:
# cd /var/apache/htdocs
# ln -s /opt/hawk/php hawk
If you are running on separate machines, you will need to copy the
entire PHP directory from the installation directory to a directory
named hawk within the Apache document root.
Hawk is hosted at SourceForge. To download, go to:
Under Latest File Releases, click Download and you will
be taken to the download page. The latest version will be highlighted.
This article is based on Hawk version 0.6. The downloaded file will
be called hawk-0.6.tar.gz. You can save this in the directory
in which you want to extract the Hawk program, (e.g., /opt). Extract
the software as follows:
# cd /opt
# tar xvzf hawk-0.6.tar.gz
# ln -s /opt/hawk-0.6 /opt/hawk
Within the installation directory, you have two subdirectories
one for the monitor and one for the PHP interface. Following is a
basic breakdown of what is installed:
./daemon - directory for perl monitor daemon
./daemon/hawk - the monitor daemon
./daemon/hawk.conf - config file for monitor daemon
./php - directory for php interface
./php/hawk.conf.inc - php web interface config file
./php/hawk.css - style sheet file for web interface
./php/hawk.php - web interface script
./php/images - directory for web interface images
The first step to configure Hawk is to edit the monitor config file
daemon/hawk.conf. The variables in this file need to follow standard
Perl syntax conventions, as this file is read into the monitor script
using a do statement. Configurable parameters in the config
file are as follows:
@networks This should contain a list of local networks
you want to be monitored by Hawk. The networks must be specified
in CIDR format. That is, if you have a class C network (24 bits)
of the range 192.168.2.0-255, the CIDR form would be 192.168.2.0/24.
@gateways This should contain the list of gateways
used by all networks. This parameter is not required, however if
it is used, the monitor will verify that the gateway is up before
trying the rest of the hosts on that network.
$frequency This parameter is the number of seconds
between checks. A 0 value will cause the monitor to loop continuously.
$pingtimeout This variable indicates how long a
ping will wait before giving up and moving on to the next host.
$debuglevel This can be set at 0-2. During initial
setup, you may want to use debug level 2. This will allow you to
see every ping, and verify database operations. Level 1 will give
basic progress reports (e.g., when each network is being checked).
Level 0 is, of course, no logging at all. You probably want to switch
to level 1 or 0 after initial install.
$logfile The name of the logfile where the above
debugging information is written.
$dbuser: mysql database username
$dbpass: mysql database password
$dbhost: database server hostname or ip address
$dbname: database name ("hawk")
$pidfile: pid file used for shutting down and restarting hawk.
See hawk.conf.sample (Listing 1).
The PHP backend has a similar simple configuration. The config
file is php/hawk.conf.inc. This file is sourced into the main hawk.php
script so, like the monitor config file, it must contain syntax
understood by PHP. The configurable parameters are as follows:
$dbuser, $dbpass, $dbhost, $dbname
Should be set to the same as above.
$redzone If a host has not been ping-able in this
amount of time (in seconds), the LED will glow red.
$yellowzone If a host has not been ping-able in
this amount of time (in seconds), the LED will glow yellow, unless
it has also surpassed $redzone.
$networks This should contain all the networks you
specified within your hawk.conf file above. However, each of the
networks is paired with a human-readable name for this parameter.
If your network contains a really large broadcast domain, it may
be too large for easy viewing on a single Web page, in which case
you can break it into logical pieces. You can do so by specifying
smaller, adjacent networks. For example, if you specified 192.168.4.0/22
in your daemon/hawk.conf above, you can break that into the following
networks in php/hawk.conf.inc for display purposes: 192.168.4.0/24,
192.168.5.0/24, 192.168.6.0/24, 192.168.7.0/24. See hawk.conf.inc.sample
The look and feel of the Web interface for Hawk are customizable
using cascading style sheets. All of the styles have been placed
into a separate CSS file, php/hawk.css.
After installation of all components is complete, the next step
is to start Hawk by hand and watch the logfile to verify proper
# /opt/hawk-0.6/daemon/hawk &
# tail -f /var/log/hawk
If you set your $debuglevel to 2, this should provide a sufficient
level of detail to identify any problems. The most common problem
is database connectivity. If the logging seems to hang at the point
it is doing a database access, the database server name might be the
issue. This will also eventually cause the script to fail and exit.
If there is a problem with user credentials (e.g., username/password),
the script will fail immediately. Once database connectivity is properly
established, the log should display every ping attempt and every database
access/update. Also, verify that data is going into the database by
viewing database logs or using a tool like phpMyAdmin.
Once proper operation is verified above, configure your system
to start Hawk at boot. Below is a sample init.d script that can
be used for starting/stopping/restarting Hawk. See hawk.init.d.sample
You will need to copy the script into your init.d directory and
make symbolic links to the appropriate rc?.d directories as follows:
For the 0, 1, S, and 6, runlevels:
ln -s /etc/init.d/hawk /etc/rc0.d/K90hawk
ln -s /etc/init.d/hawk /etc/rc1.d/K90hawk
ln -s /etc/init.d/hawk /etc/rc6.d/K90hawk
ln -s /etc/init.d/hawk /etc/rcS.d/K90hawk
For the 2, 3, and 4 runlevels:
ln -s /etc/init.d/hawk /etc/rc2.d/S90hawk
ln -s /etc/init.d/hawk /etc/rc3.d/S90hawk
ln -s /etc/init.d/hawk /etc/rc4.d/S90hawk
The location of init.d and rc?.d directories will vary between systems,
so modify the commands to match the layout of your system. Also, runlevel
5 is used differently on different systems. Some UNIX systems use
runlevel 5 for shutdown, while some Linux systems use runlevel 5 as
the default runlevel. Verify how your system uses this runlevel and
create the appropriate symbolic links as above.
Once youve verified proper operation of Hawk and installed
the above startup scripts, reboot your system at the next opportunity
to verify proper startup.
Next, you need to verify the interface is working properly by
opening the page in your browser. The URL should be something like
http://hawk.someplace.org/hawk/hawk.php. When the page loads,
select a network and click Go. The page will be redisplayed
listing the hosts on your network as in Figure 1. If this does not
work as expected, database connectivity is most likely the problem.
PHP will generally report any connectivity problems directly on
the Web page. The error messages given are usually very specific
and you should be able to identify the problem right away. You should
also check your MySQL log to verify the PHP queries are actually
reaching the database.
If you were successful with your installation, you will be able
to use Hawk to manage your DNS with a little more sanity.
Greg Heim has been working as a UNIX systems administrator
for 13 years. He has a strong background in programming and relational
databases. He can be contacted at: firstname.lastname@example.org.