There’s a million things you need to do to get one-to-one NAT working. This is my checklist – a list that’s saved my bacon many-a-time.
Let’s suppose the situation is that you have a single host with multiple virtual machine running in it. The host has a network connection to the WAN. There are three VM guests each with an IP address of “192.168.122.10”, “192.168.122.11” and “192.168.122.12”. Your ISP has given you three pubic IP addresses for your VM guests of “188.8.131.52”, “184.108.40.206” and “220.127.116.11”. You have another public IP address for your host of “18.104.22.168”.
So here’s the check-list:
- Host-to-Guest connectivity: Make sure the host knows how to get to each VM guest. This is likely already done when you built your VMs. If you can “ping” your guests from your host, you’re in good shape.
- IP Forwarding: Make sure the kernel knows that it can forward IP packets between two network. This is done by putting a “1” in the “/proc/sys/net/ipv4/ip_forward” file.
- Firewall / IPtables: Make sure IPTables knows that it can forward packets between the WAN and the guests. You can “drop” and “accept” specific ports or permit “all” data for specific VM guests. That’s up to you. I suggest that you use the host’s IPTables as a firewall and block what you don’t want passing through to the guests.
- Don’t assign public IP addresses to the gusts: Make sure the VM guests only have private IP addresses configured and “not” public IP addresses. They should be using the “192.168.122.x” range.
- Assigning all public IP addresses to the host: Make sure the host has public IP addresses for each VM guests. This is an ARP thing. The host is what’s listening on the WAN interface and therefore it should have sub-interfaces – one for each public IP address. Eg: eth0:1=22.214.171.124, eth0:2=126.96.36.199 and eth0:3=188.8.131.52.
- The actual NAT: Make sure IPTables knows to “postrouting” and “prerouting” for each VM guest. See the example below.
Here’s an example IPTables file on a Redhat server. I’ve kept it simple and recommend you use this as a basis for a more complete setup.
*nat :PREROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] # Guest 1 -A POSTROUTING -o em1 -s 192.168.122.10 -j SNAT --to-source 184.108.40.206 -A PREROUTING -i em1 -d 220.127.116.11 -j DNAT --to-destination 192.168.122.10 # Guest 2 -A POSTROUTING -o em1 -s 192.168.122.11 -j SNAT --to-source 18.104.22.168 -A PREROUTING -i em1 -d 22.214.171.124 -j DNAT --to-destination 192.168.122.11 # Guest 3 -A POSTROUTING -o em1 -s 192.168.122.12 -j SNAT --to-source 126.96.36.199 -A PREROUTING -i em1 -d 188.8.131.52 -j DNAT --to-destination 192.168.122.12 COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited #-A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT