Building NICTool on FreeBSD 11.2 (as KVM Virtual Machine)

Building NICTool on FreeBSD 11.2 (as KVM Virtual Machine)

This provide summary instructions for building NICTool DNS management solution on FreeBSD 11.2 (was a KVM Virtual Machine). In my case I am looking for way to manage a set of private IP address ranges (and get LetEncrypt certificates for these machines) in a repeatable and easy to manage way.

NICTool is just one of a number of options for DNS management I have looked at and in addition to providing summary of installation I will also provide results of use and merits relative to other tools.

See "A Diversion to DNS, DHCP, Certificates and Private Addresses" for broader context.

Build NICTool Dependencies on FreeBSD 11.2

NOTE: It is October 2019 and I am building on top of FreeBSD 11.2 as there appears to be a bug with FreeBSD 11.3 that prevents it from detecting NIC card under QEMU / KVM with OVMF (UEFI) VM.

To build NICTool requires you to first build / install the dependencies (I have elected to do this via ports collection).

  1. Install FreeBSD 11.2 on QEMU / KVM Host (Q35 machine type) with: CD == SATA Raw, HD == SATA qcow2, NIC = e1000
  2. Install FreeBSD Ports Collection
  3. Build OpenSSL - Multi-threaded with zlib support (builds Perl 5.30 as dependency)
  4. Build MySQL 5.7 Server (no Storage Engines) - post installation you will find the root password in /root/.mysql_secret and you should run "mysql_secure_installation" script.
  5. Build BIND 9 (9.14 threaded)
  6. Build Apache (with BDB and MySQL support)

Build NICTool on FreeBSD 11.2

  1. Build NICTool (2.34) - note on FreeBSD 11.2, the documented process suggests you download src package via as tar ball via "The Network People" store download site, so I did this rather than git clone.
  2. Following instruction with FreeBSD 11.2 resulted, I go the following port missing: p5-App-cpanminus and the following extra perl modules: Time::TAI64 & Net::DNS::Zonefile. This is managed via cpanm (p5-App-cpanminus) python module management tool rather than via ports collection.
  3. When you get to database table creation you will first need to create the nictool user in db (@localhost in my case as bind, mysql & nictool are all on the same machine).
CREATE USER 'mynictool'@'localhost' IDENTIFIED BY 'secretstuff' ;

4. Ensure that the configuration files in /usr/local/nictool/server/lib/nictoolserver.conf & /usr/local/sql/ reflect the id/password created in step 3

5. Run table create script: "perl /usr/local/nictool/server/sql/". If this fails due to " ... TIMESTAMP DEFAULT 0" statement, then the reason if due to MySQL "sql_mode" which was changed in 5,7 release. The work around is to remove the sql mode item that cause this error:

mysql -u root -p
> SELECT @@GLOBAL.sql_mode ;  // see setting
Result >>>
| @@GLOBAL.sql_mode
// So now remove the "NO_ZERO_DATE" option
// You should now be ok with MySQL 5.7

6. Make and enable apache mod_perl (the required port is: /usr/ports/www/mod-perl2). The installation process requires SSL configuration. The instructions for FreeBSD nictool outline steps achieve this using self signed certificate. To avoid this I used LetsEncrypt certificate and outline steps to get this in main post: A Diversion to DNS, DHCP, Certificates and Private Addresses".  As this is private network and I do not want to have to expose another Web Server for host based ACME, I will get internal DNS server (BIND) going and expose this. Then you can get LetsEncrypt wildcard certificates for internal machines. See below for LetsEncrypt instructions.

7. Final step is to do some configuration via on Apache file by doing into: /usr/local/etc/apache24/Includes/nictool.conf and /usr/local/etc/apache24/httpd.conf

# // copy the nictool apache config file
fetch -o /usr/local/etc/apache24/Includes/nictool.conf \
# // edit ServerName and point certifates config to letsencrypt ones
vi /usr/local/etc/apache24/Includes/nictool.conf
# // Now enable ssl, perl modules and set ServerName
# vi /usr/local/etc/apache24/httpd.conf
# service apache24 restart

8. Point your browser to web server...

Using NICTool and Results

Once you start to use NICTool, you get a sense of the motivations for its creation.

Features include:

  • Management Roles and Groups - to help you partition the set of resource (zones and name services) being managed, each of which can have its own set of roles for management defined with various levels of privileges
  • Multiple Zones and Sub-Zones - to help manage a set of independent zones and sub-zones within these. This is consistent with need to support a large pool of domains as a service with the Management Roles support allowing delegation of responsibilies to alternate management teams
  • Integration with a wide variety of DNS servers including BIND and DNS Update.

In my context these features are more complete and sophisticated than my needs.

Using the tool I run into some immediate issues:

  1. I was not able to create a new zone and so could not start working on my configuration.  Here is error log (/var/http-error.log):
DBD::mysql::st execute failed: Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'nictool.nt_delegate.delegated_by_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by at /usr/local/lib/perl5/site_perl/DBIx/ line 172.
exec_query called by NicToolServer::Zone, 360
         SELECT nt_zone.nt_zone_id,
                 count(*) as delegated_records,
               1 as pseudo
         FROM nt_delegate
         INNER JOIN nt_zone_record ON nt_delegate.nt_object_id=nt_zone_record.nt_zone_record_id
         INNER JOIN nt_zone ON nt_zone.nt_zone_id=nt_zone_record.nt_zone_id
       WHERE nt_delegate.nt_group_id=3 AND nt_delegate.nt_object_type='ZONERECORD'
         GROUP BY nt_zone.nt_zone_id
        DBI error: Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'nictool.nt_delegate.delegated_by_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by at /usr/local/lib/perl5/site_perl/ line 1598.
Client error: 505: : ModPerl::ROOT::ModPerl::Registry::usr_local_nictool_client_htdocs_group_zones_2ecgi:/usr/local/nictool/client/htdocs/group_zones.cgi:197 at /usr/local/nictool/client/lib/ line 1317.

Now I am sure given sufficient time I could work out what the problems was, but as a non perl user I put this in the to hard basket for the moment...

2. My next approach was to avoid data entry and just load my existing zones files into DB by using the "" import tool. This also failed, as for some reason it would not parse a perfectly good zone files (it barfed on the $ORIGIN statement at the start of the file). So I tried to resolve by doing some file clean up and looking for zone file parsers and generators.


I quickly stopped myself looking into NICTool, as this was starting to look like a "going down rat hole" exercise, trying to look at perl code and hand editing BIND acceptable zones files.

I want to state that some of the issues I had may stem from my trying run NICTool on FreeBSD 11.2, when the instructions are for 10.x and I also used more recent MySQL version, which resulted in issues with "sql_mode".

As a tool NICTool looks like it has rich features, it is web based and supports multiple DNS servers, so if your needs are sophisticated and you are perl expert I believe you would find tool useful and could provide contribution into the github code base (a worthy endevour to my mind).

So next I looked into Admin4...

References & Links:

LetsEncrypt - your go to place for certificates, not just free but automated as well

NICTool - DNS Management Software

MySQL TIMESTAMP DEFAULT - Info about MySQL 5.7 sql_mode issue.

DNS and BIND (5th Ed) - By Cricket Liu & Paul Albitz (picture is from cover)

nsupdate / tsig-gen / ddns-confgen - bind utilities

rfc2136 - Dynamic Updates in the Domain Name System (DNS UPDATE)