How to setup Internet on Openvz container with Private IP

Ok, so i don't want to waste my IP addresses so i would need to setup multiple openvz container with private ip with a single host public ip. If you did read the article on openvz.org about using NAT for container with private IPs, but you were unable to setup properly or your internet isn't going into your container, this is most likely due to a setup issue you have (which is what happen to me and this is why i am writing this up!)

Assuming i have 3 container with the following ips (please setup these ips on your containers)

vps1.hungred.com 192.168.0.1
vps2.hungred.com 192.168.0.2
vps3.hungred.com 192.168.0.2

and a single public ip host machine that all these 3 containers sites on with the following ip

vps.hungred.com 10.2.5.1

i am going to setup and explain what is going to be done with the above machines.

OpenVZ Host

Most of the work, or to be exact, all of the work will need to be done on the Openvz Host machine in this case its the machine with the ip 10.2.5.1. Make sure the following things are done on your host machine,

IP forwarding should be turned on on the hardware node in order for container networking to work. Make sure it is turned on:

$ cat /proc/sys/net/ipv4/ip_forward
1
Output should be '1'. If it is '0', enable IP forwarding as it is described in Quick installation#sysctl.

NOTE: Ubuntu made some changes to the syntax for NAT. See this link if you are needing to enable NAT on an Ubuntu host :

Launchpad

The syntax of /etc/sysctl.conf has changed to :

net.ipv4.conf.default.forwarding=1
net.ipv4.conf.all.forwarding=1

Once the above are done, it's time to setup our iptables to forward all internet traffic to our containers. All you need to do are to setup the iptables with the range of ips needed to forward to.

To enable the containers, which have only internal IP addresses, to access the Internet, SNAT (Source Network Address Translation, also known as IP masquerading) should be configured on the Hardware Node. This is ensured by the standard Linux iptables utility. To perform a simple SNAT setup, execute the following command on the Hardware Node:

# iptables -t nat -A POSTROUTING -s src_net -o eth0 -j SNAT --to ip_address
where src_net is a range of IP addresses of containers to be translated by SNAT, and ip_address is the external IP address of your Hardware Node. The format of src_net is xx.xx.xx.xx/xx (CIDR notation). For example:

# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to ip_address
Multiple rules are allowed, for example, in case you wish to specify several ranges of IP addresses. If you are using a number of physical network interfaces on the Node, you may need to specify a different interface for outgoing connections, e.g. -o eth2.

To make all IP addresses to be translated by SNAT (not only the ones of containers with private addresses), you should type the following string:

# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to ip_address

Let me explain a little bit on what is really needed, you will really want to enter the below statement

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to 10.2.5.1

what the above does is to tell your iptables to allow all private ip of the range 192.168.0.1-192.168.254 to be connect to the internet at 10.2.5.1 but bear in mind what ethernet port you are using, it can be eth0 or vmbr01 depending what you have setup your 10.2.5.1 on. Just firing up ifconfig and you should see where 10.2.5.1 are being attached to.

and also, while you are still at it, do setup your firewall as well.

Firewall
For Debian hardware node, you may need to allow a forward rule. The table still being the default table (filter) but the chain is FORWARD:

# iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT
# iptables -A FORWARD -d 192.168.0.0/24 -j ACCEPT
For default RedHat/CentOS firewall, allow outgoing connections from your containers, for example:

# iptables -A RH-Firewall-1-INPUT -s 192.168.0.0/24 -j ACCEPT
# iptables-save > /etc/sysconfig/iptables
# service iptables restart

The above forward all internet and accept connection from the range of 192.168.0.1-192.168.254 due to /24 being accepted.

Once you are done with the above, test it out

Test
Now you should be able to reach internet from your container:

# vzctl exec $CTID ping openvz.org

where $CTID is the openvz id

if you don't get unknown host, and get a response back, you have just setup your machine with an internal ip!