|
Size: 5603
Comment:
|
Size: 3763
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 2: | Line 2: |
| This page is inteded to help ppl with a DNAT from a 192 from another 192 address that needs to be redirected instead. Were only talking about ONE interface, the internal one. For the topic disscused the ""external"" interface might also be the internal one, I.E. using the same 192 IP. | 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. |
| Line 4: | Line 4: |
| THE SETUP: A router with local ip 192.168.1.1 and internet ip x.y.z.p Several clients on the 192 network(hosts 100 and up). An fqdn DNS pointing too x.y.z.p and at least one ["DNATed"] server with a real IP of 192.168.1.10 |
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. |
| Line 9: | Line 6: |
| THE PROBLEM: Host 192.168.1.100 gets an fqdn DNS as x.y.z.p and fails to connect, YES a BUG. The bug that the rest of this document will explain and offer several good solutions. |
|
| Line 12: | Line 7: |
| THE SOLUTIONS: | 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 }}} |
| Line 14: | Line 16: |
| 1. Use a separate DNS to point 192 clients to the correct 192 address. This is the (IMHO) BEST but also, thankfully, was the HARDEST (until dnsmasq came along). |
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 |
| Line 18: | Line 18: |
| 1a. Use 'hosts' files on all the clients. Add the 192.168.1.10 ip number against all fqdn's used by the server, in /etc/hosts or lmhosts.sam file on each internal client and server. | Also, the domain name 'www.example.com' is correctly set up to map to 1.2.3.4 |
| Line 20: | Line 20: |
| 1b. 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. | 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. |
| Line 27: | Line 54: |
| 1c. Use another DNS server for just your internal clients. There can be only one domain, even if there is only one changed record, so you will have to duplicate all the DNS records. One problem you will run into is that client's can't have a backup DNS server, unless you setup more than one internal DNS server. To combat this and other problems* I always run a DNS server/cache on every host. For this dnsmasq is small, so it won't hurt your clients much, and is easy to setup. | c. Use a second DNS server, or a server with "split" views such as bind9. |
| Line 29: | Line 56: |
| * GetHostBy""Ip"" is a blocking function call used by most servers(telnet, ssh, smtp, pop3, imap, http, ect) that will BLOCK for 60 seconds if your nameserver(s) are down. THIS IS NOT A BUG IT'S A GOOD DESIGN. The end result is Names vs ["IPs"] in the logs and is needed for hosts.deny and the like. | 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. |
| Line 31: | Line 58: |
| 2. Use a SNAT to 192.168.1.1 for data from from 192.168.1.0/24 eg on the router iptables -t nat -A POSTROUTING -o eth1 -d 192.168.1.10 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1 iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.10 -j SNAT --to-source x.y.z.p so every reply is forced back to the router to de-SNAT correctly. The server sees 192.168.1.1 & the clients see x.y.z.p |
|
| Line 37: | Line 59: |
| 3. Place all servers and clients on different subnets. | |
| Line 39: | Line 60: |
| 3a. Change the server IP to a different subnet and add a virtual ip on the router for it's gateway address. This sends ALL traffic through the router, so isn't practical if the server has a large amount of local traffic from other services. If you want to pass packets directly, make a static arp entry in each client. |
The other path you can take is to force the packets back through the router. |
| Line 42: | Line 62: |
| 3b. Add a virtual ip to the server (192.168.2.10 eth0:1) and a matching virtual ip address on the router (192.168.2.1 eth1:1) for it's gateway. Change the router's DNAT to the second server address and add iproute2 definitions to force replies back out the same incoming interface. eg echo "300 router" >> /etc/iproute2/rt_tables (or wherever the tables file is) ip route add 192.168.2.0/24 dev eth0:1 src 192.168.2.10 table router ip route add default via 192.168.2.1 table router ip route add 192.168.2.0/24 dev eth1 src 192.168.2.10 ip rule add from 192.168.2.10 table router This makes sure replies to 192.168.1.0/24 go back to the router on the 2nd card rather than be routed directly. Add an outgoing SNAT on the router to fake the x.y.z.p address, eg iptables -t nat -A POSTROUTING -o eth1 -s 192.168.2.10 -j SNAT --to-source x.y.z.p |
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 }}} |
| Line 51: | Line 68: |
| 3c. Use a second set of nic cards for clients and servers. This is good for HA/mission-critical servers as they don't have to compete with clients for the router's incoming(can not be shaped) bandwith. You must still use routing rules as in 3b to pass the replies back out the incoming interface to avoid local delivery. | 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. |
| Line 53: | Line 70: |
| 4. Route the server(192.168.1.10) to 192.168.1.1/32 instead of 192.168.1.0/24. This is more difficult than 2 and doesn't really gain a whole lot. You lose local connectivity and broadcasts. 5. Add a proxy in the network. Use mod_proxy or mod_rewrite etc or ["ACLs"] to pull files from 192.168.1.10 and serve from the proxy. It's a huge cpu and disk drain however if it's installed on the router, (and a security risk too). THE DON'T WORK: 1. Never use a non-statefull DNAT(only for the 192 interface). As all pkts will be sent directly to the client, but they will not get unnated and apper to come from the wrong host then be droped by the client. THE FAQ: Q? Why doesn't it just work without all of this. A? The DNAT allows the SYN togo through, but never sees the SYN+ACK. This packet gets sent directly from 192.168.1.10 to the client without going through 192.168.1.1. Since according to the router the connection was never accepted the rest of the data from the client is dropped at the router(192.168.1.1). According to the client, it never sees replies from x.y.z.p and drops the replies from 192.168.1.10 |
All packets then go through this path. This works, but involves the firewall in all of the traffic. |
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.1The 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.
