Split Horizon is normally used to describe a DNS server that will give different responses based on the source address (IP address) of the query. It is typically used in the follow situations:
- Geographic Mapping: Assume that, for example, a web service is replicated in a number of locations (for either performance or access latency reasons) then a specific IP address may be returned based on the source address of the query to ensure the shortest possible path from the user to the service. For those familiar with anycast you could consider this as a poor man's anycast service.
- Naming Consistency: Assume that you have, say, a corporate in-house LDAP service and that you want to keep certain highly secure data on one server only accessible to certain individuals or organizational sections, which have unique or identifiable IP addresses or address ranges, but for reasons of consistency (scripts, configuration files etc) you want both the secure and insecure LDAP services to be named, say, ldap.example.com.
- Load Balancing: Assume that an analysis of incoming service users shows that their source-ip addresses can be separated into contiguous ranges: 50% from a to b, 50% from b to c. In this case rather than simply provide multiple A/AAAA RRs (where load balancing is essentially random) it may be more effective to use a split-horizon strategy.
This Tutorial shows you how to configure a DNS split-Horizon. The problem we try to solve in this tutorial is: to have a DNS server for internal network and have a DNS server for external servers. That way when you are inside you can resolve to internal IPs and when you are outside you can resolve to external IPs. Efficiency and security purposes.
Assumptions:
DNS server: master.test.com (10.168.1.0)
client1: internal1.test.com (10.168.1.1, 114.168.1.1) internal zone
client2: internal2.test.com (10.168.1.2, 114.168.1.2) internal zone
client3: external.test.com (10.168.1.3, 114.168.1.3) external zone
Configure a Linux server A to be a split horizon DNS server means: If client1 pings client2 from LAN, it should see the internal IP address:
client1 -> $ ping client2.test.com PING client2 (10.168.1.3) 56(84) bytes of data.
But if client1 pings client3 , it will see the external IP:
client1 -> $ ping client3.test.com PING client3 (114.168.1.3) 56(84) bytes of data.
Configuration:
OS: Centos 6.x
BIND9
Install bind service on master.test.com
# yum install bindAfter installation, you should have a /etc/named.conf /etc/named/ directory. The named.conf prints named to source DNS information. Some of these sources are local files and others are remote servers. The structure of the configuration commands in named.conf is similar to C programming language. Below is a list of basic named.conf configration statements:
acl - Defines an access control list of IPs
include - Includes another file into the configuration file
key - Defines security keys for authentication
logging - Defines what will be logged and where it will be stored
options - Defines global configuration opetions and defaults
server - Defines a remote server's characteristics
zone - Defines a zone
Edit named.conf file:
1. Define internals and externals
acl internals { 127.0.0.0/8; 10.168.1.0/24; };
Notice we don need to define externals here because everything that is not internal is external.
2. Create "view", "view" will let us put a piece of configuration inside a conditional that can depend on a number of things, in this case we'll just depend on internals. We replace the zone declaration at /etc/named.conf with:
view "internal" { match-clients { internals; }; zone "test.com" { type master; file "/etc/bind/internals/db.test.com"; }; }; view "external" { match-clients { any; }; recursion no; forwarders { IP-Adderss-of-nameserver1; IP-Adderss-of-nameserver2; }; };
IP-Address-of-nameserver1 and IP-Address-of-nameserver2 are the IP address of your ISP's nameserver IP, or your company's dedicated nameservers.
Notice that we disabled recursion on our DNS server. By default, DNS server recursive queries on behalf of its DNS client and DNS servers that have forwarded DNS client queries to it. Recursion is a name-resolution technique in which a DNS server queries other DNS servers on behalf of the requesting client to fully resolve the name and then sends an answer back to the client. Attackers can use recursion to deny the DNS server service (DNS amplification attacks), we are not intended to receive recursive queries, so we disable it.
2. Create the db.test.com file with the following contents:
$TTL 604800 @ IN SOA master.test.com. root.test.com. ( 2006020201 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800); Negative Cache TTL ; @ IN NS master client1 IN A 10.168.1.1 client2 IN A 10.168.1.2 client3 IN A 114.168.1.33. Start the DNS server:
# service named start
4. On all your client machines, update the /etc/resolv.conf file to use the new DNS server:
; generated by /sbin/dhclient-script ;search privatedns.com ;nameserver IP-Adderss-of-nameserver1 ;nameserver IP-Adderss-of-nameserver2 nameserver 10.168.1.05. Now ping client2.test.com will give you the internal IP address and ping client3.test.com will give you external IP.
6. To configure reverse DNS look up (translate IP address into hostname) you need to create another zone file called 1.168.10.in-addr.arpa file.
The contents of arpa file are:
$TTL 604800 @ IN SOA master.test.com. root.test.com. ( 2006020201 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800); Negative Cache TTL ; 1.168.10.in-addr.arpa. IN NS master.test.com. 1 IN PTR client1.test.com. 2 IN PTR client2.test.com.7. Update the named.conf file:
view "internal" { match-clients { internals; }; zone "test.com" { type master; file "/etc/bind/internals/db.test.com"; }; zone "1.168.10.in-addr.arpa" IN { type master; file "/etc/named/internals/1.168.10.in-addr.arpa"; }; }; view "external" { match-clients { any; }; recursion no; forwarders { IP-Adderss-of-nameserver1; IP-Adderss-of-nameserver2; }; };
8. Restart named process
# service named restart
9. Now you can do reverse DNS lookups:
$ nslookup 10.168.1.1 Server: 10.168.1.0 Address: 10.168.1.1#53 1.1.168.10.in-addr.arpa name = client1.test.com
Some other resources:
http://www.debian-administration.org/articles/355
TTL - Time-to-live defines the length of time, in seconds, that the information in this resource record should be kept in a remote system's cache. Usually this field is left blank and the default ttl, set for the entire zone by the $TTL directive is used.
IN - Identities the record as an Internet DNS resource record. There are other classes of records, but they are rarely used.
Type - Identifies the kind of resource record.
Serial number - The revision number of this zone file. Increment this number each time the zone file is changed. It is important to increment this value each time a change is made, so that the changes will be distributed to any secondary DNS servers.
Refresh Time - The time, in seconds, a secondary DNS server waits before querying the primary DNS server's SOA record to check for changes. When the refresh time expires, the secondary DNS server requests a copy of the current SOA record from the primary. The primary DNS server complies with this request. The secondary DNS server compares the serial number of the primary DNS server's current SOA record and the serial number in it's own SOA record. If they are different, the secondary DNS server will request a zone transfer from the primary DNS server. The default value is 3,600.
Retry time - The time, in seconds, a secondary server waits before retrying a failed zone transfer. Normally, the retry time is less than the refresh time. The default value is 600.
Expire time - The time, in seconds, that a secondary server will keep trying to complete a zone transfer. If this time expires prior to a successful zone transfer, the secondary server will expire its zone file. This means the secondary will stop answering queries, as it considers its data too old to be reliable. The default value is 86,400.
Minimum TTL - The minimum time-to-live value applies to all resource records in the zone file. This value is supplied in query responses to inform other servers how long they should keep the data in cache. The default value is 3,600.
No comments:
Post a Comment