Openvz共享Ip NAT映射端口、NAT with private IP
Using NAT for container with private IPs
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
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 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/parallels.conf
). If there is such a line, please
- change
=1
to=0
- reboot the node.
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
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:
# 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
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
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:
# iptables -A RH-Firewall-1-INPUT -s 192.168.2.0/24 -j ACCEPT
Test
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
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/
.
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.
External Links
例如:將IP 1.1.1.1 的7788端口轉發到2.2.2.2的3389端口,也就是說連接1.1.1.1的7788端口就等於連接2.2.2.2的3389
/sbin/iptables -F /sbin/iptables -X /sbin/iptables -P INPUT ACCEPT /sbin/iptables -P FORWARD ACCEPT /sbin/iptables -P OUTPUT ACCEPT /sbin/iptables -A INPUT -i lo -j ACCEPT /sbin/iptables -A OUTPUT -o lo -j ACCEPT /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT /sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT /sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT sysctl -w net.ipv4.ip_forward=1 /sbin/iptables -t nat -F /sbin/iptables -t nat -A PREROUTING -d 1.1.1.1 -p tcp --dport 7788 -j DNAT --to-dest 2.2.2.2:3389 /sbin/iptables -t nat -A POSTROUTING -d 2.2.2.2 -p tcp --dport 3389 -j SNAT --to-source 1.1.1.1使用NAT为OpenVZ节省IP地址
我们都知道,在配置OpenVZ时需要打开核心的路由转换支持,并且通常设置Hardware Node和VPS使用相同网段的地址,以便外面的机器可以直接访问到VPS上。 但在某些情况下,例如托管服务器中,通常只提供一个互联网IP地址,再购买一个IP地址是比较贵的。这时,我们可以把VPS设置为内网地址,然后通过iptables的NAT转换,让VPS与外界可以互相联通。 一、网络架构 当前IP配置是:这样,VPS处在HW里面,使用私有网段地址,HW相当于网关的作用。 首先,需确认HW上已经打开路由转发,并关闭防火墙:引用HW:121.12.172.184/255.255.255.0 VPS:192.168.100.112/24如果没有的话,请打开/etc/sysctl.conf的支持,并使用sysctl -p生效:引用# cat /proc/sys/net/ipv4/ip_forward 1 # service iptables stop※ 初次使用,请务必关闭防火墙设定,否则,可能会带来很多意想不到的事情。 然后,确认HW和VPS之间可以互通:引用net.ipv4.ip_forward = 1二、查看VPS状态 以我使用的模板centos-5-x86_64-default-5.2-20081210.tar.gz为例,VPS中的网络状态:引用# ping 192.168.100.112 -c 1 PING 192.168.100.112 (192.168.100.112) 56(84) bytes of data. 64 bytes from 192.168.100.112: icmp_seq=1 ttl=64 time=0.044 ms --- 192.168.100.112 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.044/0.044/0.044/0.000 ms # vzctl exec 112 ping 121.12.172.184 -c 1 PING 121.12.172.184 (121.12.172.184) 56(84) bytes of data. 64 bytes from 121.12.172.184: icmp_seq=1 ttl=64 time=0.046 ms --- 121.12.172.184 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.046/0.046/0.046/0.000 ms可见,VPS通过venet0与HW互相访问。但网关192.0.2.1是一个虚拟出来的IP地址,VPS在启动时自动设定该值,不能直接修改。(若使用route add/del命令修改VPS的默认网关,VPS和HW将中断网络连接) 三、使用HW iptables的NAT转发 在HW上执行(121.12.172.184为HW上eth0的对外IP地址):引用# vzctl enter 112 entered into CT 112 # ifconfig venet0:0 venet0:0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:192.168.100.112 P-t-P:192.168.100.112 Bcast:192.168.100.112 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 [root@112 /]# route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.0.2.0 * 255.255.255.0 U 0 0 0 venet0 169.254.0.0 * 255.255.0.0 U 0 0 0 venet0 default 192.0.2.1 0.0.0.0 UG 0 0 0 venet0 # cat /etc/sysconfig/network NETWORKING="yes" GATEWAY="192.0.2.1" HOSTNAME="112.linuxfly.org" [root@112 /]# ping 192.0.2.1 connect: Invalid argument# iptables -F -t nat # iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 121.12.172.184若HW使用浮动IP地址,请使用:# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE然后设定VPS的DNS地址:测试VPS能否出去:引用# vzctl set 112 --nameserver 202.96.128.86 --save File resolv.conf was modified Saved parameters for CT 112这时,VPS处在HW的后面,若需要从互联网访问VPS,则还需要根据应用转发端口。例如22服务,在HW上设置:引用# vzctl exec 112 ping www.163.com -c 1 PING www.cache.idns.yeah.net (220.181.28.50) 56(84) bytes of data. 64 bytes from 220.181.28.50: icmp_seq=1 ttl=55 time=42.7 ms --- www.cache.idns.yeah.net ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 42.757/42.757/42.757/0.000 ms# iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 8022 -j DNAT --to-destination 192.168.100.112:22同样的道理,想利用VPS提供http服务的话,可以在HW上设置iptables或squid反向代理实现转发。 四、NAT inside VE 实际上这不属于本次内容的话题,但由于概念有点相似,觉得有必要说说。 NAT inside VE,也就是在VPS中使用iptables的NAT功能。VPS作为一个相对独立的虚拟系统环境,是支持iptables防火墙设置的。但VPS可使用的iptables模块受限与HW环境,并由/etc/vz/vz.conf决定:其中,默认没有加入iptable_nat模块的。添加后,即可在VPS中使用了。 五、参考资料 在Virtuozzo 3.5版以上平台上,使用NAT功能节约SVPS的IP Parallels Virtuozzo Containers - 虚拟机之家 ubuntu 下 openvz 与 virtualbox 的综合设置 Nat inside VE - openvpn again [message #32095]引用## IPv4 iptables kernel modules IPTABLES="ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length iptable_nat ip_nat_ftp"
目录 返回
首页