NAT does not work in all cases. The following subsections document some of the instances where NAT will not work as expected.
The main components that NAT changes are the IP addresses in the TCP/IP headers and possibly the TCP or UDP ports. This works for some applications, but many applications embed IP addresses in the data portion of the packet (e.g., Microsoft Networking[5]) or expect packets to come from a particular source port (e.g., IKE negotiations for IPSec). In these cases, NAT has to act somewhat like an application proxy in that it must understand the underlying protocol and make intelligent changes to the packets so that the protocol will work despite undergoing NAT.
[5] Microsoft used to say that Microsoft Networking was incompatible with NAT and that NAT, if present in your network, should be removed. It would not surprise me if the company still stood by this claim.
FireWall-1 understands certain protocols like FTP, RealAudio, and Microsoft Networking (if support is specifically enabled). There are plenty of applications that do not work correctly with FireWall-1's NAT, not necessarily because it is impossible to make them work but because Check Point has not added support for them. However, some protocols are simply impossible to make work with NAT. Any protocol that uses IP datagram types other than TCP or UDP often fails when NAT is applied. In fact, Check Point does not NAT packets that aren't TCP, UDP, or ICMP. Protocols that validate the IP packet headers between source and destination (such as the Authentication Header mechanism of IPSec) will not work with NAT. To a protocol that protects network traffic from man-in-the-middle attacks?attacks where the headers or payload changes in transit?NAT looks like a hacker. The bottom line: NAT breaks end-to-end connectivity and should be employed only in instances where you can live with the limitations.
NAT is problematic in situations where the firewall is not placed between both the source and the destination. Using the example in the previous step-by-step configuration (see Figure 10.3), consider the situation where a host on segment B (10.0.11.69) tries to access the intranet Web server via the translated IP address (192.168.0.13). The host 10.0.11.69 tries to initiate a connection to 192.168.0.13. Routing will eventually take this packet to the firewall. The packet is accepted by the firewall's security policy and is then processed by NAT. The first NAT rule that matches the packet is Rule 3, which translates the destination of the packet from 192.168.0.13 to 10.0.10.80. The "source" of the packet is not changed (the rule says not to touch it). The packet is then routed back to 10.0.10.80 via 10.0.0.2.
When 10.0.10.80 sends its reply, it is sent to 10.0.11.69 (the "source" of the connection attempt). The reply is routed to 10.0.10.2 and then directly to 10.0.11.69. The host 10.0.11.69 expects replies from 192.168.0.13 (which it tries to connect to), not 10.0.10.80, so the reply packets are ignored.
What would happen if the rule hid 10.0.11.0/24 behind the firewall's external IP address? When 10.0.11.69 tried to access 10.0.10.80, the packet would get routed to the firewall and passed through the rulebase. NAT then would rewrite the source of the packet to be 192.168.0.2. The destination of the packet would still be 192.168.0.13 (i.e., it would not get translated), but it would get routed out the internal interface. The Internet router would see this packet and route it back to the firewall (it is an external address, after all). The packet would ping-pong back and forth until the packet's time to live (TTL) value expired.
One reason you might connect to the translated IP address is because your internal client's DNS server resolves the host's name to the external address. You can solve this problem by implementing split-horizon DNS, that is, maintaining an internal version of your DNS and an external version of your DNS, typically on separate servers. The external DNS is accessible from the Internet and contains only a subset of names and addresses contained in the internal DNS server. An internal DNS contains all the names used internally and reflects the internal IP address for a host. The external DNS server reflects the externally resolvable IP addresses for the host.
Other than implementing split-horizon DNS, can you get around this problem? Yes, there are two tricks you can use, which are documented in the following subsections. However, it is highly recommended that you not place yourself in a position where you have to use these tricks.
FireWall-1 allows you to translate both the source and destination IP address at once. It is simply a matter of crafting the correct rules and placing them in the right order. In the preceding case, if you want to allow your internal network to access the internal host via its translated IP address, modify your NAT rules so they read as shown in Figure 10.6. The two rules that were added to the rulebase shown earlier in Figure 10.5 are shown with white backgrounds in Figure 10.6 and will hide the source address behind the firewall's IP address and modify the destination IP to be the web-intranet address.
In this particular case, there is another issue to contend with: ICMP Redirects. Because the firewall will be routing a packet out the same interface from which it was received, the system sends the client an ICMP Redirect, giving it a more direct route to the host. Depending on the exact circumstances, the ICMP Redirect will cause the connection either to never take place or to take a long time to establish because the client will be trying to communicate directly to a host using an IP address it knows nothing about. There are a few ways around this situation.
Bind the translated IP address to the server's loopback interface. See the next subsection for details.
Block ICMP Redirects. You can block outgoing ICMP Redirects in FireWall-1 with the FireWall-1 rule shown in Figure 10.7.
On some operating systems, there is an option to disable sending ICMP Redirects. On Solaris, you do this by typing:
# /usr/sbin/ndd -set /dev/ip ip_send_redirects 0
On a Nokia platform, you can do this on a per-interface basis by typing:
# ipsctl -w interface:<phys-if>:family:inet:flags:icmp_no_rdir 1
where you replace <phys-if> with the physical interface name (e.g., eth-s1p1).
NOTE!
By default, ICMP Redirects[6] are not enabled on any interface running VRRP. This is highly recommended in a VRRP configuration because it limits the possibility that your machine's physical address is propagated.
|
Assuming this trick works, a side effect can occur, which makes traffic traverse your network twice: once to the firewall and once to the server. This could add to an already congested network.
The basic idea is to bind the translated IP address to the loopback interface of the server. On Windows NT, you need to add the MS Loopback interface (a software-only network adaptor) and add the IP address to this interface with a netmask of 255.255.255.255. In IPSO, you can simply add an IP address to the loop0c0 interface via Voyager. On UNIX machines, use a command such as the following:
# ifconfig lo0:0 204.32.38.25 up
If packets come into the system for the translated IP address (because, for instance, they did not come to the firewall), the system will respond to packets for this IP address. This method does require slightly more administration because you must also maintain the NAT on the individual servers.