Difference between revisions of "Using NAT for container with private IPs"

From OpenVZ Virtuozzo Containers Wiki
Jump to: navigation, search
(How to provide access from Internet to a VE)
 
(37 intermediate revisions by 15 users not shown)
Line 1: Line 1:
Usually you supply public IP addresses to your VEs. Sometimes you don't want to do it (lack of IPs, etc.). This article describes how to use private IP addresses for VEs.
+
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.
  
 
== Prerequisites ==
 
== Prerequisites ==
 +
 +
Make sure that below prerequisites are met, otherwise it won't work for you!
 +
 +
=== 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 4.7 and newer (because it has a negative impact on venet performance, see {{Bug|2755}}). 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 <code>/etc/modules.conf</code>, <code>/etc/modprobe.conf</code>, or any file under <code>/etc/modprobe.d/</code> (such as <code>/etc/modprobe.d/vz.conf</code>). '''If there is such a line, please'''
 +
#change <code>=1</code> to <code>=0</code>
 +
#reboot the node.
  
 
=== IP forwarding ===
 
=== IP forwarding ===
IP forwarding should be turned on on hardware node in order for VE networking to work. Make sure it is turned on:
+
 
 +
'''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  
 
  $ cat /proc/sys/net/ipv4/ip_forward  
Line 11: Line 26:
 
Output should be '1'. If it is '0', enable IP forwarding as it is described in [[Quick installation#sysctl]].
 
Output should be '1'. If it is '0', enable IP forwarding as it is described in [[Quick installation#sysctl]].
  
=== IP conntracks ===
+
NOTE: '''Ubuntu''' made some changes to the syntax for NAT. See this link if you are needing to enable NAT on an Ubuntu host :
IP connection tracking should be enabled for VE0.
+
 
 +
[https://bugs.launchpad.net/ubuntu/+source/procps/+bug/84537 Launchpad]
 +
 
 +
The syntax of /etc/sysctl.conf has changed to:
 +
 
 +
<pre>net.ipv4.conf.default.forwarding=1
 +
net.ipv4.conf.all.forwarding=1</pre>
 +
 
 +
===Enable iptables in OpenVZ 7/Virtuozzo 7===
 +
 
 +
If you use OpenVZ 7/Virtuozzo 7 and want to manage iptables through iptables-services you must disable firewalld and enable iptables:
 +
 
 +
# systemctl stop firewalld
 +
# systemctl mask firewalld
 +
# yum install iptables-services
 +
# systemctl enable iptables
 +
 
 +
== How to create the container and attach network properties to it ==
 +
 
 +
Create the container:
  
'''For OpenVZ kernels 2.6.8''', put the following line into /etc/modprobe.conf:
+
# prlctl create 100700 --vmtype ct
  
modprobe ip_conntrack ip_conntrack_enable_ve0=1
+
Attach the internal IP address and DNS server:
  
and reboot.
+
# prlctl set 100700 --ipadd 192.168.0.101/24
 +
# prlctl set 100700 --nameserver 8.8.8.8
  
'''For OpenVZ kernels later than 2.6.8''', connection tracking for VE0 is enabled by default. '''However''', make sure there is '''no''' line like
+
Start the container:
  
  options ip_conntrack ip_conntrack_disable_ve0=1
+
  # prlctl start 100700
  
in /etc/modules.conf or /etc/modprobe.conf. If there is such line, comment it out (or remove) and reboot.
+
== How to provide access for container to the Internet ==
  
== How to provide access for VE to Internet ==
+
To enable the [[container]]s, 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 <tt>iptables</tt> utility.
  
To enable the [[VE]]s, 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 <tt>iptables</tt> utility. To perform a simple SNAT setup, execute the following command on the [[Hardware Node]]:
+
To perform a simple SNAT setup, execute the following command on the [[Hardware Node]]:
 
<pre>
 
<pre>
 
# iptables -t nat -A POSTROUTING -s src_net -o eth0 -j SNAT --to ip_address
 
# iptables -t nat -A POSTROUTING -s src_net -o eth0 -j SNAT --to ip_address
 
</pre>
 
</pre>
  
where <tt>src_net</tt> is a range of IP addresses of VEs to be translated by SNAT, and <tt>ip_address</tt> is the external IP address of your [[Hardware Node]]. 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 [[Hardware Node|Node]], you may need to specify a different interface for outgoing connections, e.g. <tt>-o eth2</tt>.
+
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>
 +
# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to ip_address
 +
</pre>
  
To make all IP addresses to be translated by SNAT (not only the ones of [[VE]]s with private addresses), you should type the following string:
+
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 [[Hardware Node|Node]], you may need to specify a different interface for outgoing connections, e.g. <tt>-o eth2</tt>.
 +
 
 +
To make all IP addresses to be translated by SNAT (not only the ones of [[container]]s with private addresses), you should type the following string:
 
<pre>
 
<pre>
 
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to ip_address
 
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to ip_address
 
</pre>
 
</pre>
  
{{Note|If the above is not working then check if one of the following solutions does the trick.}}
+
Or you can just use:
1. If you are using stable (currently 2.6.8-based) kernel, then to enable SNAT for the VEs on your local network you need to explicitly enable connection tracking in [[VE0]]. Make sure that the following string is present in the <tt>/etc/modprobe.conf</tt> file:
+
 
<pre>
+
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
options ip_conntrack ip_conntrack_enable_ve0=1
+
 
</pre>
+
=== Save new iptables rules ===
 +
 
 +
Do not forget to save your new iptables rules
 +
 
 +
# service iptables save
 +
# service iptables restart
 +
 
 +
=== 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:
  
{{Note|in kernels later than 2.6.8, connection tracking is enabled by default}}
+
# iptables -A RH-Firewall-1-INPUT -s 192.168.2.0/24 -j ACCEPT
  
In case it is not, add this string to the file by means of any text editor (for example, vi). This setting is not needed for kernels more recent than 2.6.8, since connection tracking for [[VE0]] is enabled by default in those kernels.
+
=== Test ===
  
2. For unknown reasons the above didn't work on a Debian host. The solution is to do it in an init.d script as follows:
+
Now you should be able to reach internet from your container:
<pre>
 
modprobe ip_conntrack ip_conntrack_enable_ve0=1
 
</pre>
 
Make sure that this module is loaded before any of the other iptables-modules are loaded! Also remember that if this module is loaded without the option, unloading and reloading doesn't work! You need to reboot the computer.
 
  
{{Note|in kernels later than 2.6.8, connection tracking is enabled by default}}
+
# prlctl enter 100700
 +
# ping openvz.org
  
== How to provide access from Internet to a VE ==
+
== How to provide access from Internet to a container ==
  
In addition, to make some services in VE 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]]:
+
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]]:
 
<pre>
 
<pre>
 
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport port_num \
 
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport port_num \
Line 66: Line 117:
 
</pre>
 
</pre>
  
where <tt>ve_address</tt> is an IP address of the VE, <tt>dst_port_num</tt> is a tcp port which requires service use, <tt>ip_address</tt> is the external (public) IP address of your [[Hardware Node]], and <tt>port_num</tt> is a tcp port of [[Hardware Node]], which will be used for Internet connections to private VE service. Note that this setup makes the service which is using <tt>port_num</tt> on the [[Hardware Node]] be unaccessible from the Internet. Also note that SNAT translation is required too.
+
where <tt>ve_address</tt> is an IP address of the container, <tt>dst_port_num</tt> is a tcp port which requires service use, <tt>ip_address</tt> is the external (public) IP address of your [[Hardware Node]], and <tt>port_num</tt> 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 <tt>port_num</tt> 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 VE to be accessible from outside and, at the same time, keep a web server on the [[Hardware Node]] be accessible, use the following config:
+
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:
 
<pre>
 
<pre>
 
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport 8080 \
 
# iptables -t nat -A PREROUTING -p tcp -d ip_address --dport 8080 \
Line 75: Line 126:
 
</pre>
 
</pre>
  
After applying this, you'll see VE' web server at <code><nowiki>http://ip_address:8080/</nowiki></code>.
+
Is need add GATEWAY in /etc/sysconfig/network-script/interface (IP of host that provide access internet).
 +
 
 +
After applying this, you'll see container' web server at <code><nowiki>http://ip_address:8080/</nowiki></code>.
  
 
{{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.}}
 
{{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.}}
 +
 +
{{Note|If you get any errors relating to:
 +
<code>iptables: No chain/target/match by that name</code>
 +
double check to see if you have all the iptables/netfilter modules loaded properly. I had to <code> modprobe xt_tcpudp </code> before getting it to work.}}
 +
  
 
The <tt>iptables</tt> 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. [http://www.netfilter.org netfilter.org]) and tutorials devoted to this issue.
 
The <tt>iptables</tt> 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. [http://www.netfilter.org netfilter.org]) and tutorials devoted to this issue.
Line 83: Line 141:
 
== External Links ==
 
== External Links ==
 
* [http://www.netfilter.org netfilter.org]
 
* [http://www.netfilter.org netfilter.org]
 +
* [[w:Private network]]
  
 
[[Category: HOWTO]]
 
[[Category: HOWTO]]
 
[[Category: Networking]]
 
[[Category: Networking]]

Latest revision as of 09:52, 17 August 2016

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.

Prerequisites[edit]

Make sure that below prerequisites are met, otherwise it won't work for you!

IP conntracks[edit]

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 4.7 and newer (because it has a negative impact on venet performance, see OpenVZ Bug #2755). 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/ (such as /etc/modprobe.d/vz.conf). If there is such a line, please

  1. change =1 to =0
  2. reboot the node.

IP forwarding[edit]

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

Enable iptables in OpenVZ 7/Virtuozzo 7[edit]

If you use OpenVZ 7/Virtuozzo 7 and want to manage iptables through iptables-services you must disable firewalld and enable iptables:

# systemctl stop firewalld
# systemctl mask firewalld
# yum install iptables-services
# systemctl enable iptables 

How to create the container and attach network properties to it[edit]

Create the container:

# prlctl create 100700 --vmtype ct

Attach the internal IP address and DNS server:

# prlctl set 100700 --ipadd 192.168.0.101/24
# prlctl set 100700 --nameserver 8.8.8.8

Start the container:

# prlctl start 100700

How to provide access for container to the Internet[edit]

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

Or you can just use:

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Save new iptables rules[edit]

Do not forget to save your new iptables rules

# service iptables save
# service iptables restart

Firewall[edit]

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

Test[edit]

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

# prlctl enter 100700 
# ping openvz.org

How to provide access from Internet to a container[edit]

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

Is need add GATEWAY in /etc/sysconfig/network-script/interface (IP of host that provide access internet).

After applying this, you'll see container' web server at http://ip_address:8080/.

Yellowpin.svg 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.
Yellowpin.svg Note: If you get any errors relating to:

iptables: No chain/target/match by that name double check to see if you have all the iptables/netfilter modules loaded properly. I had to modprobe xt_tcpudp before getting it to work.


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.

External Links[edit]