Setting Up NAT VPS on CentOS 6 using IP Tables and HAProxy

When ordering dedicated server sometimes we only got 1 IPv4, but that's enough, we can using NAT for container with IP Tables and HAProxy to creating many OpenVZ VPS inside our dedicated server.

yum update -y
yum install -y wget
cd /etc/yum.repos.d
wget http://download.openvz.org/openvz.repo
rpm --import http://download.openvz.org/RPM-GPG-Key-OpenVZ
yum install -y vzkernel.x86_64
yum install -y vzctl vzquota
yum install -y ploop
sed -i 's/kernel.sysrq = 0/kernel.sysrq = 1/g' /etc/sysctl.conf
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
echo 'net.ipv4.conf.default.proxy_arp = 0' >> /etc/sysctl.conf
echo 'net.ipv4.conf.all.rp_filter = 1' >> /etc/sysctl.conf
echo 'net.ipv4.conf.default.send_redirects = 1' >> /etc/sysctl.conf
echo 'net.ipv4.conf.all.send_redirects = 0' >> /etc/sysctl.conf
echo 'net.ipv4.icmp_echo_ignore_broadcasts=1' >> /etc/sysctl.conf
echo 'net.ipv4.conf.default.forwarding=1' >> /etc/sysctl.conf
sysctl -p
sed -i 's/NEIGHBOUR_DEVS=detect/NEIGHBOUR_DEVS=all/g' /etc/vz/vz.conf
sed -i 's/options nf_conntrack ip_conntrack_disable_ve0=1/options nf_conntrack ip_conntrack_disable_ve0=0/g' /etc/modprobe.d/openvz.conf
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
yum install -y ntp
ntpdate -u us.pool.ntp.org
chkconfig ntpd on
reboot

Now we can install the OpenVZ Web Panel:

wget -O - http://ovz-web-panel.googlecode.com/svn/installer/ai.sh | sh

Open http://PublicIP:3000 in your browser (Login admin/admin, make sure to change your default password).

For private IP, I pick this IP range 192.168.2.0/24, and let say our public IP is 8.8.8.8, and our virtual server IP is set to 192.168.2.1 using OpenVZ Web Panel.

Provide access for container to Internet

iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to 8.8.8.8

SSH for virtual server (port forwarding)

User can access their VPS trough SSH by using our public IP and custom port, I pick port 2122.

iptables -t nat -A PREROUTING -p tcp -d 8.8.8.8 --dport 2122 -j DNAT --to-destination 192.168.2.1:22

Save the iptables:

service iptables save

Restart iptables:

service iptables restart

HAProxy (web access)

We can use HAProxy to bind any http request to our private IPs (DNAT). Install HAProxy first:

rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install -y haproxy

Now configure the /etc/haproxy/haproxy.cfg, example:

frontend httpd
    bind *:80
    acl example_www hdr_end(host) -i example.com www.example.com
    use_backend example_http if example_www
 
backend example_http
    mode http
    server localhost-stash-http 192.168.2.1:80

Start HAProxy and set to start automatically on reboot:

service haproxy start
chkconfig haproxy on

Nginx

If you prefer using nginx instead of haproxy than install nginx first:

rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install nginx

Than creating your nginx configurations, example:

server {
  listen 80;
  server_name example.com www.example.com;
    location / {
      access_log off;
      proxy_pass http://192.168.2.1;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_buffering    off;
      proxy_buffer_size  128k;
      proxy_buffers 100  128k;
    }
}

Troubleshoot

When you start OpenVZ service and you got Running kernel is not an OpenVZ kernel message, you’ll just need to modify /boot/grub/grub.conf manually, example:

default=0
timeout=5

title OpenVZ (2.6.32-042stab090.5)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-042stab090.5 root=/dev/sda1 ro
initrd /boot/initramfs-2.6.32-042stab090.5.img

Important! pick kernel that has stab filename, if mistaken than our dedibox will not booting, after checking the grub.conf file properly than reboot it.