Configuring basic DNS service with bind
<yambe:breadcrumb self="Basic bind configuration">Bind DNS server configuration | Bind DNS</yambe:breadcrumb>
Configuring basic DNS service with bind
- yum -y install bind bind-utils
- Edit /etc/named.conf and append following lines:
- zone "rekallsoftware.com." IN {
- type master;
- file "rekallsoftware.com.forward";
- };
 
 
- In '/etc/named.conf' make following modifications:
- listen-on port 53 {127.0.0.1; any;};
- allow-query {localhost; 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;};
- dnssec-enable no;
- dnssec-validation no;
 
- 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
 
 
- Start or restart DNS with "service named restart" command.
- Try "nslookup rekallsoftware.com 127.0.0.1"
- 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:
- For starting bind after configuring as suggested above use:
- systemctl enable bind
- systemctl start bind
 
 
- For allowing port 53 in firewall use:
- firewall-cmd --permanent --add-port=53/tcp
- firewall-cmd --permanent --add-port=53/udp
- firewall-cmd --reload
 
 
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
<yambe:breadcrumb self="Basic bind configuration">Bind DNS server configuration | Bind DNS</yambe:breadcrumb>

