Translation(s): English - ?Русский


Contents

This page is intended to describe some of the issues encountered when you use NAT to map a public IP address to a private address used internally.

One common example of this is a user who uses a Firewall system to map some ports on their public IP address through to the internal servers, in the 192.168.0.0/16 range, that actually offer those services.

For this example we will use the following setup:

  Internet IP Address: 1.2.3.4
  Internal Network:    192.168.1.0/24
  Router/Firewall:     192.168.1.1
  Web Server:          192.168.1.10
  Client Machine:      192.168.1.200

The desired behavior is to have the web server, on 192.168.1.10, available to the Internet when accessed via 1.2.3.4:80

Also, the domain name 'www.example.com' is correctly set up to map to 1.2.3.4

Using standard DNAT on the Firewall machine, Internet hosts are able to connect to the web server and everything works as expected, using both the public IP address and the domain name.

The problems start when the client machine, 192.168.1.200, tries to connect to http://www.example.com/.

This connection attempt will not succeed - rather, it times out after spending a while in SYN_SENT.

This problem is caused by the nature of a NAT device: all packets must pass through the NAT device in both directions for the address translation to be effective.

Unfortunately, in the case described above this is not true: the web server will send the response packets back to the client machine directly. These packets, of course, have not had the reverse DNAT operation applied, so they are not recognised by the client machine as valid.

There are two main methods for resolving this problem:

1. Talk to the right IP address. 2. Force all packets to go back through the firewall machine.

The first option, talking to the right IP address, is the most efficient path. It involves only the two machines, client and server, talking to each other.

To achieve this you can take several paths:

a. Add entries to the '/etc/hosts' file on the client machines that map the internal IP of the web server to the domain name:

    192.168.1.10    www.example.com

b. Use dnsmasq in the router, along with/as your DHCP server. Works nicely. Install it to serve dns requests only from internal machines, (not internet facing). Edit /etc/hosts (or a separate file) on the router to give 192.168.1.10 for all of the fqdn's of the server. Either make a DNAT rule for dns queries to redirect to dnsmasq, eg iptables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT or using dhcp specify the dnsmasq machine as primary dns server, or manually change everybody's dns settings to point to the router. (This is where dhcp and static assignments comes in very handy) This leaves just one place to enter fqdn numbers..

c. Use a second DNS server, or a server with "split" views such as bind9.

This is the nicest option, as it allows you to use standard servers and protocols, and ensures that you don't end up having to modify every host when you renumber the network or change the web server.

The other path you can take is to force the packets back through the router.

This is done by implementing two NAT rules:

    any packet to 1.2.3.4:80  set destination to 192.168.1.10
    any packet from 192.168.1.0/24 to 1.2.3.4:80 set source to 192.168.1.1

The second SNAT will pretend that the packets came from the router rather than an internal host. The web server will then send the responses back to the firewall. The firewall then undoes both NAT operations and sends the response to the client.

All packets then go through this path. This works, but involves the firewall in all of the traffic.