In July 1997, during two periods of several days, users around the Internet who typed www.internic.net into their web browsers thinking they were going to the InterNICs web site instead ended up at a web site belonging to the AlterNIC. (The AlterNIC runs an alternate set of root name servers that delegate to additional top-level domains with names like med and porn.) Howd it happen? Eugene Kashpureff, then affiliated with the AlterNIC, had run a program to poison the caches of major name servers around the world, making them believe that www.internic.net's address was actually the address of the AlterNIC web server. Kashpureff hadnt made any attempt to disguise what he had done; the web site that users reached was plainly the AlterNICs, not the InterNICs. But imagine someone poisoning your name servers cache to direct www.amazon.com or www.wellsfargo.com to his own web server, conveniently well outside local law enforcement jurisdiction. Further, imagine your users typing in their credit card numbers and expiration dates. Now you get the idea. Protecting your users against these kinds of attacks requires DNS security. DNS security comes in several flavors. You can secure transactionsthe queries, responses, and other messages your name server sends and receives. You can secure your name server, refusing queries, zone transfer requests, and dynamic updates from unauthorized addresses, for example. You can even secure zone data by digitally signing it. Since DNS security is one of the most complicated topics in DNS, well start you off easy and build up to the hard stuff.
TSIG
BIND 8.2 introduced a new mechanism for securing DNS messages called transaction signatures, or TSIG for short. TSIG uses shared secrets and a one-way hash function to authenticate DNS messages, particularly responses and updates. TSIG, now codified in RFC 2845, is relatively simple to configure, lightweight for resolvers and name servers to use, and flexible enough to secure DNS messages (including zone transfers) and dynamic updates. With TSIG configured, a name server or updater adds a TSIG record to the additional data section of a DNS message. The TSIG record signs the DNS message, proving that the messages sender had a cryptographic key shared with the receiver and that the message wasnt modified after it left the sender. One-Way Hash Functions TSIG provides authentication and data integrity through the use of a special type of mathematical formula called a one-way hash function. A one-way hash function, also known as a cryptographic checksum or message digest, computes a fixed-size hash value based on arbitrarily large input. The magic of a one-way hash function is that each bit of the hash value depends on each and every bit of the input. Change a single bit of the input and the hash value changes dramatically and unpredictablyso unpredictably that its computationally infeasible to reverse the function and find an input that produces a given hash value. TSIG uses a one-way hash function called MD5. In particular, it uses a variant of MD5 called HMAC-MD5. HMAC-MD5 works in a keyed mode in which the 128-bit hash value depends not only on the input, but also on a key. The TSIG Record We wont cover the TSIG records syntax in detail because you dont need to know it: TSIG is a meta-record that never appears in zone data and is never cached by a resolver or name server. A signer adds the TSIG record to a DNS message, and the recipient removes and verifies the record before doing anything further, such as caching the data in the message. You should know, however, that the TSIG record includes a hash value computed over the entire DNS message as well as some additional fields. (When we say computed over, we mean that the raw, binary DNS message and the additional fields are fed through the HMAC-MD5 algorithm to produce the hash value.) The hash value is keyed with a secret shared between the signer and the verifier. Verifying the hash value proves both that the DNS message was signed by a holder of the shared secret and that it wasnt modified after it was signed. The additional fields in the TSIG record include the time the DNS message was signed. This helps combat replay attacks, in which a hacker captures a signed, authorized transaction (say a dynamic update deleting an important resource record) and replays it later. The recipient of a signed DNS message checks the time signed to make sure its within the allowable fudge (another field in the TSIG record). Configuring TSIG Before using TSIG for authentication, we need to configure one or more TSIG keys on either end of the transaction. For example, if we want to use TSIG to secure zone transfers between the master and slave name servers for movie.edu, we need to configure both name servers with a common key: key terminator-wormhole.movie.edu. { algorithm hmac-md5; secret skrKc4Twy/cIgIykQu7JZA==; }; The argument to the key statement in this example, terminator-wormhole.movie.edu., is actually the name of the key, though it looks like a domain name. (Its encoded in the DNS message in the same format as a domain name.) The TSIG RFC suggests you name the key after the two hosts that use it. The RFC also suggests that you use different keys for each pair of hosts. Its important that the name of the keynot just the binary data the key points tobe identical on both ends of the transaction. If its not, the recipient tries to verify the TSIG record and finds it doesnt know the key that the TSIG record says was used to compute the hash value. That causes errors like the following: Nov 21 19:43:00 wormhole named-xfer[30326]: SOA TSIG verification from server [192.249.249.1], zone movie.edu: message had BADKEY set (17) The algorithm, for now, is always hmac-md5. The secret is the base 64 encoding of the binary key. You can create a base 64-encoded key using the dnssec-keygen program included in BIND 9 or the dnskeygen program included in BIND 8. Heres how youd create a key using dnssec-keygen, the easier of the two to use: # dnssec-keygen -a HMAC-MD5 -b 128 -n HOST terminator-wormhole.movie.edu. Kterminator-wormhole.movie.edu.+157+28446 The -a option takes as an argument the name of the algorithm the key will be used with. (Thats necessary because dnssec-keygen can generate other kinds of keys, as well see in the DNSSEC section.) -b takes the length of the key as its argument; the RFC recommends using keys 128 bits long. -n takes as an argument HOST, the type of key to generate. (DNSSEC uses ZONE keys.) The final argument is the name of the key. dnssec-keygen and dnskeygen both create files in their working directories that contain the keys generated. dnssec-keygen prints the base name of the files to its standard output. In this case, dnssec-keygen created the files Kterminator-wormhole.movie.edu.+157+28446.key and Kterminator-wormhole.movie.edu.+157+28446.private. You can extract the key from either file. The funny numbers (157 and 28446), in case youre wondering, are the keys DNSSEC algorithm number (157 is HMAC-MD5) and the keys fingerprint (28446), a hash value computed over the key to identify it. The fingerprint isnt particularly useful in TSIG, but DNSSEC supports multiple keys per zone, so identifying which key you mean by its fingerprint is important. Kterminator-wormhole.movie.edu.+157+28446.key contains: terminator-wormhole.movie.edu. IN KEY 512 3 157 skrKc4Twy/cIgIykQu7JZA== and Kterminator-wormhole.movie.edu.+157+28446.private contains: Private-key-format: v1.2 Algorithm: 157 (HMAC_MD5) Key: skrKc4Twy/cIgIykQu7JZA== You can also choose your own key and encode it in base 64 using mmencode : % mmencode foobarbaz Zm9vYmFyYmF6 Since the actual binary key is, as the substatement implies, a secret, we should take care in transferring it to our name servers (e.g., by using ssh) and make sure that not just anyone can read it. We can do that by making sure our named.conf file isnt world-readable or by using the include statement to read the key statement from another file, which isnt world-readable: include /etc/dns.keys.conf; Theres one last problem that we see cropping up frequently with TSIG: time synchronization. The timestamp in the TSIG record is useful for preventing replay attacks, but it tripped us up initially because the clocks on our name servers werent synchronized. That produced error messages like the following: Nov 21 19:56:36 wormhole named-xfer[30420]: SOA TSIG verification from server [192.249.249.1], zone movie.edu: BADTIME (-18) We quickly remedied the problem using NTP, the network time protocol. Using TSIG Now that weve gone to the trouble of configuring our name servers with TSIG keys, we should probably configure them to use those keys for something. In BIND 8.2 and later name servers, we can secure queries, responses, zone transfers, and dynamic updates with TSIG. The key to configuring this is the server statements keys substatement, which tells a name server to sign queries and zone transfer requests sent to a particular remote name server. This server substatement, for example, tells the local name server, wormhole.movie.edu, to sign all such requests sent to 192.249.249.1 (terminator.movie.edu) with the key terminator-wormhole.movie.edu: server 192.249.249.1 { keys { terminator-wormhole.movie.edu.; }; }; Now, on terminator.movie.edu, we can restrict zone transfers to those signed with the terminator-wormhole.movie.edu key: zone movie.edu { type master; file db.movie.edu; allow-transfer { key terminator-wormhole.movie.edu.; }; }; terminator.movie.edu also signs the zone transfer, which allows wormhole.movie.edu to verify it. You can also restrict dynamic updates with TSIG by using the allow-update and update-policy substatements, as we showed you in the last chapter. The nsupdate programs shipped with BIND 8.2 and later support sending TSIG-signed dynamic updates. If you have the key files created by dnssec-keygen lying around, you can specify either of those as an argument to nsupdates -k option. Heres how youd do that with BIND 9s version of nsupdate : % nsupdate -k Kterminator-wormhole.movie.edu.+157+28446.key or: % nsupdate -k Kterminator-wormhole.movie.edu.+157+28446.private With the BIND 8.2 or later nsupdate, the syntax is a little different: -k takes a directory and a key name as an argument, separated by a colon: % nsupdate -k /var/named:terminator-wormhole.movie.edu. If you dont have the files around (maybe youre running nsupdate from another host), you can still specify the key name and the secret on the command line with the BIND 9 nsupdate : % nsupdate -y terminator-wormhole.movie.edu.:skrKc4Twy/cIgIykQu7JZA== The name of the key is the first argument to the -y option, followed by a colon and the base 64-encoded secret. You dont need to quote the secret since base 64 values cant contain shell metacharacters, but you can if you like. Michael Fuhrs Net::DNS Perl module also lets you send TSIG-signed dynamic updates and zone transfer requests. For more information on Net::DNS, see Chapter 15, Programming with the Resolver and Name Server Library Routines. Now that weve got a handy mechanism for securing DNS transactions, lets talk about securing our whole name server. Securing Your Name Server BIND 4.9 introduced several important security features that help you protect your name server. BIND 8 and 9 continued the tradition by adding several more. These features are particularly important if your name server is running on the Internet, but theyre also useful on purely internal name servers. Well start by discussing measures you should take on all name servers for which security is important. Then well describe a model in which your name servers are split into two communities, one for serving only resolvers and one for answering other name servers queries. BIND Version One of the most important ways you can enhance the security of your name server is to run a recent version of BIND. All versions of BIND before 8.2.3 are susceptible to at least a few known attacks. Check the ISCs list of vulnerabilities in various BIND versions at http://www.isc.org/products/BIND/bind-security.html for updates. But dont stop there: new attacks are being thought up all the time, so youll have to do your best to keep abreast of BINDs vulnerabilities and the latest safe version of BIND. One good way to do that is to read the comp.protocols.dns.bind newsgroup regularly. Theres another aspect of BINDs version relevant to security: if a hacker can easily find out which version of BIND youre running, he may be able to tailor his attacks to that version of BIND. And, wouldnt you know it, since about BIND 4.9, BIND name servers have replied to a certain query with their version. If you look up TXT records in the CHAOSNET class attached to the domain name version.bind, BIND graciously returns something like this: % dig txt chaos version.bind. ; > DiG 9.1.0 > txt chaos version.bind. ;; global options: printcmd ;; Got answer: ;; ->>HEADERRestricting Queries Before BIND 4.9, administrators had no way to control who could look up names on their name servers. That makes a certain amount of sense; the original idea behind DNS was to make information easily available all over the Internet. The neighborhood is not such a friendly place anymore, though. In particular, people who run Internet firewalls may have a legitimate need to hide certain parts of their namespace from most of the world while making it available to a limited audience. The BIND 8 and 9 allow-query substatement lets you apply an IP address-based access control list to queries. The access control list can apply to queries for data in a particular zone or to any queries received by the name server. In particular, the access control list specifies which IP addresses are allowed to send queries to the server. Restricting all queries The global form of the allow-query substatement looks like this: options { allow-query { address_match_list; }; }; So to restrict our name server to answering queries from the three main Movie U. networks, wed use: options { allow-query { 192.249.249/24; 192.253.253/24; 192.253.254/24; }; }; Restricting queries in a particular zone BIND 8 and 9 also allow you to apply an access control list to a particular zone. In this case, just use allow-query as a substatement to the zone statement for the zone you want to protect: acl HP-NET { 15/8; }; zone hp.com { type slave; file bak.hp.com; masters { 15.255.152.2; }; allow-query { HP-NET; }; }; Any kind of authoritative name server, master or slave, can apply an access control list to the zone. Zone-specific access control lists take precedence over a global ACL for queries in that zone. The zone-specific access control list may even be more permissive than the global ACL. If theres no zone-specific access control list defined, any global ACL will apply. In BIND 4.9, this functionality is provided by the secure_zone record. Not only does it limit queries for individual resource records, it limits zone transfers, too. (In BIND 8 and 9, restricting zone transfers is done separately.) However, BIND 4.9 name servers have no mechanism for restricting who can send your server queries for data in zones your server is not authoritative for; the secure_zone mechanism works only with authoritative zones. To use secure_zone, include one or more special TXT records in your zone data on the primary master name server. Conveniently, these records are transferred to the zones slave servers automatically. Of course, only BIND 4.9 slaves will understand them. The TXT records are special because theyre attached to the pseudo-domain name secure_zone, and the resource record-specific data has a special format, too: address:mask or: address:H In the first form, address is the dotted-octet form of the IP network to which you want to allow access to the data in this zone. The mask is the netmask for that network. If you want to allow all of 15/8 access to your zone data, use 15.0.0.0:255.0.0.0. If you want to allow only the range of IP addresses from 15.254.0.0 to 15.255.255.255 access to your zone data, use 15.254.0.0:255.254.0.0. The second form specifies the address of a particular host youd like to allow access to your zone data. The H is equivalent to the mask 255.255.255.255; in other words, each bit in the 32-bit address is checked. Therefore, 15.255.152.4:H gives the host with the IP address 15.255.152.4 the ability to look up data in the zone. If we want to restrict queries for information in movie.edu to hosts on Movie U.s networks, but our name servers run BIND 4.9 instead of BIND 8 or 9, we could add the following lines to db.movie.edu on the movie.edu primary master: secure_zone IN TXT 192.249.249.0:255.255.255.0 secure_zone IN TXT 192.253.253.0:255.255.255.0 secure_zone IN TXT 192.253.254.0:255.255.255.0 secure_zone IN TXT 127.0.0.1:H Notice that we included the loopback address (127.0.0.1) in our access control list. Thats so a resolver running on the same host as a name server can query the local name server. If you forget the :H, youll see the following syslog message: Aug 17 20:58:22 terminator named[2509]: build_secure_netlist (movie.edu): addr (127.0.0.1) is not in mask (0xff000000) Also, note that the secure_zone records here apply only to the zone theyre inthat is, movie.edu. If you wanted to prevent unauthorized queries for data in other zones on this server, youd have to add secure_zone records to those zones on their primary master name servers, too. Preventing Unauthorized Zone Transfers Arguably even more important than controlling who can query your name server is ensuring that only your real slave name servers can transfer zones from your name server. Users on remote hosts that can query your name servers zone data can only look up records (e.g., addresses) for domain names they already know, one at a time. Users who can start zone transfers from your server can list all of the records in your zones. Its the difference between letting random folks call your companys switchboard and ask for John Q. Cubicles phone number and sending them a copy of your corporate phone directory. BIND 8 and 9s allow-transfer substatement and 4.9s xfrnets directive let administrators apply an access control list to zone transfers. allow-transfer restricts transfers of a particular zone when used as a zone substatement, and restricts all zone transfers when used as an options substatement. It takes an address match list as an argument. The slave servers for our movie.edu zone have the IP addresses 192.249.249.1 and 192.253.253.1 (wormhole.movie.edu) and 192.249.249.9 and 192.253.253.9 (zardoz.movie.edu). The following zone statement: zone movie.edu { type master; file db.movie.edu; allow-transfer { 192.249.249.1; 192.253.253.1; 192.249.249.9; 192.253.253.9; }; }; allows only those slaves to transfer movie.edu from the primary master name server. Note that because the default for BIND 8 or 9 is to allow zone transfer requests from any IP address, and because hackers can just as easily transfer the zone from your slaves, you should probably also have a zone statement like this on your slaves: zone movie.edu { type slave; masters { 192.249.249.3; }; file bak.movie.edu; allow-transfer { none; }; }; BIND 8 and 9 also let you apply a global access control list to zone transfers. This applies to any zones that dont have their own explicit access control lists defined as zone substatements. For example, we might want to limit all zone transfers to our internal IP addresses: options { allow-transfer { 192.249.249/24; 192.253.253/24; 192.253.254/24; }; }; The BIND 4.9 xfrnets directive also applies an access control list to all zone transfers. xfrnets takes as its arguments the networks or IP addresses youd like to allow to transfer zones from your name server. Networks are specified by the dotted-octet form of the network number. For example: xfrnets 15.0.0.0 128.32.0.0 allows only hosts on the network 15/8 or the network 128.32/16 to transfer zones from this name server. Unlike the secure_zone TXT record, this restriction applies to any zones the server is authoritative for. If you want to specify just a part of a network, down to a single IP address, you can add a network mask. network&netmask is the syntax for including a network mask. Note that spaces arent allowed between the network and the ampersand or between the ampersand and the netmask. To pare down the addresses allowed to transfer zones in the previous example to just the IP address 15.255.152.4 and the subnet 128.32.1/24, use the xfrnets directive: xfrnets 15.255.152.4&255.255.255.255 128.32.1.0&255.255.255.0 Finally, as we mentioned earlier in the chapter, those newfangled BIND 8.2 and later name servers let you restrict zone transfers to slave name servers that include a correct transaction signature with their request. On the master name server, you need to define the key in a key statement and then specify the key in the address match list: key terminator-wormhole. { algorithm hmac-md5; secret UNd5xYLjz0FPkoqWRymtgI+paxW927LU/gTrDyulJRI=; };
zone movie.edu { type master; file db.movie.edu; allow-transfer { key terminator-wormhole.; }; }; On the slaves end, you need to configure the slave to sign zone transfer requests with the same key: key terminator-wormhole. { algorithm hmac-md5; secret UNd5xYLjz0FPkoqWRymtgI+paxW927LU/gTrDyulJRI=; };
server 192.249.249.3 { keys { terminator-wormhole.; }; // sign all requests to 192.249.249.3 // with this key };
zone movie.edu { type slave; masters { 192.249.249.3; }; file bak.movie.edu; }; For a primary master name server accessible from the Internet, you probably want to limit zone transfers to just your slave name servers. You probably dont need to worry about name servers inside your firewall, unless youre worried about your own employees listing your zone data. Running BIND with Least Privilege Running a network server such as BIND as the root user can be dangerousand BIND normally runs as root. If a hacker finds a vulnerability in the name server through which he can read or write files, hell have unfettered access to the filesystem. If he can exploit a flaw that allows him to execute commands, hell execute them as root. BIND 8.1.2 and later include code that allows you to change the user and group the name server runs as. This allows you to run the name server with whats known as least privilege : the minimal set of rights it needs to do its job. That way, if someone breaks into your host through the name server, at least that person wont have root privileges. BIND 8.1.2 and later also include an option that allows you to chroot( ) the name server: to change its view of the filesystem so that its root directory is actually a particular directory on your hosts filesystem. This effectively traps your name server in this directory, along with any attackers who successfully compromise your name servers security. The command-line options that implement these features are: u Specifies the username or user ID the name server changes to after starting, e.g., named -u bin. g Specifies the group or group ID the name server changes to after starting, e.g., named -g other. If you specify -u without -g, the name server uses the users primary group. BIND 9 name servers always change to the users primary group, so they dont support -g. t Specifies the directory for the name server to chroot( ) to. If you opt to use the -u and -g options, youll have to decide what user and group to use. Your best bet is to create a new user and group for the name server to run as, such as named. Since the name server reads named.conf before giving up root privileges, you dont have to change that files permissions. However, you may have to change the permissions and ownership of your zone data files so that the user the name server runs as can read them. If you use dynamic update, youll have to make the zone data files for dynamically updated zones writable by the name server. If your name server is configured to log to files (instead of to syslog), make sure that those files exist and are writable by the name server before starting the server. The -t option takes a little more specialized configuration. In particular, you need to make sure that all the files named uses are present in the directory youre restricting the server to. Heres a procedure to follow to set up your chroot ed environment, which well assume lives under /var/named : 1. Create the /var/named directory, if it doesnt exist. Create dev, etc, lib, usr, and var subdirectories. Within usr, create an sbin subdirectory. Within var, create subdirectories named named and run: # mkdir /var/named # cd /var/named # mkdir -p dev etc lib usr/sbin var/named var/run 2. Copy named.conf to /var/named/etc/named.conf: # cp /etc/named.conf etc 3. If youre running BIND 8, copy the named-xfer binary to the usr/sbin/ or etc subdirectory (depending on whether you found it in /usr/sbin or /etc). # cp /usr/sbin/named-xfer usr/sbin Alternately, you can put it wherever you like under /var/named and use the named-xfer substatement to tell named where to find it. Just remember to strip /var/named off of the pathname, since when named reads named.conf, /var/named will look like the root of the filesystem. (If youre running BIND 9, skip this step because BIND 9 doesnt use named-xfer.) 4. Create dev/null in the chroot ed environment: # mknod dev/null c 1 3 5. If youre running BIND 8, copy the standard, shared C library and the loader to the lib subdirectory: # cp /lib/libc.so.6 /lib/ld-2.1.3.so lib # ln -s lib/ld-2.1.3.so lib/ld-linux.so.2 The pathnames may vary on your operating system. BIND 9 name servers are self-contained. 6. Edit your startup files to start syslogd with an additional option and option argument: -a /var/named/dev/log. On many modern versions of Unix, syslogd is started from /etc/rc.d/init.d/syslog. When syslogd restarts next, it will create /var/named/dev/log, and named will log to it. If your syslogd doesnt support the -a option, use the logging statement described in Chapter 7, Maintaining BIND, to log to files in the chroot ed directory. 7. If youre running BIND 8 and use the -u or -g options, create passwd and group files in the etc subdirectory to map the arguments of -u and -g to their numeric values (or just use numeric values as arguments):
# echo named:x:42:42:named:/: > etc/passwd # echo named::42 > etc/group Then add the entries to the systems /etc/passwd and /etc/group files. If youre running BIND 9, you can just add the entries to the systems /etc/passwd and /etc/group files, since BIND 9 name servers read the information they need before calling chroot( ). 8. Finally, edit your startup files to start named with the -t option and option argument: -t /var/named. Similarly to syslogd, many modern versions of Unix start named from /etc/rc.d/init.d/named. If youre hooked on using ndc to control your BIND 8 name server, you can continue to do so as long as you specify the pathname to the Unix domain socket as the argument to ndc s -c option: # ndc -c /var/named/var/run/ndc reload rndc will continue to work as before with your BIND 9 name server since it just talks to the server via port 953. Split-Function Name Servers Name servers really have two major roles: answering iterative queries from remote name servers and answering recursive queries from local resolvers. If we separate these roles, dedicating one set of name servers to answering iterative queries and another to answering recursive queries, we can more effectively secure those name servers. Delegated name server configuration Some of your name servers answer nonrecursive queries from other name servers on the Internet because these name servers appear in NS records delegating your zones to them. Well call these name servers delegated name servers. There are special measures you can take to secure your delegated name servers. But first, you should make sure that these name servers dont receive any recursive queries (that is, you dont have any resolvers configured to use these servers and no name servers use them as forwarders). Some of the precautions well takelike making the server respond nonrecursively even to recursive queriespreclude your resolvers from using these servers. If you do have resolvers using your delegated name servers, consider establishing another class of name servers to serve just your resolvers or using the Two Name Servers in One configuration, both described later in this chapter. Once you know your name server only answers queries from other name servers, you can turn off recursion. This eliminates a major vector of attack: the most common spoofing attacks involve inducing the target name server to query name servers under the hackers control by sending the target a recursive query for a domain name in a zone served by the hackers servers. To turn off recursion, use the following statement on a BIND 8 or 9 name server: options { recursion no; }; or, on a BIND 4.9 server, use: options no-recursion You should also restrict zone transfers of your zones to known slave servers, as described in the section Preventing Unauthorized Zone Transfers earlier in this chapter. Finally, you might also want to turn off glue fetching. Some name servers will automatically try to resolve the domain names of any name servers in NS records; to prevent this from happening and keep your name server from sending any queries of its own, use this on a BIND 8 name server (BIND 9 name servers have glue fetching turned off by default): options { fetch-glue no; }; or, on a BIND 4.9 server, use: options no-fetch-glue Resolving name server configuration Well call a name server that serves one or more resolvers or that is configured as another name servers forwarder a resolving name server. Unlike a delegated name server, a resolving name server cant refuse recursive queries. Consequently, we have to configure it a little differently to secure it. Since we know our name server should receive queries only from our own resolvers, we can configure it to deny queries from any but our resolvers IP addresses. Only BIND 8 and 9 allow us to restrict which IP addresses can send our name server arbitrary queries. (BIND 4.9 name servers let us restrict which IP addresses can send the server queries in authoritative zones, via the secure_zone TXT record, but were actually more worried about recursive queries in others zones.) This allow-query substatement restricts queries to just our internal network: options { allow-query { 192.249.249/24; 192.253.253/24; 192.253.254/24; }; }; With this configuration, the only resolvers that can send our name server recursive queries and induce them to query other name servers are our own internal resolvers, which are presumably relatively benevolent. Theres one other option we can use to make our resolving name server a little more secureuse-id-pool: options { use-id-pool yes; }; use-id-pool was introduced in BIND 8.2. It tells our name server to take special care to use random message IDs in queries. Normally, the message IDs arent random enough to prevent brute-force attacks that try to guess the IDs our name server has outstanding in order to spoof a response. The ID pool code became a standard part of BIND 9, so you dont need to specify it on a BIND 9 name server. Two Name Servers in One What if you have only one name server to advertise your zones and serve your resolvers, and you cant afford the additional expense of buying another computer to run a second name server on? There are still a few options open to you. Two are single-server solutions that take advantage of the flexibility of BIND 8 and 9. One of these configurations allows anyone to query the name server for information in zones its authoritative for, but only our internal resolvers can query the name server for other information. While this doesnt prevent remote resolvers from sending our name server recursive queries, those queries have to be in its authoritative zones so they wont induce our name server to send additional queries. Heres a named.conf file to do that: acl « internal » { 192.249.249/24; 192.253.253/24; 192.253.254/24; };
zone movie.edu { type master; file db.movie.edu; allow-query { any; }; allow-transfer { slaves; }; };
zone 249.249.192.in-addr.arpa { type master; file db.192.249.249; allow-query { any; }; allow-transfer { slaves; }; }; Here, the more permissive zone-specific access control lists apply to queries in the name servers authoritative zones, but the more restrictive global access control list applies to all other queries. If we were running BIND 8.2.1 or newer, we could simplify this configuration somewhat using the allow-recursion substatement: acl « internal » { 192.249.249/24; 192.253.253/24; 192.253.254/24; };
zone movie.edu { type master; file db.movie.edu; allow-transfer { slaves; }; };
zone 249.249.192.in-addr.arpa { type master; file db.192.249.249; allow-transfer { slaves; }; }; We dont need the allow-query substatements anymore: although the name server may receive queries from outside our internal network, itll treat those queries as nonrecursive, regardless of whether they are or not. Consequently, external queries wont induce our name server to send any queries. This configuration also doesnt suffer from a gotcha the previous setup is susceptible to: if your name server is authoritative for a parent zone, it may receive queries from remote name servers resolving domain names in a subdomain of the zone. The allow-query solution will refuse those legitimate queries, but the allow-recursion solution wont. Another option is to run two named processes on a single host. One is configured as a delegated name server, another as a resolving name server. Since we have no way of telling remote servers or configuring resolvers to query one of our name servers on a port other than 53, the default DNS port, we have to run these servers on different IP addresses. Of course, if your host already has more than one network interface, thats no problem. Even if it has only one, the operating system may support IP address aliases. These allow you to attach more than one IP address to a single network interface. One named process can listen on each. Finally, if the operating system doesnt support IP aliases, you can still bind one named against the network interfaces IP address and one against the loopback address. Only the local host will be able to send queries to the instance of named listening on the loopback address, but thats fine if the local hosts resolver is the only one you need to serve. First, heres the named.conf file for the delegated name server, listening on the network interfaces IP address: acl slaves { 192.249.249.1; 192.253.253.1; 192.249.249.9; 192;253.253.9; }; };
zone movie.edu { type master; file db.movie.edu; allow-transfer { slaves; }; };
zone 249.249.192.in-addr.arpa { type master; file db.192.249.249; allow-transfer { slaves; }; };
zone « . » { type hint; file « db.cache »; }; Next, heres the named.conf file for the resolving name server, listening on the loopback address: options { directory /var/named-resolving; listen-on { 127.0.0.1; }; pid-file /var/run/named.resolving.pid; use-id-pool yes; };
zone . { type hint; file db.cache; }; Note that we didnt need an access control list for the resolving name server, since its only listening on the loopback address and cant receive queries from other hosts. (If our resolving name server were listening on an IP alias or a second network interface, we could use allow-query to prevent others from using our name server.) We turn recursion off on the delegated name server, but we must leave it on on the resolving name server. We also give each name server its own PID file and its own directory so that the servers dont try to use the same default filename for their PID files, debug files, and statistics files. To use the resolving name server listening on the loopback address, the local hosts resolv.conf file must include the following: nameserver 127.0.0.1 as the first nameserver directive. If youre running BIND 9, you can even consolidate the two name server configurations into one using views: options { directory /var/named; };
zone movie.edu { type master; file db.movie.edu; };
zone 249.249.192.in-addr.arpa { type master; file « db.192.249.249 »; };
zone « . » { type hint; file db.cache; }; }; Its a fairly simple configuration: two views, internal and external. The internal view, which applies only to our internal network, has recursion on. The external view, which applies to everyone else, has recursion off. The zones movie.edu and 249.249.192.in-addr.arpa are defined identically in both zones. You could do a lot more with itdefine different versions of the zones internally and externally, for examplebut well hold off on that until the next section. DNS and Internet Firewalls The Domain Name System wasnt designed to work with Internet firewalls. Its a testimony to the flexibility of DNS and of its BIND implementation that you can configure DNS to work with, or even through, an Internet firewall. That said, configuring BIND to work in a firewalled environment, although not difficult, takes a good, complete understanding of DNS and a few of BINDs more obscure features. Describing it also requires a large portion of this chapter, so heres a roadmap. Well start by describing the two major families of Internet firewall softwarepacket filters and application gateways. The capabilities of each family have a bearing on how youll need to configure BIND to work through the firewall. Next, well detail the two most common DNS architectures used with firewalls, forwarders and internal roots, and describe the advantages and disadvantages of each. Well then introduce a solution using a new feature, forward zones, which combines the best of internal roots and forwarders. Finally, well discuss split namespaces and the configuration of the bastion host, the host at the core of your firewall system. Types of Firewall Software Before you start configuring BIND to work with your firewall, its important to understand what your firewall is capable of. Your firewalls capabilities will influence your choice of DNS architecture and determine how you implement it. If you dont know the answers to the questions in this section, track down someone in your organization who does know and ask. Better yet, work with your firewalls administrator when designing your DNS architecture to ensure it will coexist with the firewall. Note that this is far from a complete explanation of Internet firewalls. These few paragraphs describe only the two most common types of Internet firewalls and only in enough detail to show how the differences in their capabilities affect name servers. For a comprehensive treatment of Internet firewalls, see Elizabeth D. Zwicky, Simon Cooper, and D. Brent Chapmans Building Internet Firewalls (OReilly). Packet filters The first type of firewall well cover is the packet-filtering firewall. Packet-filtering firewalls operate largely at the transport and network levels of the TCP/IP stack (layers three and four of the OSI reference model, if you dig that). They decide whether to route a packet based on packet-level criteria like the transport protocol (e.g., whether its TCP or UDP), the source and destination IP address, and the source and destination port Whats most important to us about packet-filtering firewalls is that you can typically configure them to allow DNS traffic selectively between hosts on the Internet and your internal hosts. That is, you can let an arbitrary set of internal hosts communicate with Internet name servers. Some packet-filtering firewalls can even permit your name servers to query name servers on the Internet, but not vice versa. All router-based Internet firewalls are packet-filtering firewalls. Checkpoints FireWall-1, Ciscos PIX, and Suns SunScreen are popular commercial packet-filtering firewalls. Application gateways, Application gateways operate at the application protocol level, several layers higher in the OSI reference model than most packet filters In a sense, they understand the application protocol in the same way a server for that particular application would. An FTP application gateway, for example, can make the decision to allow or deny a particular FTP operation, such as a RETR (a get) or a STOR (a put). The bad news, and whats important for our purposes, is that most application gateway-based firewalls handle only TCP-based application protocols. DNS, of course, is largely UDP-based, and we know of no application gateways for DNS. This implies that if you run an application gateway-based firewall, your internal hosts will likely not be able to communicate directly with name servers on the Internet.The popular Firewall Toolkit from Trusted Information Systems (TIS, now part of Network Associates) is a suite of application gateways for common Internet protocols such as Telnet, FTP, and HTTP. Network Associates Gauntlet product is also based on application gateways, as is Axents Eagle Firewall. Note that these two categories of firewall are really just generalizations. The state of the art in firewalls changes very quickly, and by the time you read this, you may have a firewall that includes an application gateway for DNS. Which family your firewall falls into is important only because it suggests what that firewall is capable of; whats more important is whether your particular firewall will let you permit DNS traffic between arbitrary internal hosts and the Internet. A Bad Example The simplest configuration is to allow DNS traffic to pass freely through your firewall (assuming you can configure your firewall to do that). That way, any internal name server can query any name server on the Internet, and any Internet name server can query any of your internal name servers. You dont need any special configuration. Unfortunately, this is a really bad idea, for a number of reasons: Version control The developers of BIND are constantly finding and fixing security-related bugs in the BIND code. Consequently, its important to run a recent version of BIND, especially on name servers directly exposed to the Internet. If one or just a few of your name servers communicate directly with name servers on the Internet, upgrading them to a new version is easy. If any of the name servers on your network can communicate directly with name servers on the Internet, upgrading all of them is vastly more difficult. Possible vector for attack Even if youre not running a name server on a particular host, a hacker might be able to take advantage of your allowing DNS traffic through your firewall and attack that host. For example, a co-conspirator working on the inside could set up a Telnet daemon listening on the hosts DNS port, allowing the hacker to telnet right in. For the rest of this chapter, well try to set a good example. Internet Forwarders Given the dangers of allowing bidirectional DNS traffic through the firewall unrestricted, most organizations limit the internal hosts that can talk DNS to the Internet. In an application gateway firewall, or any firewall without the ability to pass DNS traffic, the only host that can communicate with Internet name servers is the bastion host . In a packet-filtering firewall, the firewalls administrator can configure the firewall to let any set of internal name servers communicate with Internet name servers. Often, this is a small set of hosts that run name servers under the direct control of the network administrator ; Internal name servers that can directly query name servers on the Internet dont require any special configuration. Their root hints files contain the Internets root name servers, which enables them to resolve Internet domain names. Internal name servers that cant query name servers on the Internet, however, need to know to forward queries they cant resolve to one of the name servers that can. This is done with the forwarders directive or substatement. At Movie U., we put in a firewall to protect ourselves from the Big Bad Internet several years ago. Ours is a packet-filtering firewall, and we negotiated with our firewall administrator to allow DNS traffic between Internet name servers and two of our name servers, terminator.movie.edu and wormhole.movie.edu. Heres how we configured the other internal name servers at the university. For our BIND 8 and 9 name servers, we used the following: options { forwarders { 192.249.249.1; 192.249.249.3; }; forward only; }; and for our BIND 4 name servers, we used: forwarders 192.249.249.3 192.249.249.1 options forward-only We vary the order in which the forwarders appear to help spread the load between them, though thats not necessary with BIND 8.2.3 name servers, which choose which forwarder to query according to roundtrip time. When an internal name server receives a query for a name it cant resolve locally, such as an Internet domain name, it forwards that query to one of our forwarders, which can resolve the name using name servers on the Internet. Simple! The trouble with forwarding Unfortunately, its a little too simple. Forwarding starts to get in the way once you delegate subdomains or build an extensive network. To explain what we mean, take a look at part of the configuration file on zardoz.movie.edu: options { directory /var/named; forwarders { 192.249.249.1; 192.253.253.3; }; };
zone movie.edu { type slave; masters { 192.249.249.3; }; file bak.movie.edu; }; zardoz.movie.edu is a slave for movie.edu and uses our two forwarders. What happens when zardoz.movie.edu receives a query for a name in fx.movie.edu ? As an authoritative movie.edu name server, zardoz.movie.edu has the NS records that delegate fx.movie.edu to its authoritative name servers. But its also been configured to forward queries it cant resolve locally to terminator.movie.edu and wormhole.movie.edu. Which will it do? It turns out that zardoz.movie.edu ignores the delegation information and forwards the query to terminator.movie.edu. That works since terminator.movie.edu receives the recursive query and asks an fx.movie.edu name server on zardoz.movie.edus behalf. But its not particularly efficient since zardoz.movie.edu could easily have sent the query directly. Now imagine that the scale of the network is much larger: a corporate network that spans continents, with tens of thousands of hosts and hundreds or thousands of name servers. All the internal name servers that dont have direct Internet connectivitythe vast majority of themuse a small set of forwarders. Whats wrong with this picture? Single point of failure If the forwarders fail, your name servers lose the ability to resolve both Internet domain names and internal domain names that they dont have cached or stored as authoritative data. Concentration of load The forwarders have an enormous query load placed on them. This is both because of the large number of internal name servers that use them, and because the queries are recursive and require a good deal of work to answer. Inefficient resolution Imagine two internal name servers, authoritative for west.acmebw.com and east.acmebw.com, respectively, both on the same network segment in Boulder, Colorado. Both are configured to use the companys forwarder in Bethesda, Maryland. For the west.acmebw.com name server to resolve a name in east.acmebw.com, it sends a query to the forwarder in Bethesda. The forwarder in Bethesda then sends a query back to Boulder to the east.acmebw.com name server, the original queriers neighbor. The east.acmebw.com name server replies by sending a response back to Bethesda, which the forwarder sends back to Boulder. In a traditional configuration with root name servers, the west.acmebw.com name server would have learned quickly that an east.acmebw.com name server was next door and would favor it (because of its low roundtrip time). Using forwarders short-circuits the normally efficient resolution process. The upshot is that forwarding is fine for small networks and simple namespaces, but probably inadequate for large networks and complex namespaces. We found this out the hard way at Movie U., as our network grew and we were forced to find an alternative. Using forward zones We can solve this problem by using the forward zones introduced in BIND 8.2. We change zardoz.movie.edus configuration to this: options { directory /var/named; forwarders { 192.249.249.1; 192.253.253.3; }; };
zone movie.edu { type slave; masters { 192.249.249.3; }; file bak.movie.edu; forwarders {}; }; Now, if zardoz.movie.edu receives a query for a domain name ending in movie.edu but outside the movie.edu zone (e.g., in fx.movie.edu), it ignores the forwarders and sends iterative queries. With this configuration, zardoz.movie.edu still sends queries for domain names in our reverse-mapping zones to our forwarders. To relieve that load, we can add a few zone statements to named.conf: zone 249.249.192.in-addr.arpa { type stub; masters { 192.249.249.3; }; file stub.192.249.249; forwarders {}; };
zone 253.253.192.in-addr.arpa { type stub; masters { 192.249.249.3; }; file stub.192.253.253; forwarders {}; };
zone 254.253.192.in-addr.arpa { type stub; masters { 192.253.254.2; }; file stub.192.253.254; forwarders {}; };
zone 20.254.192.in-addr.arpa { type stub; masters { 192.253.254.2; }; file stub.192.254.20; forwarders {}; }; These new zone statements bear some explaining: first of all, they configure Movie U.s reverse-mapping zones as stubs. That makes our name server track the NS records for those zones by periodically querying the master name servers for those zones. The forwarders substatement then turns off forwarding for domain names in the reverse-mapping domains. Now, instead of querying the forwarders for, say, the PTR record for 2.254.253.192.in-addr.arpa, zardoz.movie.edu will query one of the 254.253.192.in-addr.arpa name servers directly.Well need zone statements like these on all of our internal name servers, which also implies that well need all of our name servers to run some version of BIND 8 after 8.2. This gives us a fairly robust resolution architecture that minimizes our exposure to the Internet: it uses efficient, robust iterative name resolution to resolve internal domain names, and forwarders only when necessary to resolve Internet domain names. If our forwarders fail or we lose our connection to the Internet, we lose only our ability to resolve Internet domain names. Internal Roots If you want to avoid the scalability problems of forwarding, you can set up your own root name servers. These internal roots will serve only the name servers in your organization. Theyll know about only the portions of the namespace relevant to your organization. What good are they? By using an architecture based on root name servers, you gain the scalability of the Internets namespace (which should be good enough for most companies), plus redundancy, distributed load, and efficient resolution. You can have as many internal roots as the Internet has roots--13 or sowhereas having that many forwarders may be an undue security exposure and a configuration burden. Most of all, the internal roots dont get used frivolously. Name servers need to consult an internal root only when they time out the NS records for your top-level zones. Using forwarders, name servers may have to query a forwarder once per resolution. The moral of our story is that if you have, or intend to have, a large namespace and lots of internal name servers, internal root name servers will scale better than any other solution. Where to put internal root name servers Since name servers lock on to the closest root name server by favoring the one with the lowest roundtrip time, it pays to pepper your network with internal root name servers. If your organizations network spans the U.S., Europe, and the Pacific Rim, consider locating at least one internal root name server on each continent. If you have three major sites in Europe, give each of them an internal root. Forward-mapping delegation Heres how an internal root name server is configured. An internal root delegates directly to any zones you administer. For example, on the movie.edu network, the root zones data file would contain: movie.edu. 86400 IN NS terminator.movie.edu. 86400 IN NS wormhole.movie.edu. 86400 IN NS zardoz.movie.edu. terminator.movie.edu. 86400 IN A 192.249.249.3 wormhole.movie.edu. 86400 IN A 192.249.249.1 86400 IN A 192.253.253.1 zardoz.movie.edu. 86400 IN A 192.249.249.9 86400 IN A 192.253.253.9 On the Internet, this information would appear in the edu name servers zone data files. On the movie.edu network, of course, there arent any edu name servers, so you delegate directly to movie.edu from the root. Notice that this doesnt contain delegation to fx.movie.edu or to any other subdomain of movie.edu. The movie.edu name servers know which name servers are authoritative for all movie.edu subdomains, and all queries for information in those subdomains pass through the movie.edu name servers, so theres no need to delegate them here. in-addr.arpa delegation We also need to delegate from the internal roots to the in-addr.arpa zones that correspond to the networks at the university: 249.249.192.in-addr.arpa. 86400 IN NS terminator.movie.edu. 86400 IN NS wormhole.movie.edu. 86400 IN NS zardoz.movie.edu. 253.253.192.in-addr.arpa. 86400 IN NS terminator.movie.edu. 86400 IN NS wormhole.movie.edu. 86400 IN NS zardoz.movie.edu. 254.253.192.in-addr.arpa. 86400 IN NS bladerunner.fx.movie.edu. 86400 IN NS outland.fx.movie.edu. 86400 IN NS alien.fx.movie.edu. 20.254.192.in-addr.arpa. 86400 IN NS bladerunner.fx.movie.edu. 86400 IN NS outland.fx.movie.edu. 86400 IN NS alien.fx.movie.edu. Notice that we did include delegation for the 254.253.192.in-addr.arpa and the 20.254.192.in-addr.arpa zones, even though they correspond to the fx.movie.edu zone. We dont need to delegate to fx.movie.edu because wed already delegated to its parent, movie.edu. The movie.edu name servers delegate to fx.movie.edu, so by transitivity the roots delegate to fx.movie.edu. Since neither of the other in-addr.arpa zones is a parent of 254.253.192.in-addr.arpa or 20.254.192.in-addr.arpa, we need to delegate both zones from the root. As we explained earlier, we dont need to add address records for the three Special Effects name servers, bladerunner.fx.movie.edu, outland.fx.movie.edu, and alien.fx.movie.edu, because a remote name server can already find their addresses by following delegation from movie.edu. The db.root file All thats left is to add an SOA record for the root zone and NS records for this internal root name server and any others: $TTL 1d . IN SOA rainman.movie.edu. hostmaster.movie.edu. ( 1 ; serial 3h ; refresh 1h ; retry 1w ; expire 1h ) ; negative caching TTL IN NS rainman.movie.edu. IN NS awakenings.movie.edu.
rainman.movie.edu. IN A 192.249.249.254 awakenings.movie.edu. IN A 192.253.253.254 rainman.movie.edu and awakenings.movie.edu are the hosts running the internal root name servers. We shouldnt run an internal root on a bastion host, because if a name server on the Internet accidentally queries it for data its not authoritative for, the internal root will respond with its list of rootsall internal! So the whole db.root file (by convention, we call the root zones data file db.root) looks like this: $TTL 1d . IN SOA rainman.movie.edu. hostmaster.movie.edu. ( 1 ; serial 3h ; refresh 1h ; retry 1w ; expire 1h ) ; negative caching TTL IN NS rainman.movie.edu. IN NS awakenings.movie.edu.
rainman.movie.edu. IN A 192.249.249.254 awakenings.movie.edu. IN A 192.253.253.254 movie.edu. IN NS terminator.movie.edu. IN NS wormhole.movie.edu. IN NS zardoz.movie.edu. terminator.movie.edu. IN A 192.249.249.3 wormhole.movie.edu. IN A 192.249.249.1 IN A 192.253.253.1 zardoz.movie.edu. IN A 192.249.249.9 IN A 192.253.253.9 249.249.192.in-addr.arpa. IN NS terminator.movie.edu. IN NS wormhole.movie.edu. IN NS zardoz.movie.edu. 253.253.192.in-addr.arpa. IN NS terminator.movie.edu. IN NS wormhole.movie.edu. IN NS zardoz.movie.edu. 254.253.192.in-addr.arpa. IN NS bladerunner.fx.movie.edu. IN NS outland.fx.movie.edu. IN NS alien.fx.movie.edu. 20.254.192.in-addr.arpa. IN NS bladerunner.fx.movie.edu. IN NS outland.fx.movie.edu. IN NS alien.fx.movie.edu. The named.conf file on both the internal root name servers, rainman.movie.edu and awakenings.movie.edu, contains the lines: zone . { type master; file db.root; }; Or, for a BIND 4 servers named.boot file: primary . db.root This replaces a zone statement of type hint or a cache directivea root name server doesnt need a root hints file to tell it where the other roots are; it can find that in db.root. Did we really mean that each root name server is a primary master for the root zone? Not unless youre running an ancient version of BIND. All BIND versions after 4.9 let you declare a server as a slave for the root zone, but BIND 4.8.3 and earlier insist that all root name servers load the root zone as primaries. If you dont have a lot of idle hosts sitting around that you can turn into internal roots, dont despair! Any internal name server (i.e., one thats not running on a bastion host or outside your firewall) can serve double duty as an internal root and as an authoritative name server for whatever other zones you need it to load. Remember, a single name server can be authoritative for many, many zones, including the root zone. Configuring other internal name servers Once youve set up internal root name servers, configure all your name servers on hosts anywhere on your internal network to use them. Any name server running on a host without direct Internet connectivity (i.e., behind the firewall) should list the internal roots in its root hints file: ; Internal root hints file, for Movie U. hosts without direct ; Internet connectivity ; ; Dont use this file on a host with Internet connectivity! ;
. 99999999 IN NS rainman.movie.edu. 99999999 IN NS awakenings.movie.edu. rainman.movie.edu. 99999999 IN A 192.249.249.254 awakenings.movie.edu. 99999999 IN A 192.253.253.254 Name servers running on hosts using this root hints file will be able to resolve domain names in movie.edu and in Movie U.s in-addr.arpa domains, but not outside those domains. How internal name servers use internal roots To tie together how this whole scheme works, lets go through an example of name resolution on an internal caching-only name server using these internal root name servers. First, the internal name server receives a query for a domain name in movie.edu, say the address of gump.fx.movie.edu. If the internal name server doesnt have any better information cached, it starts by querying an internal root name server. If it has communicated with the internal roots before, it has a roundtrip time associated with each, telling it which of the internal roots is responding to it most quickly. It then sends a nonrecursive query to that internal root for gump.fx.movie.edus address. The internal root answers with a referral to the movie.edu name servers on terminator.movie.edu, wormhole.movie.edu, and zardoz.movie.edu. The caching-only name server follows up by sending another nonrecursive query to one of the movie.edu name servers for gump.fx.movie.edus address. The movie.edu name server responds with a referral to the fx.movie.edu name servers. The caching-only name server sends the same nonrecursive query for gump.fx.movie.edus address to one of the fx.movie.edu name servers and finally receives a response. Contrast this with the way a forwarding setup would work. Lets imagine that instead of using internal root name servers, our caching-only name server were configured to forward queries first to terminator.movie.edu and then to wormhole.movie.edu. In that case, the caching-only name server would check its cache for the address of gump.fx.movie.edu and, not finding it, would forward the query to terminator.movie.edu. Then, terminator.movie.edu would query an fx.movie.edu name server on the caching-only name servers behalf and return the answer. Should the caching-only name server need to look up another name in fx.movie.edu, it would still ask the forwarder, even though the forwarders response to the query for gump.fx.movie.edus address probably contains the names and addresses of the fx.movie.edu name servers. Mail from internal hosts to the Internet But wait! Thats not all internal roots will do for you. We talked about getting mail to the Internet without changing sendmail s configuration all over the network. Wildcard records are the key to getting mail to workspecifically, wildcard MX records. Lets say that we want mail to the Internet to be forwarded through postmanrings2x.movie.edu, the Movie U. bastion host, which has direct Internet connectivity. Adding the following records to db.root will get the job done: IN MX 5 postmanrings2x.movie.edu. *.edu. IN MX 10 postmanrings2x.movie.edu. We need the *.edu MX record in addition to the * record because of wildcard production rules, which you can read more about in the Wildcards section of Chapter 16, Miscellaneous. Basically, since there is explicit data for movie.edu in the zone, the first wildcard wont match movie.edu or any other subdomains of edu. We need another, explicit wildcard record for edu to match subdomains of edu besides movie.edu. Now mailers on our internal movie.edu hosts will send mail addressed to Internet domain names to postmanrings2x.movie.edu for forwarding. For example, mail addressed to nic.ddn.mil will match the first wildcard MX record: % nslookup -type=mx nic.ddn.mil.Matches the MX record for * Server: rainman.movie.edu Address: 192.249.249.19
nic.ddn.mil preference = 5, mail exchanger = postmanrings2x.movie.edu postmanrings2x.movie.edu internet address = 192.249.249.20 Mail addressed to vangogh.cs.berkeley.edu will match the second MX record: % nslookup -type=mx vangogh.cs.berkeley.edu.Matches the MX record for *.edu Server: rainman.movie.edu Address: 192.249.249.19
vangogh.cs.berkeley.edu preference = 10, mail exchanger = postmanrings2x.movie.edu postmanrings2x.movie.edu internet address = 192.249.249.20 Once the mail has reached postmanrings2x.movie.edu, our bastion host, postmanrings2x.movie.edus mailer will look up the MX records for these addresses itself. Since postmanrings2x.movie.edu will resolve the destinations domain name using the Internets namespace instead of the internal namespace, it will find the real MX records for the domain name and deliver the mail. No changes to sendmail s configuration are necessary. Mail to specific Internet domain names Another nice perk of this internal root scheme is that it gives you the ability to forward mail addressed to certain Internet domain names through particular bastion hosts, if you have more than one. We can choose, for example, to send all mail addressed to recipients in the uk domain to our bastion host in London first and then out onto the Internet. This can be very useful if we want our mail to travel across our own network as far as possible or if were billed for our usage of some network in the U.K. Movie U. has a private network connection to our sister university in London near Pinewood Studios. For security reasons, wed like to send mail addressed to correspondents in the U.K. across our private link and then through the Pinewood host. So we add the following wildcard records to db.root: ; holygrail.movie.ac.uk is at the other end of our U.K. Internet link *.uk. IN MX 10 holygrail.movie.ac.uk. holygrail.movie.ac.uk. IN A 192.168.76.4 Now, mail addressed to users in subdomains of uk will be forwarded to the host holygrail.movie.ac.uk at our sister university, which presumably has facilities to forward that mail to other points in the U.K. The trouble with internal roots Unfortunately,