There are many of cheap NAT OpenVZ VPSes on market. However, OpenVZ virtualization has certain limitations and comes with old 2.6 kernel. Hosting provider can decide to disable tun/tap, nfs or another core feautures, which makes VPS very limited in usage.
At this article we will break the rules and run latest Alpine Linux inside Debian OpenVZ 2.6.32-042stab134.8 container with 256mb RAM. Alpine is a lightweight system, which is good for slow machines.
Download any VNC viewer. We will need it for initial setup. I use standalone version of RealVNC on Windows.
UPD. You can use -curses QEMU option instead of VNC.
Download the latest Alpine ISO optimized for virtual machines.
apt install qemu
Create QEMU disk image.
qemu-img create -f raw alpine.img 2G
NAT VPSes always comes with only few open ports. Let’s calculate VNC port by the following formula:
"Desired port" - 5900.
In my case:
51221 - 5900 = 45321
Run QEMU virtual machine.
qemu-system-x86_64 \ -netdev user,id=n1 -device virtio-net-pci,netdev=n1 \ -drive file=alpine.img,cache=none,if=virtio,format=raw \ -vnc 0.0.0.0:45321 \ -m 200 \ -cdrom alpine-virt-3.9.3-x86_64.iso
This command will run VM with userspace TCP/IP stack – SLIRP, which is very handy for VPS without tun/tap support. 200 mb will be enough to start Alpine.
Next, run VNC viewer on port 51221 and login as root without password.
Before installing Alpine, we need to setup resolv.conf, so VM can use google DNS instead of one provided by QEMU DHCP server. We can not use QEMU “-netdev dns=addr” option – for some reason it’s not working.
Alpine comes with vi editor out of the box. Practice with it a little bit if you don’t know what is it.
Create resolv.conf file containing google DNS record.
Alpine comes with udhcpc DHCP client, which will overwrite resolv.conf with QEMU DNS by default. Let’s disable this feature.
Create udhcpc config dir.
Create udhcpc.conf with only one line.
Keyboard Layout -> none #if no need
Hostname -> qemu-test #as you want
Interface to initialize -> eth0
Ip address -> DHCP
Manual network configuration -> no
Set new root password
Timezone -> UTC #as you want
Proxy URL -> none
Mirror number -> r #random or as you want
SSH Server -> dropbear #for some reason openssh will slow down OS booting for a few minutes
Disk to use -> vda
How to use -> sys
Erase disk -> y
Shut down Alpine.
Run Alpine again, but disable VNC and enable ssh port redirect.
qemu-system-x86_64 \ -netdev user,id=n1 -device virtio-net-pci,netdev=n1 -redir tcp:51222::22 \ -drive file=alpine.img,cache=none,if=virtio,format=raw \ -nographic \ -m 200
That’s all. Virtual machine is ready to use and accept ssh connections by external IP and 51222 port.
ICMP traffic is not working over SLIRP. Workaround is here (Enabling ping in the guest, on Linux hosts).
Or use virtual tap device if possible.
Cheap VPSes are comes with CPU limitations often. To limit CPU usage I use cpulimit.
git clone https://github.com/opsengine/cpulimit.git cd cpulimit make cp src/cpulimit /usr/bin
Run QEMU with 50% CPU limit.
cpulimit -l 50 \ qemu-system-x86_64 \ -netdev user,id=n1 -device virtio-net-pci,netdev=n1 -redir tcp:51222::22 \ -drive file=alpine.img,cache=none,if=virtio,format=raw \ -nographic \ -m 200