Network Address Translation: an abomination and horror
IPv4 addresses are not so many. When Internet started a long time ago, 2³² addresses (more than 4 billion) seemed to be a lot. Today the IANA (the organization which administrate addresses and “numbers” of the Internet) have already completed the assignment of all IPv4 address blocks to all “regional” authorities of several parts of the planet.
For this and other reasons we are now inside a migration process to the new IPv6 protocol, which provide 128-bit addresses. A lot of estimations shown that this new kind of addresses will be enough for a lot of time, even we will use them in a very “bad way”.
The migration process already started officially in 2008 and will go ahead for several years. We are already using a lot of migration techniques on several networks (which provide both IPv4 and IPv6 connectivity). Since June 2011, Facebook, Google and several “bigs” of the Internet, started offering IPv6 services to all customers around the world. As today, the “T-Mobile” mobile operator in the US is providing IPv6 connectivity to every mobile phone customer.
Actually this lack of IPv4 addresses was already predicted and known during the 90′, when the NAT (Network Address Translation) was created on purpose of “temporarily” solve the problem. This “temporarily” has been very long, because we still use it today and more than ever.
But, first of all, let me clarify some definitions. Plain “NAT” means the translation of public IPv4 prefix, into a “private” IPv4 prefix and vice-versa (where “private” = prefix part of the private blocks specified in RFC1918). This means that we do a one-to-one association between public and private addresses. For each public address we associate a private address.
For example, let’s suppose that we have a router with two interfaces, one to the Internet and one to a local LAN network which uses private IPv4 addresses.
Let’s also suppose we have 10 computers on the LAN and 10 public IP address available for Internet use. The plain NAT means that we could use 10 private addresses on the computers on the LAN and program the router in a way that, for each incoming IPv4 packet it will change the destination IP address with a private address and vice-versa, based on a association table. This permits to easily change public IP addresses of all machines (for example when we change ISP provider).
But this “plain NAT” is quite never used today. What I want to talk about is the NAPT (Network Address and Port Translation) , which is often called just “NAT”, giving origin to this ambiguity.
The NAPT works in this way: let’s suppose we have again a local network and a router as before, but we just have one public IPv4 address and 10 computers on the local network. How can we connect all computers to the Internet? So first let’s do a step back and let’s see in a very easy way how a connection works.
Every computer wants to send/receive TCP and UDP packets. Each TCP or UDP packets, can be identified by two “port” numbers, a source port and a destination port. The source port is an identifier to understand from which application of the host from which the packet came, while the destination port is an identifier of the application to connect on the destination host. The destination host will swap destination and source port numbers in order to send back responses.
So, we will use private IP addresses as before on the local network and we will keep the public IP address on the router. The router will use the NAPT, so when an initial packet come from the local network, the router will check the source port of the TCP packet and it will check the free source port numbers on its public IPv4 address. The router will then choose a free source port for its address and will note in a table: “the local network host with address x.y.z.w has established a connection to a remote host k.h.j.l and all packets coming from x.y.z.w with source port X must be rewritten with my source port Y and my public address as source”. In a similar way it will read on reverse-way the previous route when a packet comes from the Internet. When a packet comes from the Internet, the router will check if the destination address is its public IP, if so it will then check the destination port and see if that port is used for some NAPT mapping. If the port is part of a NAPT mapping rule, it will find the row in the table, change the destination port y with the previously changed port X and the destination address with the private address x.y.z.w of the LAN host. All this could be also be deployed using more than one public address on the router, in order to increase the number of parallel connections (we will see that later).
Even if this system allows you to “solve” the IPv4 exhaustion problem, a lot of network administrators and people in the Internet community think that this is really an abomination and horror for TCP/IP network protocol suite. In the following I will explain to you why I agree with them:
10 Reasons for which NAPT (NAT) should not be used:
- NAPT goes against the most important rule about protocol layering, which says that a protocol of level k should not make any assumption about protocols of level k+1. A router should just take IP packets coming and route them using a routing table. Instead, by using NAPT, the router also has to check the IP packet payload (the TCP/UDP protocol header) in order to check port numbers. This should not be done according to the layering rule and it also cause a not expected overhead on a embedded device which should just forward packets but also starts to trace all TCP/UDP connections going over.
- NAPT is against the hierarchical model of IP, which says that any host connected to the Internet is identified globally in unique way by an IP address. In some cases this could be a good thing for our anonymity, but surely it is not a warranty that we could not be traced anyway in several other ways.
- Internet applications should not be forced to use TCP and UDP. If a user behind a NAT chooses to use a different (layer 4) transport protocol, he will not be able to use it, because NAPT works only on TCP and UDP checking port numbers. On some transport protocol there are no port numbers. ICMP for example, the control protocol for IP workings and network diagnostics, does not use port numbers but it’s necessary anyway. For this reason NAPT routers employ several workarounds in order to send/receive ICMP packets correctly (watching other numbers inside the ICMP packets). This is obviously other “hard” work for the router. We should not forget that each time that we add something to do on the router side, the workload for each packet increase and some network lines could slowly increase latency and congestions.
This means that manufacturers will need powerful hardware and so higher costs (and energy consumption). I understand that this is a bit exaggerated view of the problem, but if we have really a lot of traffic (and not just 10 computers), we should start to consider also these problems.
- With NAPT, the router has to re-compute the IP and TCP/UDP/ICMP checksums. The IPv4 header contains a checksum of itself. Since we change IP address in the header in order to perform NAPT, we have to recalculate this checksum. TCP also have a checksum, which is calculated using the source and destination address of the IP header. The UDP checksum is not usually enabled, but ICMP also has a checksum. This is not a big problem, but if we have to NAPT a large network we will have a lot of overhead in order to process so many checksum operations at wire-speed, so we will again need more powerful hardware.
- Handling IP fragments is hard! TCP/UDP port numbers are present only in the initial header of the transport-level frame. If a TCP/UDP packet gets fragmented on the path, the NAPT router will need to keep track of fragment numbers. If two transmitters choose the same Fragment Identifier, the router might not be able to understand which is the correct translation for the packet (it has two possible translations). It’s a quite rare case but it is still possible.
- The parallel number of concurrent connections decrease. This is because the NAPT router should use one of its free source TCP/UDP ports for each connection. Since the available ports are 2^16 (actually the first 4096 should not be used for NAPT), we can’t have more than 65535 connections for each public IP address used by the NAPT router. You could think that it’s a big number, but if we use just one IP address for the network of a small company or a university campus (and maybe someone is doing port-scanning or other bad things), the router will exhaust port numbers and the network will not accept new connections. If we have 100 computers behind the NAPT, each one could do only about 655 concurrent connections. Try to open a p2p software on some of them and see what happens.
So for this reasons, manly on corporate networks, we use more than one public IPv4 address: we use a pool of IPv4 public addresses, in order to have more parallel connections available. So at this point, was it really necessary to use NAPT if we had other public addresses? Maybe for a university campus the answer would be “yes”, but for a small office could be “no”.
- NAPT transforms the Internet from a connectionless network, to a connection-oriented network. The NAPT router must keep track of all information related to a connection going over it. So, if a NAPT router goes down and its NAPT mapping table goes away, all TCP/UDP/ICMP connection will not be able to continue when the router comes back online. Instead, without NAPT, when a router goes down and then up, the endpoints using a TCP connection will see just a short lag (router’s reboot time) in communication. UDP also has problems: let’s say for example that we are doing a VoIP call when someone reboots the router. VoIP usually works over RTP protocol (which runs over UDP). If we are using a normal router we will just have a short silence in communication, then the audio will come back. Instead, when behind the NAPT, the VoIP call will be lost and we should call back again. I know, it’s not a so common scenario, but it shows how much NAPT is evil.
- Usually each host connected to the Internet is able to connect to some servers or expose some services on the network, so that other people could connect. Sadly, using the NAPT we can’t get incoming connections to our host. You could say that it is possible to configure the NAPT router to forward some ports. So let’s say I have two hosts on the LAN who want to expose a HTTP webserver (TCP port 80). We just have 1 public IP address and we can use the TCP port 80 just once. How could we provide access to more than one of the two hosts? We will be forced to use a non-standard port on the other host. I think that (also) because of the NAPT, the Internet is becoming everyday more a “download-only” network. This might be a more philosophical problem instead of a technical one, but I think that the good side of the Internet (since its first days of existence) is the possibility for anyone to expose to anyone else a self-hosted service, in any point on the world, without the need to ask to a third-party to do that.
- A lot of application-level protocols (DCC and FTP in active mode for example) use IP addresses of hosts inside application-level messages (to notice the server where to send some data). The NAPT doesn’t know anything about this and the result is that these protocols don’t work anymore today. On some routers there are some deep packet inspection systems (Application Level Gateway) which are able to recognize these application messages and alter them while opening ports in the NAPT mapping, in order to provide some form of “retro-compatibility” (a lot of NAPT routers do that for FTP active mode for example). I think this is even worse of what we were talking before. Now the router doesn’t just have to check for layer-4 messages, but even layer-7 messages! Rebuilding TCP packets to search for a byte sequence it’s not a fast/easy thing to do for a router, it adds a lot of overhead. If you aren’t still convinced about this problem maybe you should read the workarounds that IPsec creators made for using IPsec over NAPT. IPsec can sign or ecrypt the payload of IP packets in order to make them secure and with reliable source. IPsec, in order to add this feature, sign all the IP payload. This is a problem because some fields which should be fixed (port numbers) are changed by the NAPT and the sign check fail. Also, if the packet is encrypted, the NAPT can’t read port numbers!
- The NAPT doesn’t let you able to keep open idle connections. Can be sometimes useful to keep an open connection where no data is exchanged for hours or weeks (let’s think about today’s popular websockets or IMAP with IDLE command). TCP/IP supports this feature without problems since the connection state is kept just by endpoints. The NAPT has few free port numbers to use, so it can’t just keep them allocated forever (for connections bad-closed and DoS attacks to the NAPT). For these reasons, the NAPT closes some connections when are not “active” and reallocate port numbers for new connections. The worst thing about this is that (on some NAPT implementations), the two hosts involed don’t receive any notification of this “disconnection” by the NAPT, so they still assume to be connected even if they aren’t, and they will discover that just when trying to send something to the other host.
On the other hand, without NAPT, we could shutdown the router, change communication lines, change the way we connect to the router, put the host in standby, cut ethernet cables, reconnect and wait. We could do whatever we want. When we will be back online, if the addresses of the endpoints have not been changed, we are still “connected” to the other host and we are still able to send data on the same connection, thanks to TCP/IP.
Someone could ask “so how can I keep open idle connections over NAPT?”, there are many answers, maybe the most popular is to use something like “ping/pong” messages like IRC does sometimes. Another answer could be to use a workaround called “TCP-Keepalive” which sends some empty TCP packets sometimes inside a TCP connection in order to show to the NAPT that we are active and that it should not delete the mapping rule.
The NAT is not a firewall
A lot of people think that the NAPT, for how it works, could be used (improperly) as a firewall technique. Let’s imagine, for example, a university campus network. We don’t want students to turn on SMTP servers in order to start spamming or other stuff like that. How could we prevent this? Some people say “let’s turn on a NAPT so they can just connect outside”. This could work but it is not the purpose of NAPT and I consider it a bad idea, in particular on small networks where we have public addresses for everyone. The purpose of NAPT is not that. It’s always possible to use a stateful firewall on the router or a separate machine, in order to prevent LAN hosts to expose services to the Internet.
Some people says that NAPT protects them from network attacks. Really?
- On some NAPT cheap routers it can happen that, for several reasons, the WAN and LAN interface are actually on the same physical card, so if you send a packet to the WAN interface, it will go inside the LAN too.
- Some router have “modules” in order to get FTP active mode and DCC protocols working (as we stated before). This is good but it also gives you security issues. By using some special attack techniques it’s possible for an attacker to use this mechanism in order to open an arbitrary port on the NAPT to an arbitrary host in the local network. For example, by using a special webpage with a java or flash application (see for example here)
- Some local networks implement the UPnP protocol on the main router (using the so called “IGD” service). By using the IGD service, an host on the local network could ask to the router to add a port-mapping rule in order to get incoming connections from outside. It turns out that some routers accept this kind of requests also from the WAN interface (see this paper)
Other bad things
Did you know? Some ISP providers started to give you private addresses instead of public ones. This is called Carrier-Grade NAT and it’s still bad because it again breaks the end-to-end connectivity and you also don’t have any control to open up a port, since the NAT is performed on the carrier’s network.
Archiviato in:diario, informatica | Leave a Comment
Tag:disgust, horror, internat, ipv4, napt, nat, network address translation, security