{"id":4918,"date":"2024-05-07T02:02:00","date_gmt":"2024-05-07T06:02:00","guid":{"rendered":"https:\/\/www.both.org\/?p=4918"},"modified":"2024-05-03T10:03:20","modified_gmt":"2024-05-03T14:03:20","slug":"build-your-own-dns-server-on-linux","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=4918","title":{"rendered":"Build your own DNS server on Linux"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"4918\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<h2 class=\"wp-block-heading\">Learn how to use BIND to set up your own server for resolving domain names.<\/h2>\n\n\n\n<p class=\"has-small-font-size\">Image by: Geralt. CC0.<\/p>\n\n\n\n<p>In the previous article in this two-part series, <a href=\"https:\/\/www.both.org\/?p=4759\" data-type=\"link\" data-id=\"https:\/\/www.both.org\/?p=4759\" target=\"_blank\" rel=\"noreferrer noopener\">Introduction to the Domain Name System (DNS)<\/a>, I described how the DNS database is structured and how to configure name services on a client. I also listed and described some of the more common DNS records you are likely to encounter when building a name server or just trying to interpret the results of a <strong>dig<\/strong> command.<\/p>\n\n\n\n<p>In this article, I show you how to build your own name server using <a href=\"https:\/\/www.isc.org\/downloads\/bind\/\" target=\"_blank\" rel=\"noreferrer noopener\">BIND<\/a> (Berkeley Internet Name Domain). It is not as difficult as you might think, especially because you can do it in two stages. We&#8217;ll start by learning how to create a caching name server, then move on and learn how to upgrade that to a complete primary<sup data-fn=\"e8d429dc-ff79-4f0a-96a1-98d52d80a13f\" class=\"fn\"><a href=\"#e8d429dc-ff79-4f0a-96a1-98d52d80a13f\" id=\"e8d429dc-ff79-4f0a-96a1-98d52d80a13f-link\">1<\/a><\/sup> domain name server for your network, complete with forward and reverse zone files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">But Why??<\/h2>\n\n\n\n<p>But first, why did I go to the trouble of creating my own name server? I had three reasons for doing this. <\/p>\n\n\n\n<p>My primary consideration was that my network was growing and changing, so updating the \/etc\/hosts files on every computer became a challenge. The time required to make these changes was becoming greater as each new computer was added to my network. <\/p>\n\n\n\n<p>Second, I wanted to learn about various network services including centralized network configuration so I set up a DHCPD server for my network; then it only made sense to also add a name server. I used BIND for my name server because it&#8217;s still the most common and well-known one there is. <\/p>\n\n\n\n<p>Third, the name servers provided by my internet service providers (ISP) in those ancient days mostly sucked. DNA database updates were sporadic and slow when they did occur. I encountered instances where the IP address for domains were incorrect. There were even times when the ISPs name services were down for hours at a time. <\/p>\n\n\n\n<p>For these reasons and more, I decided I would create my own name server. I&#8217;ve been pleased with the results and will never go back to using name services supplies by an ISP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up a DNS server using BIND<\/h2>\n\n\n\n<p>Setting up a name server using BIND is quite straightforward, so I&#8217;ll show you how to do so on any computer you might have available for experimentation. This little lab project will show you how to install and configure BIND on your computer as a caching name server, test it, then set it up as a primary name server with a zone file that you can use as a name resolver for your network or just for testing.<\/p>\n\n\n\n<p>Setting up a name server on any GNU\/Linux computer you have available is technically possible because it will not interfere with other hosts on the network or their operation. However, you should probably not do this on a computer that you do not own or have the right to modify unless you have explicit permission to do so.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">My setup<\/h2>\n\n\n\n<p>You only need one computer to perform all but one of the tasks in this lab project. I use this setup on my laptops because the name servers provided by DHCP (Dynamic Host Configuration Protocol) when I connect to non-home networks using either wired or wireless connections can sometimes be unreliable. To show that almost any host can perform well as a name server, I long ago tested this project on a long defunct and recycled <a href=\"http:\/\/www.pcmag.com\/article2\/0,2817,2305998,00.asp\" target=\"_blank\" rel=\"noreferrer noopener\">ASUS EeePC 900<\/a>&nbsp;netbook.<\/p>\n\n\n\n<p>I will use a VM with a private IP address for this project but you should use the IP address of the host that you are using.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The hosts file<\/h2>\n\n\n\n<p>First, let&#8217;s take a look at the <strong>\/etc\/hosts<\/strong> file. In its default state, the hosts file should look like Figure 1, below. The uncommented lines are for IPV4 and IPV6. These two lines are required for a Linux computer to function correctly as they allow the host to perform necessary internal communications. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Loopback entries; do not change.\n# For historical reasons, localhost precedes localhost.localdomain:\n127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4\n::1         localhost localhost.localdomain localhost6 localhost6.localdomain6\n# See hosts(5) for proper format and other examples:\n# 192.168.1.10 foo.mydomain.org foo\n# 192.168.1.13 bar.mydomain.org bar<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 1: You can maintain a simple hosts file to perform the function of a resolver in small networks.<\/em><\/p>\n\n\n\n<p>Earlier versions of the file in Figure 1 have only the two active lines and none of the comments. I suggest using the command <code><strong>man 5 hosts<\/strong><\/code> for additional details. Although you can add hostnames and their respective IP Addresses for your local network as shown in Figure 2, this is not an optimal solution to name services, especially with larger networks or when traveling. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Loopback entries; do not change.\n# For historical reasons, localhost precedes localhost.localdomain:\n127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4\n::1         localhost localhost.localdomain localhost6 localhost6.localdomain6\n# See hosts(5) for proper format and other examples:\n# 192.168.1.10 foo.mydomain.org foo\n# 192.168.1.13 bar.mydomain.org bar\n\n<code># Lab hosts\n192.168.0.1       server\n192.168.0.21      host1\n192.168.0.22      host2\n192.168.0.23      host3\n192.168.0.24      host4<\/code><\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 2: An \/etc\/hosts file with local hostnames added.<\/em><\/p>\n\n\n\n<p>Most of you will not have any entries other than the default localhost lines. But if you&#8217;re already using the hosts file for name service on your network you&#8217;ll need to maintain the hosts file on every computer in your network. As your network grows that will eventually become a lot of work to maintain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparation<\/h2>\n\n\n\n<p>A caching name server can&#8217;t replace your use of <strong>\/etc\/hosts<\/strong> to resolve hostnames on the internal network. However, compared to using an ISP or other public name server a caching name server can improve performance when resolving commonly used external names, such as <a href=\"http:\/\/www.cnn.com\">www.cnn.com<\/a>. The best part is that setting up a caching name server is quite easy.<\/p>\n\n\n\n<p>Before starting, you should prepare by performing the following steps.<\/p>\n\n\n\n<p>First, make backup copies of the files <strong>\/etc\/hosts<\/strong>, <strong>\/etc\/named.conf<\/strong>, <strong>resolv.conf<\/strong>, and your firewall configuration and rules. If they are not already installed, use your distribution&#8217;s package manager to install the following BIND RPMs: <strong>bind<\/strong>, <strong>bind-chroot<\/strong>, and <strong>bind-utils<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configure resolv.conf<\/h2>\n\n\n\n<p>To enable your lab host to use the caching name server, you must add a name server line to point to your own host in <strong>\/etc\/resolv.conf<\/strong>. This used to be simple but has changed since NetworkManager and systemd-resolved.service replaced the old SystemV network service. I&#8217;ve also found problems with name resolution when using the systemd-resolved.service in conjunction with an in-network name server.<\/p>\n\n\n\n<p>I wrote an article for my systemd series, <a href=\"https:\/\/www.both.org\/?p=3889\" data-type=\"link\" data-id=\"https:\/\/www.both.org\/?p=3889\" target=\"_blank\" rel=\"noreferrer noopener\">systemd \u2014 #12: Fixing systemd-resolved name service failures using Ansible<\/a>, that describes the problem with systemd-resolved.service and how to resolve it. I suggest you read that article before continuing with this one. Don&#8217;t let the title of the article fool you &#8212; the fix doesn&#8217;t require Ansible unless you&#8217;re applying it to a large number of Linux hosts. I won&#8217;t copy that entire article, but here are the steps you need to take for your name server to work correctly.<\/p>\n\n\n\n<p>Let&#8217;s look at the default resolv.conf setup in Figure 3 before we change anything. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>ll \/etc\/resolv.conf<\/strong> \nlrwxrwxrwx. 1 root root 39 Apr 13  2023 \/etc\/resolv.conf -&gt; ..\/run\/systemd\/resolve\/stub-resolv.conf\n\n# <strong>cat \/etc\/resolv.conf<\/strong> \n# This is \/run\/systemd\/resolve\/stub-resolv.conf managed by man:systemd-resolved(8).\n# Do not edit.\n#\n# This file might be symlinked as \/etc\/resolv.conf. If you're looking at\n# \/etc\/resolv.conf and seeing this text, you have followed the symlink.\n#\n# This is a dynamic resolv.conf file for connecting local clients to the\n# internal DNS stub resolver of systemd-resolved. This file lists all\n# configured search domains.\n#\n# Run \"resolvectl status\" to see details about the uplink DNS servers\n# currently in use.\n#\n# Third party programs should typically not access this file directly, but only\n# through the symlink at \/etc\/resolv.conf. To manage man:resolv.conf(5) in a\n# different way, replace this symlink by a static file or a different symlink.\n#\n# See man:systemd-resolved.service(8) for details about the supported modes of\n# operation for \/etc\/resolv.conf.\n\nnameserver 127.0.0.53\noptions edns0 trust-ad\nsearch both.org<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 3: The default \/etc\/resolv.conf file is a symbolic link that points to a &#8220;stub&#8221; file, \/run\/systemd\/resolve\/stub-resolv.conf. That file contains the comments and configuration shown here.<\/em><\/p>\n\n\n\n<p>In the default resolver setup, \/etc\/resolv.conf points to a &#8220;stub&#8221; file, \/run\/systemd\/resolve\/stub-resolv.conf that contains the configuration used by systemd-resolved. The only solution that reliable host resolution for me is to stop and disable systemd-resolved.service. This causes name resolution to revert to the NSSwitch resolution. <\/p>\n\n\n\n<p>First, I deleted the existing link and created a new \/etc\/resolv.conf file to replace it. I added the content in Figure 4. Be sure to use the correct IP addresses for your own internal network.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>search both.org\nnameserver 192.168.0.101\nnameserver 8.8.8.8\nnameserver 8.8.4.4<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 4: I created a new \/etc\/resolv.conf file with the content shown here.<\/em><\/p>\n\n\n\n<p>Restart the NetworkManager service. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>systemctl restart NetworkManager<\/strong><\/code><\/pre>\n\n\n\n<p>The NSS resolver takes over, and name services work as expected. Now attempt to ping a common public host that does not block ICMP (Internet Control Message Protocol) packets. I typically use one of three public domains intended explicitly for testing, example.com, example.net, and example.org.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>ping www.example.com<\/strong><\/code><\/pre>\n\n\n\n<p>You should get an &#8220;unknown host&#8221; or &#8220;Name or service not known&#8221; error because you currently have no working DNS service or resolver defined in the resolv.conf file. Now use the <strong>dig<\/strong> command to see if name services is working.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>dig www.example.com<\/strong><\/code><\/pre>\n\n\n\n<p>You should get the error, &#8220;Connection timed out; no servers could be reached.&#8221;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Set up a caching name server<\/h2>\n\n\n\n<p>A caching name server is not an authoritative source for any domain. It simply caches the results of all name resolver requests from the network that it serves to speed up responses to future requests for the same remote host.<\/p>\n\n\n\n<p><em>Note: The <strong>named.conf<\/strong> file is very particular about syntax and especially punctuation. Semicolons are used to delineate the end of an entry and the end of a stanza as well as the end of a line. Be sure to add them in correctly as shown in the samples.<\/em><\/p>\n\n\n\n<p>For the initial setup of the caching name server making a couple modifications to the default <strong>\/etc\/named.conf<\/strong> file is necessary, so edit that file using your favorite editor. First, add the IP address of your local test host to the &#8220;listen-on port 53&#8221; line as shown in Listing 2, below. This enables <strong>named<\/strong> to listen on the external IP Address of your host, so that other computers can use it as a name server as well.<\/p>\n\n\n\n<p>By default, BIND refers to the Internet&#8217;s root name servers to locate the authoritative name servers for a domain. It is possible to specify other servers that are called &#8220;Forwarders&#8221; to which the local instance of BIND will send requests instead of the root servers. This does increase the possibility of DNS hijacking.<\/p>\n\n\n\n<p>Add a &#8220;forwarders&#8221; line as shown below. This tells your caching DNS server where to obtain IP Addresses when they are not already cached locally. The IP Addresses in the listing below is for the <a href=\"https:\/\/developers.google.com\/speed\/public-dns\/\" target=\"_blank\" rel=\"noreferrer noopener\">Google public DNS servers<\/a> You could use your local ISP or OpenDNS or some other public name server as your forwarder. It is not necessary to define any forwarders and, in that case, BIND would use the Internet root servers as defined in the file <strong>\/var\/named\/named.ca<\/strong> to locate the authoritative name servers for domains if no forwarders are defined. But for this exercise, please define the forwarders as I have in Figure 5. <\/p>\n\n\n\n<p>Comment out the IPV6 line because we are not using IPV6 in the lab environment. Note that the &#8220;\/\/&#8221; two forward slashes denote comments in the <strong>named.conf<\/strong> file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\n\/\/ named.conf\n\/\/ Provided by Red Hat bind package to configure the ISC BIND named(8) DNS\n\/\/ server as a caching only name server (as a localhost DNS resolver only).\n\/\/ See \/usr\/share\/doc\/bind*\/sample\/ for example named configuration files.\n\/\/\n\/\/\n\noptions {\n        <strong>listen-on port 53 { 127.0.0.1; 192.168.0.203; };<\/strong>\n<strong>\/\/      listen-on-v6 port 53 { ::1; };<\/strong>\n        <strong>forwarders { 8.8.8.8; 8.8.4.4; };<\/strong>\n        directory       \"\/var\/named\";\n        dump-file       \"\/var\/named\/data\/cache_dump.db\";\n        statistics-file \"\/var\/named\/data\/named_stats.txt\";\n        memstatistics-file \"\/var\/named\/data\/named_mem_stats.txt\";\n   <strong>     allow-query     { localhost; 192.168.0.0\/24; };<\/strong>\n        recursion yes;\n\n        dnssec-enable yes;\n        dnssec-validation yes;\n        dnssec-lookaside auto;\n\n        \/* Path to ISC DLV key *\/\n        bindkeys-file \"\/etc\/named.iscdlv.key\";\n\n        managed-keys-directory \"\/var\/named\/dynamic\";\n};\nlogging {\n        channel default_debug {\n                file \"data\/named.run\";\n                severity dynamic;\n        };\n};\nzone \".\" IN {\n        type hint;\n        file \"named.ca\";\n};\ninclude \"\/etc\/named.rfc1912.zones\";\ninclude \"\/etc\/named.root.key\";\n<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Fiogure 5: The \/etc\/named.conf file provides the simple configuration required to set up a caching name server. The lines that need to be added or changed are highlighted in bold.<\/em><\/p>\n\n\n\n<p>Add the local network address, 192.168.0.0\/24, to the <strong>allow-query<\/strong> line. This line specifies the network(s) from which DNS queries will be accepted by this DNS server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Start the named service<\/h3>\n\n\n\n<p>Now start the named service and configure the named service to start at every boot. I use the <strong>systemctl<\/strong> command on my Fedora host, but the command may be different on your host, depending upon the distribution you are using. Note that the name of the BIND resolver service is named.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>systemctl enable --now named<\/strong><\/code><\/pre>\n\n\n\n<p>The first test you can perform to ensure that your caching name server is working is to use <strong>dig<\/strong> to locate the DNS database information for wally2.both.org. To further test your caching name server, use the <strong>dig<\/strong> command to obtain the IP Address(es) for some common Internet websites, such as <a href=\"http:\/\/www.opensource.com\">www.opensource.com<\/a>, CNN, Wired, and any others you like. The results should now show your host as the responding server.<\/p>\n\n\n\n<p>At this point your caching name server will correctly resolve hosts on the Internet and that is because those DNS requests for public hosts are forwarded to the Google public name servers\u2014refer to the &#8220;forwarders&#8221; line in <strong>named.conf<\/strong>. However, you are still dependent upon the <strong>\/etc\/hosts<\/strong> file for internal name services. Creating a primary name server can solve that problem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a primary name server<\/h2>\n\n\n\n<p>Once you create a caching name server, converting it into a full-fledged primary name server is not too difficult. A primary name server is the authoritative source for the domain it represents.<\/p>\n\n\n\n<p>You need to change <strong>named.conf<\/strong> again and create a couple new files. You&#8217;ll create a domain called Example.com, which is a domain name reserved for example purposes in documents like this one. The Example.com domain does have an IP address on the Internet and a very sparse website, but you can use the name in the rest of your lab project without causing problems for anyone. You&#8217;ll use the Example.com domain as the internal domain name for the rest of this exercise.<\/p>\n\n\n\n<p>The two new files you&#8217;ll create are the forward and reverse zone files, which you&#8217;ll place in the <strong>\/var\/named directory<\/strong>. This location is specified by the &#8220;directory&#8221; directive in the <strong>named.conf<\/strong> configuration file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create the forward zone file<\/h3>\n\n\n\n<p>The forward zone file contains &#8220;A&#8221; records that pair the names of the hosts in the zone, aka domain, with their respective IP addresses. It may also contain CNAME records, which are aliases for the real hostnames in the A records, and MX records for mail servers.<\/p>\n\n\n\n<p>Create a basic forward zone file, <strong>\/var\/named\/example.com.zone<\/strong>, and add the following lines to it. Your zone file should look like the sample zone file in Figure 6 when you&#8217;re finished.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>; Authoritative data for example.com zone\n;\n$TTL 1D\n@   IN SOA  epc.example.com   root.epc.example.com. (\n                                       2017031301      ; serial\n                                       1D              ; refresh\n                                       1H              ; retry\n                                       1W              ; expire\n                                       3H )            ; minimum\n\n$ORIGIN         example.com.\nexample.com.            IN      NS      epc.example.com.\nepc                     IN      A       127.0.0.1\nserver                  IN      A       192.168.25.1\nwww                     IN      CNAME   server\nmail                    IN      CNAME   server\ntest1                   IN      A       192.168.25.21\nt1                      IN      CNAME   test1\ntest2                   IN      A       192.168.25.22\ntest3                   IN      A       192.168.25.23\ntest4                   IN      A       192.168.25.24\n\n; Mail server MX record\nexample.com.            IN      MX      10      mail.example.com.\n<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\">Figure 6: The forward zone file for the Example.com domain contains the hostnames and their IP addresses for this domain.<\/p>\n\n\n\n<p>The first non-comment line in Figure 6 is the Time To Live specifier, which in this case is one day for all records that are not otherwise specified. D stands for Day. The specifiers in the SOA (Start of Authority) line are just as obvious. Details of the parameters in the SOA record are described in some detail <a href=\"http:\/\/www.zytrax.com\/books\/dns\/ch8\/soa.html\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>The NS record must have the FQDN (Fully Qualified Domain Name) of the host on which you are performing this lab project. There must also be an A record in the file with a valid IP address for the host. In this case, you should use the localhost IP address of 127.0.0.1.<\/p>\n\n\n\n<p>The entries shown above will give you a few hostnames with which to experiment.<\/p>\n\n\n\n<p>Be sure to use today&#8217;s date and append a counter starting at 01 for the serial number. The serial number above is the first change of March 4, 2017. The serial number is incremented whenever the zone file is changed. If there were secondary name servers that used this one for a primary, they would not be updated unless the serial number is incremented.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Add the forward zone files to named.conf<\/h3>\n\n\n\n<p>Before your DNS server will work, however, you need to create an entry in <strong>\/etc\/named.conf<\/strong> that will point to your new zone file. Add the lines sown in Figure 7 to create the entry for the top-level hints zone but before the &#8220;include&#8221; lines.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zone \"example.com\" IN {\n        type master;\n        file \"example.com.zone\";\n};\n<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 7: Add these lines to the named.conf file to add the Example.com zone file to the resolver configuration.<\/em><\/p>\n\n\n\n<p>Now restart <strong>named<\/strong> to make these changes take effect. Test your name server by using the <strong>dig<\/strong> and <strong>nsloookup<\/strong> commands to obtain the IP Addresses for the hosts you have configured in the forward zone file. Note that the host does not have to exist on the network for the <strong>dig<\/strong> and <strong>nslookup<\/strong> commands to return an IP Address.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>dig test1.example.com<\/strong>\n# <strong>dig t1.example.com<\/strong>\n# <strong>dig mx example.com<\/strong>\n# <strong>dig mail.example.com<\/strong>\n# <strong>nslookup test3.example.com<\/strong>\n# <strong>dig www.amazon.com<\/strong><\/code><\/pre>\n\n\n\n<p>Be aware that using the FQDN for these commands is necessary except for the <strong>nslookup<\/strong> command as long as the domain and search entries of Example.com are provided in the <strong>\/etc\/resolv.conf<\/strong> file. In this case, they probably are not, so just use the FQDNs for all testing in this project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using the root name servers<\/h3>\n\n\n\n<p>Notice that the root name servers are given as the authoritative servers for the Amazon.com lookup. But remember you&#8217;re using the Google public name servers as forwarders. Now comment out the forwarders line in <strong>named.conf<\/strong> and restart <strong>named<\/strong>. Run the above commands again to compare the results that are returned. The results should look similar to those in Figure 8.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>dig www.amazon.com  <\/strong>   \n\n; &lt;&lt;>> DiG 9.18.26 &lt;&lt;>> www.amazon.com\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 61868\n;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version: 0, flags:; udp: 1232\n; COOKIE: 77e0056307150851010000006634e53bdde434a5a1bfe961 (good)\n;; QUESTION SECTION:\n;www.amazon.com.                        IN      A\n\n;; ANSWER SECTION:\nwww.amazon.com.                      1800    IN      CNAME   tp.47cf2c8c9-frontier.amazon.com.\ntp.47cf2c8c9-frontier.amazon.com.      60    IN      CNAME   d3ag4hukkh62yn.cloudfront.net.\nd3ag4hukkh62yn.cloudfront.net.         60    IN      A       18.161.75.84\n\n;; Query time: 133 msec\n;; SERVER: 192.168.0.52#53(192.168.0.52) (UDP)\n;; WHEN: Fri May 03 09:23:07 EDT 2024\n;; MSG SIZE  rcvd: 176<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 8: The results of a lookup on <a href=\"http:\/\/www.amazon.com\">www.amazon.com<\/a> have some interesting information including times to live for the various record types.<\/em><\/p>\n\n\n\n<p>When I did this, the first call to resolve the external address for Amazon took 133ms while the data was located and returned. Subsequent results to perform the same query was 1ms, which shows the advantage of caching resolver results locally. Notice the numbers 1800, 300, and 60 in the answer section lines. Those are TTL (Times To Live) in seconds. If you perform the lookup multiple times, these numbers will change, showing the amount of time that the records have remaining to live in local cache.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the reverse zone file<\/h3>\n\n\n\n<p>A reverse zone for your domain will provide the ability to do reverse lookups. Many organizations do not do these internally, but reverse lookups can be helpful in doing problem determination. Many spam fighting configurations, such as SpamAssassin, look for reverse lookups to verify valid email servers.<\/p>\n\n\n\n<p>Create the reverse zone file, <strong>\/var\/named\/example.com.rev<\/strong> and add the contents in Figure 9. Be sure to use an appropriate serial number.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>; Authoritative data for example.com  reverse zone\n;\n$TTL 1D\n@   IN SOA  test1.example.com   root.test1.example.com. (\n                                        2017031501      ; serial\n                                        1D              ; refresh\n                                        1H              ; retry\n                                        1W              ; expire\n                                        3H )            ; minimum\n\n@       IN      NS      epc.example.com.\nexample.com.    IN      NS      epc.example.com.\n1               IN      PTR     mail.example.com.\n1               IN      PTR     server.example.com.\n21              IN      PTR     test1.example.com.\n22              IN      PTR     test2.example.com.\n23              IN      PTR     test3.example.com.\n24              IN      PTR     test4.example.com<\/code><\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 9: Use this reverse zone file, example.com.rev, for your name server.<\/em><\/p>\n\n\n\n<p>You could also name your reverse zone file <strong>\/var\/named\/25.168.192.in-addr.arpa<\/strong>, which follows older conventions. You can actually name it anything you want because you will point to it explicitly in the <strong>named.conf<\/strong> file, but using one of the two conventions will make it easier for others to follow your work.<\/p>\n\n\n\n<p>Add the reverse zone stanza in Figure 10 to <strong>named.conf<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zone    \"25.168.192.in-addr.arpa\" IN {\n       type master;\n       file \"example.com.rev\";\n};<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 10: Adding this stanza to the named.conf file enables reverse lookups.<\/em><\/p>\n\n\n\n<p>Add the stanza in Figure 10 to the <strong>\/etc\/named.conf<\/strong> file to point to the new reverse zone. Now reload <strong>named<\/strong> and test your reverse zone using the commands in Figure 11. Your results should look similar to those below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u200b# <strong>systemctl reload named<\/strong>\n# <strong>dig -x 192.168.25.23<\/strong>\n\n; &lt;&lt;>> DiG 9.10.4-P6-RedHat-9.10.4-4.P6.fc25 &lt;&lt;>> -x 192.168.25.23\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 48607\n;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version: 0, flags:; udp: 4096\n;; QUESTION SECTION:\n;23.25.168.192.in-addr.arpa.    IN      PTR\n\n;; ANSWER SECTION:\n23.25.168.192.in-addr.arpa. 86400 IN    PTR     test3.example.com.\n\n;; AUTHORITY SECTION:\n25.168.192.in-addr.arpa. 86400  IN      NS      epc.example.com.\n\n;; Query time: 21 msec\n;; SERVER: 192.168.0.203#53(192.168.0.203)\n;; WHEN: Wed Mar 15 16:18:59 EDT 2017\n;; MSG SIZE  rcvd: 112<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 11: After restarting named you should see results similar to these when you do a reverse lookup on an IP address in the reverse zone.<\/em><\/p>\n\n\n\n<p>Be sure to test some of the other reverse entries in your network and also try the following as well as other reverse lookups you want to experiment with. The <strong>-x option<\/strong> means reverse lookup.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>dig -x 192.168.25.23<\/strong><code># <strong>dig -x 192.168.25.1<\/strong><\/code><\/code><\/pre>\n\n\n\n<p>Note that not all hosts that have entries in the forward zone need to have entries in the reverse zone, but it does make for more consistent results if they do.<\/p>\n\n\n\n<p>At this point, you have a working name server using BIND. However, external hosts can&#8217;t yet use this name server because the firewall should not yet be configured to allow DNS requests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring IPTables for DNS<\/h2>\n\n\n\n<p>You can do this step if you want other hosts on your local network to use your host as their name server. The firewall on your test host probably blocks access to your host for name services. IPTables must be configured to allow UDP (User Datagram Protocol) packets inbound on your name server in order for other hosts to use it for name resolution. Use the following commands to add the required entries and save them.<\/p>\n\n\n\n<p><a href=\"https:\/\/opensource.com\/downloads\/firewall-cheat-sheet\">Add a rule to your firewall with firewalld<\/a> or IPTables that allows incoming packets on port 53 (domain) for UDP and save the new ruleset. <\/p>\n\n\n\n<p>If you&#8217;re still using IPTables, be sure to insert the new rule after the <strong>-A INPUT -m state &#8211;state RELATED,ESTABLISHED -j ACCEPT<\/strong> line, so you will have to count the number of INPUT lines in the filter table in order to do that. The number 7 in the following command means that this rule will be inserted in position number 7 in the existing INPUT rules.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>iptables -t filter -I INPUT 7 -p udp -m conntrack --ctstate NEW -m udp --dport 53 -j ACCEPT<\/strong><\/code><\/pre>\n\n\n\n<p>If you&#8217;re using firewalld you should use the following commands to add the new rule to the internal zone and to make it permanent. Firewalld manages the details of connection tracking for us.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># <strong>firewall-cmd --add-service=dns --zone=internal --permanent<\/strong>\nsuccess\n# <strong>firewall-cmd --add-service=dns --zone=internal<\/strong>\nsuccess\n# <strong>firewall-cmd --list-services --zone=internal<\/strong>\ndhcpv6-client dns mdns ntp ssh\n# <strong>firewall-cmd --list-services --zone=internal --permanent<\/strong>\ndhcpv6-client dns mdns ntp ssh<\/code><\/pre>\n\n\n\n<p>Test this from one of your other hosts using the command in Figure 12. The <strong>@epc<\/strong> argument tells the <strong>dig<\/strong> command to use the specified name server with the hostname <strong>epc<\/strong>. You should substitute either the IP address of the DNS server you have just created, or a resolvable hostname on your network that points to your new name server. ANother option would be to add that hostname with its IP address to the <strong>\/etc\/hosts<\/strong> file of the host you are using for the remote test.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><small># <\/small><strong>dig @epc test1.example.com<\/strong>\n\n; &lt;&lt;>> DiG 9.10.4-P6-RedHat-9.10.4-4.P6.fc25 &lt;&lt;>> @epc test1.example.com\n; (1 server found)\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 27957\n;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version: 0, flags:; udp: 4096\n;; QUESTION SECTION:\n;test1.example.com.             IN      A\n\n;; ANSWER SECTION:\ntest1.example.com.      86400   IN      A       192.168.25.21\n\n;; AUTHORITY SECTION:\nexample.com.            86400   IN      NS      epc.both.org.\n\n;; Query time: 0 msec\n;; SERVER: 192.168.0.203#53(192.168.0.203)\n;; WHEN: Mon Mar 13 08:45:34 EDT 2017\n;; MSG SIZE  rcvd: 92\n<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\"><em>Figure 12: Testing the name resolver you have created from a different host on the same network.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cleanup<\/h2>\n\n\n\n<p>For cleanup, you should perform the following tasks using the tools appropriate for your distribution. However, you may wish to keep this name server for your network if you don&#8217;t already have one.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Restore the original <strong>\/etc\/hosts<\/strong> file.<\/li>\n\n\n\n<li>Stop named on the resolver host used for this lab project.<\/li>\n\n\n\n<li>Disable the named service.<\/li>\n\n\n\n<li>Delete the zone files.<\/li>\n\n\n\n<li>Restore the original <strong>named.conf<\/strong> file.<\/li>\n\n\n\n<li>Restore the original <strong>resolv.conf<\/strong> file.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Final thoughts<\/h2>\n\n\n\n<p>The functioning of name services seemed very obscure to me until I actually created a name server for my network using BIND. It is quite straightforward and can improve DNS lookup performance. Having your own name server can also prevent many of the relatively minor yet annoying name service interruptions caused by poorly maintained ISP name servers.<\/p>\n\n\n\n<p>Note that, even though my little EeePC is running with 100% CPU usage for Seti@Home, it responds extremely quickly to resolver requests. You should be able to try this project on any Linux host you have available with minuscule impact. I hope that many of you will try to set up your own name server and experiment with it. The specifics of your name server installation will depend upon the details of your host and network.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wikipedia, <a href=\"https:\/\/en.wikipedia.org\/wiki\/BIND\" target=\"_blank\" rel=\"noreferrer noopener\">BIND<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.iana.org\/\">IANA (Internet Assigned Numbers Authority)<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.zytrax.com\/books\/dns\/ch8\/soa.html\">SOA (Start of Authority) record<\/a><\/li>\n\n\n\n<li>Wikipedia, <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_DNS_record_types\">List of DNS Record Types<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/blog.dnsimple.com\/2015\/04\/common-dns-records\/\">Common DNS records and their uses<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<ol class=\"wp-block-footnotes\"><li id=\"e8d429dc-ff79-4f0a-96a1-98d52d80a13f\">&#8220;Primary&#8221; and &#8220;Secondary&#8221; are better terms for server relationships than the racist terms previously used. Many organizations are in the process of making that change but it does take time.  <a href=\"#e8d429dc-ff79-4f0a-96a1-98d52d80a13f-link\" aria-label=\"Jump to footnote reference 1\">\u21a9\ufe0e<\/a><\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>Learn how to use BIND to set up your own server for resolving domain names.<\/p>\n","protected":false},"author":2,"featured_media":4921,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":"[{\"content\":\"\\\"Primary\\\" and \\\"Secondary\\\" are better terms for server relationships than the racist terms previously used. Many organizations are in the process of making that change but it does take time. \",\"id\":\"e8d429dc-ff79-4f0a-96a1-98d52d80a13f\"}]"},"categories":[5,274,89],"tags":[368,360,367,361],"class_list":["post-4918","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-networking","category-system-administration","tag-bind","tag-dns","tag-domain-name-services","tag-name-services"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/4918","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4918"}],"version-history":[{"count":43,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/4918\/revisions"}],"predecessor-version":[{"id":5178,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/4918\/revisions\/5178"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/4921"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4918"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4918"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4918"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}