RFC 2694
DNS extensions to Network Address Translators (DNS_ALG)
๐ RFC 2694: DNS extensions to Network Address Translators (DNS_ALG) (part 1 of 6 โจ)
Network Working Group ๐ธ ยท Category: Informational ยท Date: September 1999 Authors: P. Srisuresh (Consultant), G. Tsirtsis (BT Laboratories), P. Akkiraju (Cisco Systems), A. Heffernan (Juniper Networks) Obsoletes / Updates: this document doesn't list anything it obsoletes or updates ๐ง
Status of This Memo โจ
okay so this one is just informational bestie ๐ It's giving "here's some info for the internet community," not an actual Internet standard of any kind. Distribution is unlimited, so share it with everyone ๐ฆ
Copyright Notice ๐ฅ
Copyright (C) The Internet Society (1999). All Rights Reserved. ๐
Abstract ๐
Okay this is the tea ๐ Domain Name Service (DNS) gives you name-to-address mapping inside a routing class (ex: IP). Network Address Translators (NATs) try to give you transparent routing between hosts that live in different address realms of the same routing class. Usually NATs sit at the edge of a stub domain and hide private addresses from the outside world ๐ซถ
This doc is all about why DNS needs extensions when NATs are involved, and how a DNS Application Level Gateway (DNS_ALG) can fix it. The DNS_ALG changes the payload transparently so address mappings stay correct as DNS packets cross from one address realm into another. The doc also walks through the DNS_ALG in action with some specific examples โจ
1. Introduction โจ
Network Address Translators (NATs) show up a lot when a network's internal IP addresses can't be used outside that network, either for privacy reasons or because they just aren't valid outside ๐
Ideally, a host name uniquely identifies a host, and its address is what gets used to find routes to that host. The thing is, applications don't always keep those two separate and often use them interchangeably ๐ Apps end up putting an IP address into the payload instead of a host name. Some examples: emails that give their MX server address (ex: user@666.42.7.11) instead of the server name (ex: user@private.com) as the sender ID, and HTML files that have IP addresses instead of names in their URLs, and so on ๐ธ This is a problem when the packet crosses a NAT, because NATs rewrite the network and transport headers to suit the address realm but leave the payload alone ๐ญ
DNS gives you name-to-address mapping. NAT does address translation (in the network and transport headers) for datagrams going between private and external address realms ๐ง The DNS_ALG described here helps translate Name-to-Private-Address mappings in DNS payloads into Name-to-External-Address mappings, and vice versa, using the state information the NAT already keeps ๐
A Network Address Port Translator (NAPT) does address and transport-level port translation (i.e., TCP and UDP ports, plus ICMP query IDs). But DNS name mapping is only at the granularity of IP addresses and doesn't go down to transport-level identifiers ๐ So for a NAPT setup, the DNS_ALG work is simpler: every host address in the private network gets bound to one single external address. When external hosts look up private hosts by name, they don't need a fresh private-to-external binding each time, since all the private hosts share that one pre-defined external address. Reverse name lookups for the NAPT external address won't map to any of the private hosts, though. They'll just map to the NAPT router ๐
Basically, the DNS_ALG requirements for NAPT are a subset of what Basic NAT needs, so it's a lot less work ๐ That's why the rest of this document focuses on Basic NAT, Bi-directional NAT and Twice NAT setups, and doesn't talk about the NAPT setup specifically ๐
Definitions for DNS and related terms can be found in [Ref 3] and [Ref 4]. Definitions for NAT-related terms can be found in [Ref 1] ๐
2. Requirement for DNS extensions ๐ฅ
There are lots of ways to make sure a host name maps to an address that's relevant inside an address realm ๐ฆ In the sections that follow, we'll point out exactly where DNS extensions would be needed โจ
Organizations typically have two kinds of authoritative name servers. Internal authoritative name servers identify all (or most) of the corporate resources in the organization, but only some of those hosts are allowed to be reached from the external world ๐ The rest of the hosts and their names are unique to the private network. The hosts that the outside world can see, along with the authoritative name server that maps their names to network addresses, usually sit in a DMZ (De-Militarized Zone) in front of a firewall ๐ก๏ธ We'll call the hosts and name servers in the DMZ "DMZ hosts" and "DMZ name servers," respectively. DMZ host names are end-to-end unique, meaning their FQDNs don't overlap with any end node that talks to them ๐
\ | /
+-----------------------+
|Service Provider Router|
+-----------------------+
WAN |
Stub A .........|\|....
|
+-----------------+
|Stub Router w/NAT|
+-----------------+
|
| DMZ - Network
------------------------------------------------------------
| | | | |
+--+ +--+ +--+ +--+ +----------+
|__| |__| |__| |__| | Firewall |
/____\ /____\ /____\ /____\ +----------+
DMZ-Host1 DMZ-Host2 ... DMZ-Name DMZ-Web |
Server Server etc. |
|
Internal hosts (Private IP network) |
------------------------------------------------------------
| | | |
+--+ +--+ +--+ +--+
|__| |__| |__| |__|
/____\ /____\ /____\ /____\
Int-Host1 Int-Host2 ..... Int-Hostn Int-Name Server
Figure 1: DMZ network configuration of a private Network. ๐
Figure 1 shows a private network that includes a DMZ. Real setups can vary ๐ง Internal name servers are only used by people inside the private network, and internal DNS queries and responses never cross the private network boundary ๐ DMZ name servers and DMZ hosts, on the other hand, are end-to-end unique and can be reached by both external and internal hosts โจ For the rest of this document we'll focus only on DMZ hosts and DMZ name servers, and won't cover internal hosts and internal name servers unless they happen to be the same things ๐
2.1. DMZ hosts assigned static external addresses on NAT ๐ฆ
Let's say DMZ hosts get static external addresses on the NAT device. Keep in mind that all hosts in the private domain, including the DMZ hosts, are identified by their private addresses ๐ The static mapping on the NAT device lets the DMZ hosts be identified by their public addresses in the external domain ๐ซถ
2.1.1. Private networks with no DMZ name servers ๐ธ
Now imagine a private network that doesn't have its own DMZ name server. If the private network connects to a single service provider for external connectivity, the DMZ hosts can be listed by their external addresses in the service provider's authoritative name servers, in both their forward and in-addr.arpa reverse zones ๐
If the network connects to multiple service providers, the DMZ host names can be listed by their external address(es) in the authoritative name servers of each of those providers. This matters a lot for in-addr.arpa reverse zones, since the private network may be given different address prefixes by different service providers ๐
Either way, externally generated DNS lookups won't reach the private network ๐ญ A large number of NAT-based private domains go with this option so their DMZ hosts are listed by their external addresses on the service provider's name servers ๐
2.1.2. Private networks with DMZ name servers ๐
Next, picture a private network that decides to keep an authoritative DMZ name server for the zone inside the network itself. If the network connects to a single service provider, the DMZ name server can be configured to avoid DNS payload interceptions like this: the hosts in the DMZ name server have to be mapped to their statically assigned external addresses, and the internal name server has to be set up to bypass the DMZ name server for queries about external hosts ๐ง This way, the DMZ name servers are set up for exclusive access by external hosts alone (not even the DMZ hosts), so they can be configured with external addresses only โจ
That scheme takes careful admin planning to make sure private hosts never contact the DMZ name servers, either directly or indirectly (through the internal name servers) ๐ฉ Using a DNS-ALG would save you from those administrative headaches ๐
2.2. DMZ hosts assigned external addresses dynamically on NAT ๐
Now the case where DMZ hosts in a private network get external addresses dynamically from the NAT. The addresses those hosts are given are fixed inside the private network, but their externally known addresses are ephemeral and decided by the NAT ๐ฆ In this situation, the private organization has to have a DMZ name server so that people can reach DMZ hosts by name. That's not optional, it's mandatory ๐ฅ
The DMZ name server would be configured with the private addresses of the DMZ hosts. The DNS Application Level Gateway (DNS_ALG) living on the NAT device will intercept DNS packets going to or from the DMZ name server(s) and do transparent payload translations, so that a DMZ host name maps to the right address in each address realm (private or external) ๐โจ
3. Interactions between NAT and DNS_ALG โจ
okay bestie, so this whole doc runs on the vibe that address realms are allowed to have overlapping address space ๐ฆ but host names have to be end-to-end unique, or nobody can reach anybody. there cannot be an overlap of FQDNs between end nodes that talk to each other. periodt ๐
Figure 2 shows how a DNS packet going through a NAT box (with a DNS_ALG) gets changed in two places, its headers AND its payload ๐ง a DNS packet can be a TCP or UDP packet with the source or destination port set to 53. NAT translates the IP and TCP/UDP headers, then tells DNS-ALG to fix up the payload. DNS-ALG talks back to NAT and uses NAT's state info to edit the payload wherever it's needed ๐
Original-IP
packet
||
||
vv
+---------------------------------+ +-----------------------+
| | |DNS Appl. Level Gateway|
|Network Address Translation (NAT)|--->| (DNS_ALG) |
| *IP & Transport header mods |<---| *DNS payload mods |
| | | |
+---------------------------------+ +-----------------------+
||
||
vv
Translated-IP
packet
Figure 2: NAT & DNS-ALG in the translation path of DNS packets
3.1. Address Binding considerations
okay so we split NAT bindings into two flavours: "Temporary Address Binding" and "Committed Address Binding" ๐ why? because DNS_ALG lets outside users create state on the NAT, which means denial-of-service attacks become a whole thing ๐ญ A temporary address binding is when an address binding is reserved but no NAT sessions are using it yet. A committed address binding is when at least one NAT session is using the binding between the external and private addresses. DNS_ALG uses both kinds to modify DNS payloads. NAT only uses committed bindings to modify the IP and Transport headers of datagrams that belong to NAT sessions.
for statically mapped addresses, none of this distinction matters ๐ for dynamically mapped addresses, though, a temporary binding usually shows up before the committed one. the temporary binding gets made when the DMZ name server gets asked for a name lookup. a name query is probably the warm-up before a real session between the query sender and the host being asked about ๐ธ the temporary binding only becomes committed once NAT sees the first packet of that session between the query initiator and the queried host.
there's a configurable parameter called "Bind-holdout time" that can be set for dynamic address assignments. it's the longest a temporary address binding can stay active without turning into a committed one โณ every time DNS_ALG uses the temporary binding to edit a DNS payload, the Bind-holdout period gets renewed. a default Bind-holdout time of a couple of minutes might suffice for most DNS-ALG implementations. also, a committed address binding can happen without ever being preceded by a temporary binding, which is a fun plot twist ๐ and when NAT is ready to unbind a committed address binding, it goes back to being a temporary binding and hangs around for one more Bind-holdout period. the binding only gets freed once Bind-holdout time runs out. both the Bind-holdout time before the committed binding and the Bind-holdout time before unbinding are required to make sure end hosts have enough time to start a data session after a name lookup ๐ซถ
let's do an example. say a private network with address prefix 10/8 is mapped to 198.76.29/24. when an external host makes a DNS query for host7, which has address 10.0.0.7, the DMZ name server inside the private network replies with an A type RR for host7 like this:
host7 A 10.0.0.7
DNS_ALG would catch that response packet, and if 10.0.0.7 doesn't already have an external address, it asks NAT to create a temporary address binding with an external address and start the Bind-holdout timer to age the binding ๐ฅ say the external address assigned is 198.76.29.1. DNS-ALG then uses that temporary binding to edit the RR in the DNS response, swapping 10.0.0.7 for its external address, and replies with:
host7 A 198.76.29.1
when the query initiator gets the DNS response, only the external address is visible ๐ within a short window (hopefully before the bind-holdout time runs out), the query initiator starts a session with host7. once NAT notices a new session heading to 198.76.29.1, NAT stops the Bind-holdout timer and turns the temporary binding between 198.76.29.1 and 10.0.0.7 into a committed binding ๐ฆ
now, to stop denial-of-service attacks, where some bad actor keeps trying name resolutions and never actually starts a connection ๐, NAT would have to keep an eye on temporary address bindings that never became committed bindings. there could be a limit on how many temporary bindings exist, and attempts to make more could just get rejected. there may be other heuristic solutions for these kinds of malicious attacks too.
we're going to use bi-directional NAT to illustrate DNS_ALG's use of temporary bindings in the following sub-sections, even though the concept works for other flavours of NAT too ๐
3.2. Incoming queries
okay so, to start an incoming session, an external host needs the V4 address of the DMZ host it wants to reach, and it gets that by making a DNS request ๐ฎ this request is the prelude to a possible new session.
the external host's resolver does a name lookup for the DMZ host through its DNS server. when that DNS server has no IPv4 address record for this name, the lookup query gets redirected at some point to the Primary/Backup DNS server (basically, the one in the DMZ) of the private stub domain.
on the way to the DMZ name server, DNS_ALG catches the datagram and edits the query like this ๐
- a) For Host name to Host address query requests: Make no change to the DNS payload.
- b) For Host address to Host name queries: Replace the external V4 address octets (in reverse order) preceding the string "IN-ADDR.ARPA" with the corresponding private V4 address, if such an address binding exists already. However, if a binding does not exist, the DNS_ALG would simply respond (as a name server would) with a response code (RCODE) of 5 (REFUSED to respond due to policy reasons) and set ANCOUNT, NSCOUNT and ARCOUT to 0 in the header section of the response. ๐ โโ๏ธ
going the other way, when the DNS response comes back from the DNS server in the private network, DNS_ALG catches the packet again and edits it like so ๐
- a) For a host name to host address query requests, replace the private address sent by the DMZ name server with a public address internally assigned by the NAT router. If a public address is not previously assigned to the host's private address, NAT would assign one at this time. โจ
- b) For host address to host name queries, replace the private address octets preceding the string "IN-ADDR.ARPA" in response RRs with their external address assignments. there's a chance that by the time the DMZ name server replies, the bind-holdout timer in NAT for that address has already expired ๐ญ if so, DNS_ALG would simply drop the reply. the sender will have to resend the query (the same thing that happens when a router along the way drops the response).
for static address assignments, the TTL value in the original RR stays unchanged ๐ for dynamic address assignments, DNS_ALG changes the TTL value on DNS resource records (RRs) to 0. that means the RRs should only be used for the transaction in progress, and not cached. for compatibility with broken implementations, a TTL of 1 might actually work better in practice ๐
setting TTL to 0 is going to create more traffic than static addresses would, because name-to-address mappings don't get cached. network-based applications will be required to use names rather than addresses to identify peer nodes, and they must use DNS for every name resolution, since name-to-address mappings can't be shared from previously run applications ๐ฉ
also, NAT gets asked to start a bind-holdout timer right after the assignment. if no session gets started to the private host within the Bind-holdout time period, NAT terminates the temporary binding โฐ
3.3. Outgoing Queries
for Basic and bi-directional NATs, there's no need to tell temporary and committed bindings apart for outgoing queries ๐ธ that's because DNS_ALG doesn't touch DNS packets going to or coming from external name servers (the ones used during outbound sessions), unlike what it does for inbound DNS sessions.
say a private host needs to talk to an external host. the DNS query goes to the internal name server (if there is one) and from there to the right authoritative or cache name server outside the private domain. the reply takes the same route, but neither the query nor the response gets DNS_ALG translations ๐
this won't be the case for address isolated twice NAT private and external domains though ๐ here, NAT intercepts all DNS packets and makes address changes to the payload, just like we talked about in the previous section. temporary private-to-external address bindings get created when responses are sent by private DNS servers, and temporary external-to-private address bindings get created when responses are sent by external DNS servers. โจ
4. DNS payload modifications by DNS-ALG ๐ง
so DNS usually runs over UDP for queries and responses, and over TCP for zone refresh stuff ๐ either way, name servers are reached on the well-known DNS server port 53 (decimal), and every DNS payload follows the same format of data [Ref 4]. NAT handles translating the IP and TCP/UDP headers of a DNS packet, and DNS-ALG handles updating the DNS payload ๐
the header section of the DNS payload is always there, and it has fields that say which of the other sections are present. the header also tells you whether the message is a query or a response ๐ DNS-ALG doesn't need to change anything in the Header section. it only parses DNS payloads whose QCLASS is set to IN (IP class) ๐
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
4.1. Question section ๐
okay so the question section holds QDCOUNT entries (usually 1 ๐), as laid out in the Header section, and each entry looks like this:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4.1.1. PTR type Queries โจ
bestie, this one is a whole vibe. DNS_ALG MUST identify all the names whose FQDNs (that's Fully Qualified Domain Names, babe ๐ซถ) fall under the IN-ADDR.ARPA domain, and swap the reversed address octets sitting in front of "IN-ADDR.ARPA" for the matching assigned ones in reverse order. But it only does this if the address binding is active on the NAT router ๐ฅ.
Now if the address in front of IN-ADDR.ARPA is inside the NAT address map but doesn't even have a temporary address binding, DNS_ALG would basically just respond back (like a DNS name server would) with an RCODE of 5 (REFUSED to respond due to policy reasons ๐). It also sets ANCOUNT, NSCOUNT and ARCOUT to 0 in the header section of that response.
ngl, host-address-to-host-name lookups like this can give you different answers at different times, depending on what the address binding status in NAT is at that moment ๐.
Here's an example. A resolver wants to find the hostname for address 198.76.29.1 from the outside, so it sends a query like:
QTYPE = PTR, QCLASS = IN, QNAME = 1.29.76.198.IN-ADDR.ARPA.
If 198.76.29.1 is internally mapped to the private address 10.0.0.1, DNS_ALG steps in and rewrites the query like this, then forwards it to the DMZ name server inside the private network ๐:
QTYPE = PTR, QCLASS = IN, QNAME = 1.0.0.10.IN-ADDR.ARPA
The DMZ name server is presumably the authoritative name server for the 10.IN-ADDR.ARPA zone, so it'll reply with an RR in the answer section that looks like this. (We'll get to how DNS_ALG translates the response RRs in a later section ๐.)
1.0.0.10.IN-ADDR.ARPA PTR host1.fooboo_org.provider_domain
A real-life example of inverse translation is e-mail programs doing it to trace where spam came from ๐ง. They check whether the address the e-mail was sent from actually belongs to the domain name the sender claims in sender ID. Main character detective energy ๐ต๏ธโโ๏ธโจ.
Query changes like this can change the length of the DNS payload, so the matching IP and TCP/UDP header checksums MUST be updated ๐ฅ. For TCP-based queries, NAT MUST track the sequence number deltas, so it can apply the delta to later sequence numbers going the same direction and to acknowledgement numbers going the opposite direction ๐ฆ. For UDP-based queries, message sizes are capped at 512 bytes (not counting the IP or UDP headers). Anything longer MUST be truncated, and the TC bit SHOULD be set in the header ๐ธ.
Last but not least, any compressed domain names that use pointers for common domain bits MUST be updated with new pointers and the right offset, if NAT had to translate the original domain name ๐ .
4.1.2. A, MX, NS and SOA type Queries ๐
For these queries, DNS_ALG just doesn't touch any of the fields in the query section, not even the name field. Hands off, queen ๐.
4.1.3. AXFR type Queries ๐ง
AXFR is the special zone transfer query type ๐. Zone transfers from a private address realm MUST be avoided for address assignments that aren't static. TCP is the usual transport for AXFR requests.
When a zone changes, those changes MUST be distributed to all name servers ๐ฃ. The usual setup is that one server is the master (or primary) for the zone. Changes get made there, usually by editing a master file. After the edit, the admin tells the master server to load the new zone. The other servers, the non-master or secondary ones, check the SERIAL field of the zone's SOA every so often (at some polling interval) and grab new copies when something has changed ๐.
Zone transfers usually go from primary to backup name servers. When NAT is involved, the primary and backup servers are advised to sit in the same private domain (say, private.zone), so the transfer never crosses the domain and DNS_ALG doesn't have to handle zone transfers at all ๐. If a secondary name server is outside the private domain, zone transfers MUST NOT be permitted for non-static address assignments ๐ซ. Primary and secondary servers are REQUIRED to live inside the same private domain, because every reference to data in the zone has to be captured. With dynamic address assignments and bindings, there's no way to translate the AXFR data so it stays up to date. So if a secondary server for private.zone were outside the domain, it would end up with bad data ๐ญ. Heads up though: this requirement is not in conformance with RFC 2182, which recommends putting primary and secondary servers at topologically and geographically dispersed locations on the Internet ๐.
During zone transfers, DNS_ALG MUST examine all A type records and swap the original address octets for their statically assigned address octets ๐. DNS_ALG could also check whether someone is trying to transfer records for hosts without static addresses, then drop just those records or drop the whole transfer. That helps cut down on misconfiguration and human error ๐ซ .
4.1.4. Dynamic Updates to the DNS. ๐
An authoritative name server can take dynamic updates from nodes inside the zone without NAT or DNS-ALG getting involved, as long as you don't spread a DNS zone across address realms ๐ฆ. We recommend keeping each DNS zone inside the same realm it's responsible for. That way, DNS update traffic never crosses realms, so DNS-ALG never has to think about it ๐งโโ๏ธ.
And if dynamic updates do cross address realms, and they MUST always be secured with DNSSEC, then those updates are clearly out of scope for DNS-ALG (see section 7) ๐.
4.2. Resource records in all other sections ๐
The answer, authority, and additional sections all share the same format, just with a variable number of resource records in each. The number of RRs in each section is in the matching count field of the DNS header. Every resource record looks like this:
The TTL value from the original RRs stays unchanged for static address assignments โจ. For dynamic address assignments, DNS_ALG sets the TTL to 0, so those RRs are only good for the transaction in progress and won't get cached ๐ โโ๏ธ. RFC 2181 requires every RR in an RRset (RRs with the same name, class and type but different RDATA) to share the same TTL. So if one RR's TTL goes to 0, DNS-ALG also sets every other RR in that RRset to 0 too ๐ซถ.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4.2.1. PTR type RRs ๐ฆ
The stuff from the Question section about PTR names applies here too ๐. A private address in front of "IN-ADDR.ARPA" (reversed octet order) MUST be replaced by its external address assignment (also reversed), if a binding exists. Every other field in this RR stays exactly the same ๐.
4.2.2. A type RRs ๐ธ
The RDATA for A records is a 4-byte IP address ๐ข. DNS_ALG just swaps the original address in RDATA for its externally assigned IP address, as long as it finds an address binding. A successful translation SHOULD NOT change the payload length ๐. Only the transport header checksum needs updating. If DNS_ALG can't find an address binding, it has to drop that record and decrement the matching COUNT field in the header section ๐.
4.2.3. CNAME, MX, NS and SOA type RRs ๐งโโ๏ธ
No changes are REQUIRED from DNS_ALG for these RRs, since the RDATA doesn't contain any IP addresses ๐. The host names in the RDATA stay the same across realms. Easy peasy ๐ซง.
5. Illustration of DNS_ALG in conjunction with Bi-directional NAT โจ
okay bestie, this section is a full walkthrough of DNS_ALG doing its thing inside a bi-directional NAT router ๐ we're gonna follow a regular name lookup and a reverse name lookup step by step, and it's giving main character energy ๐ฆ
.
________________ . External.com
( ) .
( ) . +-------------+
+--+ ( Internet )-.---|Border Router|
|__|------ ( ) . +-------------+
/____\ (________________) . |
Root | . |
DNS Server | . ---------------
+---------------+ . | |
|Provider Router| . +--+ +--+
+---------------+ . |__| |__|
| . /____\ /____\
| . DNS Server Host X
External domain | . 171.68.1.1 171.68.10.1
............................|...............................
Private domain |
| Private.com
|
+--------------------------------------+
|Bi-Directional NAT router with DNS_ALG|
| |
| Private addresses: 172.19/16 |
| External addresses: 131.108.1/24 |
+--------------------------------------+
| |
---------- ----------
| | DNS Server
+--+ +--+ Authoritative
|__| |__| for private.com
/____\ /____\
Host A DNS Server
172.19.1.10 172.19.2.1
(Mapped to 131.108.1.8)
Figure 3: DNS-ALG operation in Bi-Directional NAT setup
So this diagram shows a company called private.com ๐ that uses the private address space 172.19/16 and connects to the Internet through bi-directional NAT. DNS_ALG lives inside the NAT device and makes the necessary DNS payload changes โจ The NAT is set up to translate those private addresses into the external address block 131.108.1/24. It also has a static translation for private.com's DNS server, so that server can be reached from the external domain using a valid address ๐ซถ
The company external.com sits in the external domain and uses a registered address block of 171.68/16. The topology also includes a root DNS server ๐
Here are the simplifications made to this configuration:
- private.com is not multihomed, and all traffic to the external space transits a single NAT.
- The DNS server for private.com is authoritative for the private.com domain and points to the root server for all other DNS resolutions. The same is true for the DNS server in external.com.
- The internal name servers for private.com and external.com are the same as their DMZ name servers. The DNS servers for these domains are configured with addresses private to the organization.
- The name resolvers on host nodes do not have recursion available on them and desire recursive service from servers. All name servers are assumed to be able to provide recursive service.
5.1. Outgoing Name-lookup queries
Say Host A in private.com needs to look up Host X in external.com so it can start a session with X ๐ Here's how that goes:
- Host A sends a UDP based name lookup query (A record) for
"X.External.Com"to its local DNS server. - The local DNS server sends the query to the root server en route through the NAT. The NAT changes the IP and UDP headers to reflect the DNS server's statically assigned external address. DNS_ALG makes no changes to the payload.
- The root server then refers the local DNS server to query the DNS server for External.com. This referral transits the NAT en route to the local DNS server. The NAT simply translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address. No changes are made to the payload by DNS_ALG.
- The private.com DNS server now sends the query to the DNS server for external.com, once again en route through the NAT. Just like the query to the root, the NAT router changes the IP and UDP headers to reflect the DNS server's statically assigned external address. And DNS_ALG makes no changes to the payload.
- The DNS server for external.com replies with the IP address
171.68.10.1. This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address. Once again, no changes are made to the payload by DNS_ALG. - The DNS server in private.com replies to Host A.
Once Host A finds the address of Host X, A starts a session with X using the destination IP address 171.68.10.1 โจ This datagram and any others that follow in this session get translated as usual by the NAT ๐ฆ
Note, DNS_ALG does not change the payload for DNS packets in either direction. It's literally hands off ๐
5.2. Reverse name lookups originated from private domain
This scenario builds on the last one ๐
Host A in private.com does a reverse name lookup on 171.68.10.1, which is Host X's global address. Here's the sequence:
- Host A sends a UDP based inverse name lookup query (PTR record) for
"1.10.68.171.IN-ADDR.ARPA."to its local DNS server. - The local DNS server sends the query to the root server en route through the NAT. As before, the NAT changes the IP and UDP headers to reflect the DNS server's statically assigned external address. DNS_ALG makes no changes to the payload.
- The root server then refers the local DNS server to query the DNS server for External.com. This referral transits the NAT en route to the local DNS server. The NAT simply translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address. No changes are made to the payload by DNS_ALG.
- The private.com DNS server now sends the query to the DNS server for external.com, once again en route through the NAT. Just like the query to the root, the NAT router changes the IP and UDP headers to reflect the DNS server's statically assigned external address. And DNS_ALG makes no changes to the payload.
- The DNS server for external.com replies with the host name
"X.External.Com.". This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address. Once again, no changes are made to the payload by DNS_ALG. - The DNS server in private.com replies to Host A.
Note, DNS_ALG does not change the payload in either direction. Still hands off, periodt ๐
5.3. Incoming Name-lookup queries
Now it's flipped ๐ฅ This time Host X in external.com wants to start a session with Host A in private.com. Here's what happens:
- Host X sends a UDP based name lookup query (A record) for
"A.Private.com"to its local DNS server. - The local DNS server in external.com sends the query to the root server.
- The root server then refers the DNS server in external.com to query the DNS server for private.com.
- The external.com DNS server now sends the query to the DNS server for private.com. This query traverses the NAT router. The NAT changes the IP and UDP headers of the packet to reflect the DNS server's private address. DNS_ALG makes no changes to the payload.
- The DNS server for private.com replies with the IP address
172.19.1.10for Host A. This reply also transits the NAT. The NAT translates the IP and UDP headers of the outgoing packet from the DNS server.
DNS_ALG asks the NAT to (a) set up a temporary binding for Host A (172.19.1.10) with an external address, and (b) start the Bind-holdout timer. When the NAT successfully sets up a temporary binding with an external address (say, 131.108.1.12), DNS_ALG modifies the payload to replace A's private address with its externally assigned address, and sets the Cache timeout to 0 โจ
- The server in external.com replies to Host X.
When Host X finds the address of Host A, X starts a session with A using the destination IP address 131.108.1.12 ๐ฆ This datagram and any others that follow in this session get translated as usual by the NAT.
Note, DNS_ALG changes only the response packets from the DNS server for the private domain. Queries are left alone ๐
5.4. Reverse name lookups originated from external domain
This scenario builds on the previous case (section 5.3) ๐ธ Host X in external.com does a reverse name lookup on 131.108.1.12, which is Host A's assigned external address. Here's the sequence of events:
- Host X sends a UDP based inverse name lookup query (PTR record) for
"12.1.108.131.IN-ADDR.ARPA."to its local DNS server. - The local DNS server in external.com sends the query to the root server.
- The root server then refers the local DNS server to query the DNS server for private.com.
- The external.com DNS server now sends the query to the DNS server for private.com. This query traverses the NAT router. The NAT changes the IP and UDP headers to reflect the DNS server's private address.
DNS_ALG asks the NAT for the private address associated with the external address 131.108.1.12, and modifies the payload, replacing 131.108.1.12 with the private address 172.19.1.10 ๐ง
- The DNS server for private.com replies with the host name
"A.Private.Com.". This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address.
Once again, DNS_ALG asks the NAT for the assigned external address associated with the private address 172.19.1.10, and modifies the payload, replacing 172.19.1.10 with the assigned external address 131.108.1.12 ๐
- The DNS server in external.com replies to Host X.
Note, DNS_ALG changes both the query and the response packets from the DNS server for the private domain. This is the one section where it's doing work on both sides ๐
6. Illustration of DNS_ALG in conjunction with Twice-NAT โจ
Okay bestie, this is where things get spicy ๐ถ๏ธ Twice-NAT is the one that translates BOTH sides of the connection. Here's the whole setup, diagram included ๐ฆ
.
________________ . External.com
( ) .
( ) . +-------------+
+--+ ( Internet )-.---|Border Router|
|__|------ ( ) . +-------------+
/____\ (________________) . |
Root | . |
DNS Server | . ---------------
+---------------+ . | |
|Provider Router| . +--+ +--+
+---------------+ . |__| |__|
| . /____\ /____\
| . DNS Server Host X
External domain | . 171.68.1.1 171.68.10.1
............................|...............................
Private domain |
| Private.com
|
+-------------------------------------------+
| Twice-NAT router with DNS_ALG |
| |
| Private addresses: 171.68/16 |
| Assigned External addresses: 131.108.1/24 |
| |
| External addresses: 171.68/16 |
| Assigned Private addresses: 10/8 |
+-------------------------------------------+
| |
---------- ----------
| | DNS Server
+--+ +--+ Authoritative
|__| |__| for private.com
/____\ /____\
Host A DNS Server
171.68.1.10 171.68.2.1
(Mapped to 131.108.1.8)
Figure 4: DNS-ALG operation in Twice-NAT setup
So the vibe here is that the private.com hosts weren't using the RFC 1918 172.19/16 space. They're numbered with the globally-routable 171.68/16 network, which is the exact same block external.com uses ๐ญ That means private.com needs translation for its own host addresses, AND it needs translation whenever those hosts want to exchange datagrams with external.com. Twice-NAT handles the mess by translating the overlapping external.com space into a unique block from RFC 1918 space, which is 10/8. Routes inside the private domain send anything destined for 10/8 through the Twice-NAT device, which then reaches the external global network space ๐ฃ๏ธ
Simplifications and assumptions made in section 5.0 will be valid here as well. Same rules, new drama ๐
6.1. Outgoing Name-lookup queries
Say Host A in private.com needs to look up Host X in external.com (Host X has the FQDN X.external.com) to find its address ๐ Here's how it goes down:
- Host A sends a UDP based name lookup query (A record) for
"X.External.Com"to its local DNS server. - The local DNS server sends the query to the root server on its way through the NAT. The NAT changes the IP and UDP headers to reflect the DNS server's statically assigned external address. DNS_ALG makes no changes to the payload ๐
- The root server then refers the local DNS server to the DNS server for External.com. This referral transits the NAT on its way back to the local DNS server. The NAT simply translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address.
DNS_ALG asks the NAT for an assigned private address for the referral server, and then swaps the external address for that assigned private address in the payload. The plot thickens ๐งฉ
- The private.com DNS server now sends the query to the DNS server for external.com, using its assigned private address, via the NAT. This time the NAT changes the IP and UDP headers to reflect the external addresses of the DNS servers. In other words, the private.com DNS server's IP address is changed to its assigned external address, and the External.Com DNS server's assigned private address is changed to its external address.
DNS_ALG makes no changes to the payload.
- The DNS server for external.com replies with the IP address
171.68.10.1. This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet again, this time to reflect the private addresses of the DNS servers. So the private.com DNS server's IP address is changed to its private address, and the External.Com DNS server's external address is changed to its assigned private address.
DNS_ALG asks the NAT to (a) set up a temporary binding for Host X (171.68.10.1) with a private address and (b) start the Bind-holdout timer. Once the NAT successfully sets up that temporary binding with a private address (say, 10.0.0.254), DNS_ALG modifies the payload to replace X's external address with its assigned private address, and sets the Cache timeout to 0. Iconic behaviour ๐ค
- The DNS server in private.com replies to Host A.
When Host A finds Host X's address, A starts a session with X using the destination IP address 10.0.0.254. That datagram and every one after it in this session get translated as usual by Twice NAT ๐
Note, DNS_ALG has to change the payload in both directions. Two-way payload edits, no cap, it's a lot ๐
6.2. Reverse name lookups originated from private domain
This one builds on the last case. Host A in private.com does a reverse name lookup on 10.0.0.254, which is Host X's assigned private address ๐ Here's the sequence:
- Host A sends a UDP based inverse name lookup query (PTR record) for
"254.0.0.10.IN-ADDR.ARPA."to its local DNS server. - The local DNS server sends the query to the root server on its way through the NAT. As before, the NAT changes the IP and UDP headers to reflect the DNS server's statically assigned external address.
DNS_ALG translates the private assigned address 10.0.0.254 into its external address 171.68.10.1 ๐
- The root server refers the local DNS server to the DNS server for External.com. This referral transits the NAT on its way back to the local DNS server. The NAT simply translates the IP and UDP headers of the incoming packet to reflect the DNS server's private address.
Just like with the original query, DNS_ALG translates the private assigned address 10.0.0.254 into its external address 171.68.10.1. On top of that, DNS_ALG replaces the external address of the referral server (that is, the DNS server for External.com) with its assigned private address in the payload.
- The private.com DNS server now sends the query to the DNS server for external.com, using its statically assigned private address, via the NAT. This time the NAT changes the IP and UDP headers to reflect the external addresses of the DNS servers. The private.com DNS server's IP address is changed to its assigned external address, and the External.Com DNS server's assigned private address is changed to its external address.
Just like with the original query, DNS_ALG translates the private assigned address 10.0.0.254 into its external address 171.68.10.1.
- The DNS server for external.com replies with the FQDN
"X.External.Com.". This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet again, reflecting the private addresses of the DNS servers. So the private.com DNS server's IP address is changed to its private address, and the External.Com DNS server's external address is changed to its assigned private address.
Once again, DNS_ALG translates the query section, replacing the external address 171.68.10.1 with its assigned private address 10.0.0.254 ๐ช
- The DNS server in private.com replies to Host A.
Note, DNS_ALG has to change the payload in both directions. We're really doing this twice, periodt ๐
6.3. Incoming Name-lookup queries
This time, Host X in external.com wants to start a session with Host A in private.com. Here's what happens, in order:
- Host X sends a UDP based name lookup query (A record) for
"A.Private.com"to its local DNS server. - The local DNS server in External.com sends the query to the root server.
- The root server refers the DNS server in External.com to query the DNS server for private.com.
- The External.com DNS server now sends the query to the DNS server for Private.com. This query traverses the NAT router. The NAT changes the IP and UDP headers to reflect the private addresses of the DNS servers. So the Private.com DNS server's IP address is changed to its private address, and the External.Com DNS server's external address is changed to its assigned private address.
DNS_ALG makes no changes to the payload ๐ธ
- The DNS server for Private.com replies with the IP address
171.68.1.10for Host A. This reply also transits the NAT. The NAT translates the IP and UDP headers of the incoming packet again, reflecting the external addresses of the DNS servers. So the Private.com DNS server's IP address is changed to its assigned external address, and the External.Com DNS server's assigned private address is changed to its external address.
DNS_ALG asks the NAT to (a) set up a temporary binding for Host A (171.68.1.10) with an external address and (b) start the Bind-holdout timer. When the NAT succeeds in finding an external address (say, 131.108.1.12) to temporarily bind to Host A, DNS_ALG modifies the payload to replace A's private address with its assigned external address, and sets the Cache timeout to 0. The glow-up is real โจ
- The server in External.com replies to Host X.
When Host X finds Host A's address, X starts a session with A using the destination IP address 131.108.1.12. That datagram and any others that follow in this session get translated as usual by the NAT ๐ฆ
Note, DNS_ALG changes only the response packets from the DNS server for the Private domain. Only the replies get the makeover, the queries are left alone ๐
6.4. Reverse name lookups originated from external domain ๐
okay so this one builds on the last scenario (section 6.3) ๐ host X over in External.com wants to do a reverse name lookup on 131.108.1.12, which is host A's assigned external address. here's how it goes down:
- Host X sends a UDP based inverse name lookup query (PTR record) for
"12.1.108.131.IN-ADDR.ARPA."to its local DNS server. ๐ฉ - The local DNS server in External.com sends the query to the root server. ๐ณ
- The root server refers the local DNS server to query the DNS server for Private.com. ๐
- The External.com DNS server now sends the query to the DNS server for Private.com. this query goes through the NAT router, and NAT changes the IP and UDP headers so they show the private addresses of the DNS servers. so the Private.com DNS server's IP address gets changed to its private address, and the External.Com DNS server's external address gets changed to the assigned Private address. ๐
DNS_ALG asks NAT for the private address that goes with the external address of 131.108.1.12, then edits the payload and swaps 131.108.1.12 for the private address of 171.68.1.10. โจ
- The DNS server for Private.com replies with the host name
"A.Private.Com.". this reply also goes through the NAT, which translates the IP and UDP headers of the incoming packet again so they show the external addresses of the DNS servers. so the Private.com DNS server's IP address gets changed to its assigned external address, and the External.Com DNS server's assigned private address gets changed to its external address. ๐ซ
Once more, DNS_ALG asks NAT for the assigned external address that goes with the private address of 172.19.1.10, then edits the payload and swaps 171.68.1.10 for the assigned external address of 131.108.1.12. ๐ฆ
- The DNS server in External.com replies to host X. ๐
Note, DNS_ALG changes the query packets as well as the response packets from the DNS server for the Private domain. it's doing the most ๐
7. DNS-ALG limitations and Future Work ๐ง
ngl this part is where things get a little messy ๐ NAT makes mis-addressing more likely. like, the same local address might get bound to different public addresses at different times, and the other way around too. so hosts that cache the name to address mapping for longer than the NAT router is set up to hold the mapping are likely to misaddress their sessions. but real talk, this is mainly a problem with bad host implementations that keep DNS records past what the TTL says they're good for, and it isn't really caused by the mechanism described here. ๐ค
DNS_ALG cannot support secure DNS name servers in the private domain. ๐ญ like, signed replies from an authoritative DNS name server in the DMZ to queries coming from the external world will get broken by the DNS-ALG. at best, DNS-ALG can turn secure dnssec data into unprotected data. end-nodes that demand signed DNS replies may reject replies that DNS_ALG has tampered with. and since the DNS server has no way to tell where a query came from (internal or external), it will most likely have to fall back to the common denominator of today's insecure DNS. both of these are serious limitations for DNS_ALG. zone transfers between DNS-SEC servers are hit the same way if the transfer crosses address realms. ๐
the good news is that only end-nodes in the DMZ pay the price for the limitation above in a traditional NAT (or a bi-directional NAT), since external end-nodes may not access internal hosts because the DNS replies aren't secure. ๐ซถ however, for outgoing sessions (from the private network) in a bi-directional NAT setup, the DNS queries can be signed and securely accepted by the DMZ and other internal hosts, since DNS_ALG doesn't intercept outgoing DNS queries and incoming replies. and lastly, zone transfers between DNS-SEC servers within the same private network are not impacted. โจ
clearly, once DNS SEC is deployed on DNS servers and end-host resolvers, the scheme suggested in this document will not work. ๐ฅ
8. Security Considerations ๐
this section is serious, bestie, so pay attention ๐ If DNS packets are encrypted/authenticated per DNSSEC, then DNS_ALG will fail because it won't be able to perform payload modifications. ๐จ Alternately, if packets must be preserved in an address realm, DNS_ALG will need to hold the secret key to decrypt/verify the payload before forwarding packets to a different realm. for example, if DNS-ALG, NAT and an IPsec gateway (providing secure tunneling service) all live on the same device, then DNS-ALG will have access to the IPsec security association keys. ๐ the section right before this one, "DNS-ALG limitations and Future Work," covers the DNS_ALG security considerations too, so go check it out ๐
also, with DNS-ALG there's a possibility of a denial of service attack from a malicious user, as outlined in section 3.1. section 3.1 suggests some ways to counter this attack. ๐ก๏ธ
REFERENCES ๐
- [1] Srisuresh, P. and M. Holdrege, "IP Network Address Translator (NAT) Terminology and Considerations", RFC 2663, August 1999.
- [2] Egevang, K. and P. Francis, "The IP Network Address Translator (NAT)", RFC 1631, May 1994.
- [3] Rekhter, Y., Moskowitz, B., Karrenberg, D., de Groot, G. and E. Lear, "Address Allocation for Private Internets", BCP 5, RFC 1918, February 1996.
- [4] Mockapetris, P., "Domain Names - Concepts and Facilities", STD 13, RFC 1034, November 1987.
- [5] Mockapetris, P., "Domain Names - Implementation and Specification", STD 13, RFC 1035, November 1987.
- [6] Reynolds J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700, October 1994.
- [7] Braden, R., "Requirements for Internet Hosts -- Communication Layers", STD 3, RFC 1122, October 1989.
- [8] Braden, R., "Requirements for Internet Hosts -- Application and Support", STD 3, RFC 1123, October 1989.
- [9] Baker, F., "Requirements for IP Version 4 Routers", RFC 1812, June 1995.
- [10] Carpenter, B., Crowcroft, J. and Y. Rekhter, "IPv4 Address Behaviour Today", RFC 2101, February 1997.
- [11] Eastlake, D., "Domain Name System Security Extensions", RFC 2535, March 1999.
- [12] Vixie, P., Thompson, S., Rekhter Y. and J. Bound, "Dynamic Updates in the Domain Name System (DNS UPDATE)", RFC 2136, April 1997.
- [13] Eastlake, D., "Secure Domain Name System Dynamic Update", RFC 2137, April 1997.
- [14] Elz R. and R. Bush, "Clarifications to the DNS specification", RFC 2181, July 1997.
- [15] Elz, R., R. Bush, Bradner S. and M. Patton, "Selection and Operation of Secondary DNS Servers", RFC 2182, July 1997.
Authors' Addresses ๐
these are the people who made this happen, so here they are, exactly as written ๐
Pyda Srisuresh
849 Erie Circle
Milpitas, CA 95035
U.S.A.
Phone: +1 (408) 263-7527
EMail: srisuresh@yahoo.com
George Tsirtsis
Internet Transport Group
B29 Room 129
BT Laboratories
Martlesham Heath
IPSWICH
Suffolk IP5 3RE
England
Phone: +44 1473 640756
Fax: +44 1473 640709
EMail: george@gideon.bt.co.uk
Praveen Akkiraju
cisco Systems
170 West Tasman Drive
San Jose, CA 95134 USA
Phone: +1 (408) 526-5066
EMail: spa@cisco.com
Andy Heffernan
Juniper Networks, Inc.
385 Ravensdale Drive.
Mountain View, CA 94043 USA
Phone: +1 (650) 526-8037
Fax: +1 (650) 526-8001
EMail: ahh@juniper.net
Full Copyright Statement โ๏ธ
the legal bits stay word for word, no vibes changed here ๐
Copyright (C) The Internet Society (1999). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement ๐
funding for the RFC Editor function is currently provided by the Internet Society. thank you, Internet Society, you're iconic ๐
๐ฆ where this page comes from
- ietf: rfc2694 1999-09
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms