Difference between revisions of "Configuring basic DNS service with bind"

From Notes_Wiki
(Created page with "=Configuring basic DNS service with bind= In order to configure basic DNS service with bind we can first look for sample named.conf that came with our bind distribution. We c...")
 
m
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Configuring basic DNS service with bind=
[[Main Page|Home]] > [[CentOS]] > [[CentOS 6.x]] > [[Bind DNS server configuration]] > [[Configuring basic DNS service with bind]]


In order to configure basic DNS service with bind we can first look for sample named.conf that came with our bind distribution. We can use '<tt>updatedb</tt>' and then '<tt>locate</tt>' to find files which are required to setup bind. Most of the files are located somewhere within '<tt>/usr/share/doc/bind-&lt;version&gt;</tt>'. There is also Bind Administrators Reference Manual (BARM) inside that directory which has complete reference to all the options supported by bind and is very extensive compared to man pages.
=Basic Bind configuration=
# <tt>yum -y install bind bind-utils</tt>
# <tt>yum remove bind-chroot</tt>
# Edit /etc/named.conf and append following lines: <source type="shell">
    zone "rekallsoftware.com." IN {
        type master;
        file "rekallsoftware.com.forward";
    };
</source>
# In '<tt>/etc/named.conf</tt>' make following modifications:
## <tt>listen-on port 53 {127.0.0.1; any;}; </tt>
## <tt>allow-query {localhost; 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;}; </tt>
## <tt>dnssec-enable no; </tt>
## <tt>dnssec-validation no; </tt>
# Go to /var/named and create rekallsoftware.com.forward with contents similar to: <source type="shell">
    $TTL 3600
    @ SOA ns.rekallsoftware.com. root.rekallsoftware.com. (1 15m 5m 30d 1h)
        NS ns.rekallsoftware.com.
        A 10.1.2.3
    ns              IN      A      10.1.1.1
    www            IN      A      10.1.2.3
</source>
# Start or restart DNS with "<tt>service named restart</tt>" command.
# Try "<tt>nslookup rekallsoftware.com 127.0.0.1</tt>"
# Try "<tt>nslookup www.google.co.in 127.0.0.1</tt>".  This will only work if machine has direct access to Internet at least for outgoing UDP port 53.




=Setup bind on CentOS 7=
For CentOS 7 following small differences are important:
#For starting bind after configuring as suggested above use:
#:<pre>
#:: systemctl enable bind
#:: systemctl start bind
#:</pre>
#For allowing port 53 in firewall use:
#:<pre>
#::firewall-cmd --permanent --add-port=53/tcp
#::firewall-cmd --permanent --add-port=53/udp
#::firewall-cmd --reload
#::firewall-cmd --list-all
#:</pre>
#::Add '<tt>--zone=internal</tt>' if zones are being used


==Configuring basic named.conf==


First we can search for sample 'named.conf' and copy it to '<tt>/var/named/chroot/etc</tt>'. Normally bind runs in chroot environment inside '<tt>/var/named/chroot</tt>' directory. Hence files need to be inside this chroot directory. To avoid confusion or multiple copies or wrong editing whenever we copy file to '<tt>/var/named/chroot/var/named</tt>', we also create symbolic from it to '<tt>/etc</tt>'. Hence even if someone tries to edit '<tt>/etc/named.conf</tt>' proper file '<tt>/var/named/chroot/etc/named.conf</tt>' gets edited.  
Refer http://www.unixmen.com/setting-dns-server-centos-7/ for information including SELinux commands to setup bind with SELinux enabled.


''Note that one has to keep the original file in '<tt>/var/named/chroot/etc</tt>' and create symbolic link with absolute path in '<tt>/etc</tt>'. That is command should be something like '<tt>ln -s /var/named/chroot/etc/named.conf /etc</tt>'. This is because after chroot only outside symbolic links can refer to files inside '<tt>/var/named/chroot</tt>'.''


Sample named.conf file is at [[media:2010-03-14-named.conf.txt|2010-03-14-named.conf.txt]]. This file is properly documented with two zones 'sbarjatiya.in' and 'leet.co.in'. The logs of most categories are sent to different channels and basic views are used to distinguish between 'localhost' and others. The parameters like files, max-cache-size, etc. which protect server resources are defined. The server is configured not to send OS or bind version information. The configuration works well with SELinux enabled as all logs files are written in data directory.
=Automated bind configuration=
For automated bind configuration using ansible playbooks use:
<pre>
---
  - name: Configure DNS using bind
    hosts: dns_servers
    remote_user: root
    vars:
      zone_names:
        - rekallsoftware.com.
      zone_address: 1.1.1.1
      allow_query_from: "10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;"
      name_server: private-dns
      recursion: yes
      servers:
        - { hostname: base1, ip: 10.3.1.23 }
        - { hostname: ansible, ip: 192.168.122.101 }
        - { hostname: private-dns, ip: 192.168.122.102 }
        - { hostname: ldap, ip: 192.168.122.103 }
        - { hostname: git, ip: 192.168.122.104 }
        - { hostname: wiki, ip: 192.168.122.105 }
        - { hostname: redmine, ip: 192.168.122.106 }
 
    tasks:
    - name: Install bind and bind-utils package
      yum: name="{{item}}" state=present
      with_items:
        - bind
        - bind-utils
 
    - name: Create custom named.conf with desired zone
      template: src=named.conf dest=/etc/named.conf owner=root group=named mode=640
      notify:
        - restart bind
 
    - name: Copy zone forward files for all zones to /var/named
      template: src="zone.forward" dest="/var/named/{{item}}forward" owner=root group=named mode=640
      with_items: zone_names
      notify:
        - restart bind
 
    - name: Disable IPv6 support
      lineinfile: dest=/etc/sysconfig/named line='OPTIONS="-4"' regexp="^OPTIONS"
      notify:
        - restart bind
 
    - name: Start and enable bind service
      service: name=named state=started enabled=yes
 
    - name: Configure strong firewall on bind/named server
      template: src=named_iptables dest=/etc/sysconfig/iptables
      notify:
        - restart iptables
 
    handlers:
    - name: restart bind
      service: name=named state=restarted
 
    - name: restart iptables
      service: name=iptables state=restarted
</pre>
 
The playbook requires a named.conf template with following contents:
<pre>
options {
listen-on port 53 { 127.0.0.1; any; };
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-query    { localhost; {{allow_query_from}} };
recursion {{recursion}};


One can start with above configuration file along with these two zone files ([[media:2010-03-14-sbarjatiya.in.zone.txt|2010-03-14-sbarjatiya.in.zone.txt]] and [[media:2010-03-14-leet.co.in.zone.txt|2010-03-14-leet.co.in.zone.txt]])  and test the basic setup. If things are fine then proper zones instead of these two zones can be defined. One should also refer to documentation of current version of bind installed located at '<tt>/usr/share/doc/bind-&lt;version&gt;</tt>' to know about extra/deprecated features in this version.
dnssec-enable no;
dnssec-validation no;
dnssec-lookaside auto;


Similar to files in '<tt>/var/named/chroot/etc</tt>', for files in '<tt>/var/named/chroot/var/named</tt>' we create a symbolic link in '<tt>/var/named</tt>' so that if someone accidentally tries to modify files in '<tt>/var/named</tt>' then also the correct version gets modified.
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";


managed-keys-directory "/var/named/dynamic";
};


logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};


==Troubleshooting bind==
{% for item in zone_names  %}


===File/zone not found errors===
zone "{{item}}" IN {
  type master;
  file "{{item}}forward";
};


When one uses above given sample '<tt>named.conf</tt>' file then it is possible to get errors like '<tt>file named.root.hints not found</tt>' or '<tt>file named.rfc1912.zones</tt>' not found. For all such common files use locate and copy the sample files that come with bind. There can be six or seven such files so keep reading error messages that you get when you try to start bind and then copy the files appropriately. Make sure that you also create symbolic link whenever you copy new file.
{% endfor %}


If '<tt>directory</tt>' options has been used then named may search for zones files in that directory. Hence we should copy the zone files like '<tt>localhost.zone</tt>', '<tt>localdomain.zone</tt>' and even the zone files that we create appropriately.


zone "." IN {
type hint;
file "named.ca";
};


include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";


===No error is printed===
</pre>
Some times bind will fail to start and no error gets printed then try
 
The playbook requires zone.forward file present in the same folder.  The file should have following contents:
<pre>
<pre>
echo '' >> /var/log/messages
$TTL 3600
echo '' >> /var/log/messages
@ SOA ns.{{item}} root.{{item}} (1 15m 5m 30d 1h)
service bind start
IN NS {{name_server}}
tail -30 /var/log/messages
IN A {{zone_address}}
 
{% for server1 in servers %}
 
{{server1.hostname}} IN A {{server1.ip}}
 
{% endfor %}
</pre>
</pre>
and look for bind error messages. There can still be some files like '<tt>/etc/named.root</tt>' which are not found. Copy those files to '<tt>/var/named/chroot/etc</tt>' and create symbolic link in '<tt>/etc</tt>'.


Finally a named_iptables file with following contents should also be present:
<pre>
*filter
:INPUT ACCEPT [-1:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
#Accept loopback connections
-A INPUT -i lo -d 127.0.0.0/8 -j ACCEPT
#Rate limit new connections to 20 new connections per 30 seconds
-A INPUT ! -p udp -m state --state NEW -m recent --name new_limit --set
-A INPUT ! -p udp -m state --state NEW -m recent --name new_limit --rcheck --seconds 30 --hitcount 20 -m limit --limit 2/min -j LOG --log-prefix "new_limit_"
-A INPUT ! -p udp -m state --state NEW -m recent --name ssh_limit --rcheck --seconds 30 --hitcount 20 -j DROP
#Accept ICMP ping requests at limited rate
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 60/minute --limit-burst 120 -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/minute --limit-burst 2 -j LOG
-A INPUT -p icmp --icmp-type echo-request -j DROP
#Allow ongoing connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Allow incoming SSH connections
-A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
#Allow access to DNS from everywhere.  The allow_query option in DNS will take care of limiting clients.
-A INPUT -m state --state NEW -p udp -m udp --dport 53 -j ACCEPT
#Log all other "blocked_input_" attempts with rate limiting
-A INPUT -m state --state NEW -m limit --limit 2/min -j LOG --log-prefix "blocked_input_"
#Reply with proper ICMP error message and reject the connection
-A INPUT -j REJECT --reject-with icmp-host-prohibited
#Disable packet forwarding through firewall
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
#
#
##Output rules
#Allow outgoing connections to localhost
-A OUTPUT -s 127.0.0.0/8 -o lo -j ACCEPT
#Allow ongoing connections
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#Allow DNS queries
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
#Allow server to send emails.  Required for sending logwatch emails
-A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
#Allow server to contact web-servers.  Required for yum update and installation
#For restrictive configurations this can be disabled after install
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
#Allow outgoing ping requests
-A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
#Log all other "blocked_output_" attempts
-A OUTPUT -m state --state NEW -m limit --limit 2/min -j LOG --log-prefix "blocked_output_"
#Reply with proper ICMP error message and reject the connection
-A OUTPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
#
</pre>


===Error not clear Or not printed in /var/log/messages===


If error is not printed in /var/log/messages then try running bind in foreground with
=Ansible named-server role for both public and private DNS=
<tt>
For automated bind configuration for multiple DNS using same role refer to [[Ansible named-server role for both public and private DNS]]
named -u named -f -d <debug_level>
</tt>
There is also provision to specify chroot directory. Read 'man named' to know about more options.




===Disable SELinux===


If still bind is not running then disable SELinux to confirm that problem is not due to SELinux. If bind works after doing '<tt>setenfore 0</tt>' then try to use '<tt>restorecon -vR /var/named</tt>' and then again try to start bind. Have a look at different SELinux types in '<tt>/var/named</tt>' and try to set similar contexts in '<tt>/var/named/chroot/var/named<tt>'.
[[Main Page|Home]] > [[CentOS]] > [[CentOS 6.x]] > [[Bind DNS server configuration]] > [[Configuring basic DNS service with bind]]

Latest revision as of 08:40, 17 February 2023

Home > CentOS > CentOS 6.x > Bind DNS server configuration > Configuring basic DNS service with bind

Basic Bind configuration

  1. yum -y install bind bind-utils
  2. yum remove bind-chroot
  3. Edit /etc/named.conf and append following lines:
         zone "rekallsoftware.com." IN {
            type master;
            file "rekallsoftware.com.forward";
         };
  4. In '/etc/named.conf' make following modifications:
    1. listen-on port 53 {127.0.0.1; any;};
    2. allow-query {localhost; 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;};
    3. dnssec-enable no;
    4. dnssec-validation no;
  5. Go to /var/named and create rekallsoftware.com.forward with contents similar to:
         $TTL 3600
         @ SOA ns.rekallsoftware.com. root.rekallsoftware.com. (1 15m 5m 30d 1h)
            NS ns.rekallsoftware.com.
            A 10.1.2.3
         ns              IN      A       10.1.1.1
         www             IN      A       10.1.2.3
  6. Start or restart DNS with "service named restart" command.
  7. Try "nslookup rekallsoftware.com 127.0.0.1"
  8. Try "nslookup www.google.co.in 127.0.0.1". This will only work if machine has direct access to Internet at least for outgoing UDP port 53.


Setup bind on CentOS 7

For CentOS 7 following small differences are important:

  1. For starting bind after configuring as suggested above use:
    systemctl enable bind
    systemctl start bind
  2. For allowing port 53 in firewall use:
    firewall-cmd --permanent --add-port=53/tcp
    firewall-cmd --permanent --add-port=53/udp
    firewall-cmd --reload
    firewall-cmd --list-all
    Add '--zone=internal' if zones are being used


Refer http://www.unixmen.com/setting-dns-server-centos-7/ for information including SELinux commands to setup bind with SELinux enabled.


Automated bind configuration

For automated bind configuration using ansible playbooks use:

---
  - name: Configure DNS using bind
    hosts: dns_servers
    remote_user: root
 
    vars:
      zone_names: 
        - rekallsoftware.com.
      zone_address: 1.1.1.1
      allow_query_from: "10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;"
      name_server: private-dns
      recursion: yes
      servers:
        - { hostname: base1, ip: 10.3.1.23 }
        - { hostname: ansible, ip: 192.168.122.101 }
        - { hostname: private-dns, ip: 192.168.122.102 }
        - { hostname: ldap, ip: 192.168.122.103 }
        - { hostname: git, ip: 192.168.122.104 }
        - { hostname: wiki, ip: 192.168.122.105 }
        - { hostname: redmine, ip: 192.168.122.106 }

    tasks:
    - name: Install bind and bind-utils package
      yum: name="{{item}}" state=present
      with_items:
        - bind
        - bind-utils

    - name: Create custom named.conf with desired zone
      template: src=named.conf dest=/etc/named.conf owner=root group=named mode=640
      notify:
        - restart bind

    - name: Copy zone forward files for all zones to /var/named
      template: src="zone.forward" dest="/var/named/{{item}}forward" owner=root group=named mode=640
      with_items: zone_names
      notify:
        - restart bind

    - name: Disable IPv6 support
      lineinfile: dest=/etc/sysconfig/named line='OPTIONS="-4"' regexp="^OPTIONS" 
      notify:
        - restart bind

    - name: Start and enable bind service
      service: name=named state=started enabled=yes

    - name: Configure strong firewall on bind/named server
      template: src=named_iptables dest=/etc/sysconfig/iptables 
      notify:
        - restart iptables

    handlers:
    - name: restart bind
      service: name=named state=restarted

    - name: restart iptables
      service: name=iptables state=restarted
 

The playbook requires a named.conf template with following contents:

options {
	listen-on port 53 { 127.0.0.1; any; };
	listen-on-v6 port 53 { ::1; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
	allow-query     { localhost; {{allow_query_from}} };
	recursion {{recursion}};

	dnssec-enable no;
	dnssec-validation no;
	dnssec-lookaside auto;

	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.iscdlv.key";

	managed-keys-directory "/var/named/dynamic";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

{% for item in zone_names  %}

zone "{{item}}" IN {
   type master;
   file "{{item}}forward";
};

{% endfor %}


zone "." IN {
	type hint;
	file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

The playbook requires zone.forward file present in the same folder. The file should have following contents:

$TTL 3600 
@ SOA ns.{{item}} root.{{item}} (1 15m 5m 30d 1h) 
		IN	NS	{{name_server}}
		IN	A 	{{zone_address}}

{% for server1 in servers %}

{{server1.hostname}}	IN	A	{{server1.ip}}

{% endfor %}

Finally a named_iptables file with following contents should also be present:

*filter
:INPUT ACCEPT [-1:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
#Accept loopback connections
-A INPUT -i lo -d 127.0.0.0/8 -j ACCEPT
#Rate limit new connections to 20 new connections per 30 seconds
-A INPUT ! -p udp -m state --state NEW -m recent --name new_limit --set
-A INPUT ! -p udp -m state --state NEW -m recent --name new_limit --rcheck --seconds 30 --hitcount 20 -m limit --limit 2/min -j LOG --log-prefix "new_limit_"
-A INPUT ! -p udp -m state --state NEW -m recent --name ssh_limit --rcheck --seconds 30 --hitcount 20 -j DROP
#Accept ICMP ping requests at limited rate
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 60/minute --limit-burst 120 -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/minute --limit-burst 2 -j LOG
-A INPUT -p icmp --icmp-type echo-request -j DROP
#Allow ongoing connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Allow incoming SSH connections
-A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
#Allow access to DNS from everywhere.  The allow_query option in DNS will take care of limiting clients. 
-A INPUT -m state --state NEW -p udp -m udp --dport 53 -j ACCEPT
#Log all other "blocked_input_" attempts with rate limiting
-A INPUT -m state --state NEW -m limit --limit 2/min -j LOG --log-prefix "blocked_input_"
#Reply with proper ICMP error message and reject the connection
-A INPUT -j REJECT --reject-with icmp-host-prohibited
#Disable packet forwarding through firewall
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
#
#
##Output rules
#Allow outgoing connections to localhost
-A OUTPUT -s 127.0.0.0/8 -o lo -j ACCEPT
#Allow ongoing connections
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#Allow DNS queries
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
#Allow server to send emails.  Required for sending logwatch emails
-A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
#Allow server to contact web-servers.  Required for yum update and installation
#For restrictive configurations this can be disabled after install
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
#Allow outgoing ping requests
-A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
#Log all other "blocked_output_" attempts
-A OUTPUT -m state --state NEW -m limit --limit 2/min -j LOG --log-prefix "blocked_output_"
#Reply with proper ICMP error message and reject the connection
-A OUTPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
#


Ansible named-server role for both public and private DNS

For automated bind configuration for multiple DNS using same role refer to Ansible named-server role for both public and private DNS


Home > CentOS > CentOS 6.x > Bind DNS server configuration > Configuring basic DNS service with bind