User Tools

Site Tools


  • ispconfigdns
  • Jonathan Haack
  • Haack's Networking


This tutorial is for self-hosting your own authoritative DNS server using ISP Config and bind9. The requirements are that you own three IPs, have a domain dedicated just for this with three A records pointing towards three clean Debian installs on each of the VMs. The names would be,, and Okay, since my data center only just rolled out ipv6 support, I had to disable ipv6 since I could not set ipv6 PTR records at the time of creation:

nano /etc/sysctl.d/00_ipv6_off.conf
net.ipv6.conf.all.disable_ipv6 = 1

One of the servers will be primary and the others mirrors of that. For this reason, they will need to use a common mysql database on the primary. Since I did not want to expose mysql publicly, I created a separate NIC on each VM on virsh's default virtual bridge, virbr0. You can also use bridge-utils and just brctl addbr virbr0 but since this was ready to go and did not require me tinkering with my primary interfaces or ifupdown, I just used it.

On virtmanager > Connection Details > Start virbr0 > Auto Start
On each VM > open > Add Hardware > NIC > Bridge > virbr0

Of course, you can also do this with pure virsh and xml, but with -X passthrough, it's just so easy to use the GUI and saved a ton of time. Remember, each VM also needs to be publicly accessible as it is an authoritative DNS server, so the bridge above is just the secondary interface with a private subnet. Here's an example of what /etc/network/interfaces needs to look like inside each of the three VMs:

nano /etc/network/interfaces
auto enp1s0
iface enp1s0 inet static
auto enp7s0
iface enp7s0 inet static

The next machine would .3, the next one .4. Once you set up all the VMs with the primary and secondary interfaces, make sure each of them can reach the other. You can ping for example from inside the .2 box, and so on. Once they are all reachable, set up the fully qualified hostnames in each.

nano /etc/hosts

The contents being as follows:       localhost        ns1 ns1 ns2 ns3

Each VM needs a similar configuration, but the second line would change to and ns2, and and ns3 on the other boxes. It's now time to install ISPConfig on the primary box. In my case, I chose to first install a complete configuration and then disabled services manually afterwards. I ran the following official script on

wget -O - | sh -s

After it completes, make sure to record your admin password and mysql root password securely. It's now time to set up the database on the primary server. It installs roundcube, openVZ, and some other services by default. I later removed all of these after testing and just installed a simple send-only MTA with postfix and nothing else. You should customize to your preference and/or adjust the install script with flags to limit what it brings in. You now want to create users for each of the slave servers:

sudo mysql -u root -p

Then run the following mysql commands for each slave server (.3 and .4) so they can communicate with the primary:

CREATE USER 'root'@'' IDENTIFIED BY 'securepass';


CREATE USER 'root'@'' IDENTIFIED BY 'securepass';


After that is done, log in to the web panel and add a firewall record with 22,80,443,53,8080,8081 open for tcp and 53 open on udp. Next, we need to manually add a firewall record at the command line to allow mysql to communicate across the local subnet:

ufw allow from to any port 3306 proto tcp

Next, set up each of the slave servers ns2 and ns3 by shelling in to them and running this script:

wget -O - | sh -s -- --no-web --no-mail --use-php=system --interactive

Make sure to record the mysql and ispconfig database passwords for each securely. Be sure to select expert mode and be sure to use the local address of the primary,, not the external for mysql communcations. Use the securepassword you chose while setting up the database above for the primary. Make sure you say “n” to adding the web panel and/or other services not needed for DNS. Next, we need to log in to the web panel of the primary server and go to Settings / and Settings / and change the “Is mirror of Server” dropdown to Once that's done, we can now set up our zone on ISP Config and the Glue records on the Registrar. To set up your zone, go to DNS / Add new DNS zone with Wizard on the web panel, and enter your domain, the IP of your primary name server, and for the nameservers enter and Enter an email of your choice and select create zone. You need to now add a third NS record for your other name server, and don't forget the trailing “.” as this will cause hours of caching errors. Secondly, make sure to create three corresponding A records for each domain (ns1, ns2, ns3) that point to the IPs of those domains. Once all the zone is added as follows and all records entered properly, check /etc/bind/ and make sure there is no .err appended to If there is, you likely parsed something wrong while entering the records. Adjust and debug until the error goes away when you restart bind9's service. It's now time to set up the Glue records at your Registrar. To do that, go to your Registrar's Name Server settings, and register name servers for the domain. In the settings, point each of those name servers to the IPs you have set up for them. Once those Glue records are setup, you now change the Name Servers from the Registrar's to your own. Give it a good 1-2 hours to cache, and check this site to see if you did everything correctly:


Note everything worked properly at first, and I had to spend some time debugging. Using host and dig can be helpful while debugging:

dig ns
dig ns @

The commands above check your default dns for the records and/or check the Name Server itself (the one you are setting up now). These commands are particularly helpful in determining whether your name server can return the proper records and/or whether they have already cached to other servers or not. Also, while debugging and re-adding a zone, I did once have to manually remove the “.err” from /etc/bind and restart bind to get the changes to stick. This is apparently due to a DNSsec glitch in ISPConfig.

Note: This tutorial is fairly advanced and there are lots of omitted smaller steps, days of debugging that are left unreported and so on. Feel free to email or hit me up on Mastodon (see home page of Wiki) if you need help.

oemb1905 2023/05/21 16:46

computing/ispconfig.txt · Last modified: 2023/05/21 22:57 by oemb1905