Difference between revisions of "Using NAT for container with private IPs"
(VE0 conntrack updated) |
(→How to provide access for container to Internet: removed old crap, added nameserver setup, simplified) |
||
Line 41: | Line 41: | ||
</pre> | </pre> | ||
− | where <tt>src_net</tt> is a range of IP addresses of containers to be translated by SNAT, and <tt>ip_address</tt> is the external IP address of your [[Hardware Node]]. The format of src_net is xx.xx.xx.xx/xx ([[w:CIDR|CIDR notation]]). For example | + | where <tt>src_net</tt> is a range of IP addresses of containers to be translated by SNAT, and <tt>ip_address</tt> is the external IP address of your [[Hardware Node]]. The format of src_net is xx.xx.xx.xx/xx ([[w:CIDR|CIDR notation]]). For example: |
<pre> | <pre> | ||
− | # iptables -t nat -A POSTROUTING -s 192.168.2.0/ | + | # iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to ip_address |
</pre> | </pre> | ||
Line 53: | Line 53: | ||
</pre> | </pre> | ||
− | + | === 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.2.0/24 -j ACCEPT | ||
+ | # iptables -A FORWARD -d 192.168.2.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.2.0/24 -j ACCEPT | |
− | + | # iptables-save > /etc/sysconfig/iptables | |
− | + | # service iptables restart | |
− | |||
− | |||
− | |||
− | + | === Nameserver === | |
− | + | Make sure in-CT nameserver is set. The easiest way to do it is: | |
− | |||
− | |||
− | |||
− | |||
− | + | # vzctl set $CTID --nameserver inherit | |
− | + | === Test === | |
− | |||
− | |||
− | |||
− | Now you should be able to reach internet from | + | Now you should be able to reach internet from your container: |
− | + | # vzctl exec $CTID ping openvz.org | |
− | vzctl exec | ||
− | |||
== How to provide access from Internet to a container == | == How to provide access from Internet to a container == |
Revision as of 20:56, 17 December 2013
Usually you supply public IP addresses to your containers. Sometimes you don't want to do it (lack of IPs, etc.). This article describes how to use private IP addresses for containers.
Contents
Prerequisites
Make sure that below prerequisites are met, otherwise it won't work for you!
IP forwarding
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 :
The syntax of /etc/sysctl.conf has changed to :
net.ipv4.conf.default.forwarding=1 net.ipv4.conf.all.forwarding=1
IP conntracks
IP connection tracking should be enabled for CT0.
For recent OpenVZ kernels (2.6.9 and later) connection tracking for CT0 is enabled by default, but it can be disabled by vzctl (because it has a negative impact on venet performance). So, make sure there is no line like
options ip_conntrack ip_conntrack_disable_ve0=1
or
options nf_conntrack ip_conntrack_disable_ve0=1
in /etc/modules.conf
, /etc/modprobe.conf
, or any file under /etc/modprobe.d/
. If there is such a line, please change =1
to =0
and reboot.
How to provide access for container to Internet
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
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.2.0/24 -j ACCEPT # iptables -A FORWARD -d 192.168.2.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.2.0/24 -j ACCEPT # iptables-save > /etc/sysconfig/iptables # service iptables restart
Nameserver
Make sure in-CT nameserver is set. The easiest way to do it is:
# vzctl set $CTID --nameserver inherit
Test
Now you should be able to reach internet from your container:
# vzctl exec $CTID ping openvz.org
How to provide access from Internet to a container
In addition, to make some services in container with private IP address be accessible from the Internet, DNAT (Destination Network Address Translation) should be configured on the Hardware Node. To perform a simple DNAT setup, execute the following command on the Hardware Node:
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport port_num \ -i eth0 -j DNAT --to-destination ve_address:dst_port_num
where ve_address is an IP address of the container, dst_port_num is a tcp port which requires service use, ip_address is the external (public) IP address of your Hardware Node, and port_num is a tcp port of Hardware Node, which will be used for Internet connections to private container service. Note that this setup makes the service which is using port_num on the Hardware Node be unaccessible from the Internet. Also note that SNAT translation is required too.
For example, if you need a web server in a container to be accessible from outside and, at the same time, keep a web server on the Hardware Node be accessible, use the following config:
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport 8080 \ -i eth0 -j DNAT --to-destination ve_address:80 # iptables -t nat -A POSTROUTING -s ve_address -o eth0 -j SNAT --to ip_address
After applying this, you'll see container' web server at http://ip_address:8080/
.
Note: this rule will only work for external clients, i.e. connections originating from a different host — so you can not test if it works locally. |
The iptables utility allows to set up more complex rules for Network Address Translation, involving various protocols and ports. If you wish to get more information on this, consult the numerous Internet sites (e.g. netfilter.org) and tutorials devoted to this issue.