June 22, 2006

Getting started with Linux-VServer

BSD users can improve system security with that operating system's jail mechanism, which creates a partition of resources, thereby
creating a logical barrier between services running inside different such jails. Under Linux, an application called Linux-VServer implements pretty much the same functionality. It partitions a system's resources -- namely CPU, memory, hard disk, and network -- so that processes inside
of the partitions are limited to their context, which makes denial of service attacks less likely to succeed. This is one reason why many hosting companies use virtual servers.

Linux-VServer allows you to create virtual private servers and
security contexts, which operate like normal Linux servers but allow
many independent servers to be run simultaneously in one box at full
speed. It utilizes operating system-level virtualization to enable the
kernel to partition resources. All services, such as SSH, email, Web,
and databases, can be started on such a VServer, without modification,
just as they can on a real server. This also means you can restart your
mail server, for example, without rebooting your Web server, while both
co-exist on the same physical machine. Each virtual server has its own
IP address, hard drive space, user account database, and root password,
and doesn't interfere with other virtual servers.

Virtual servers comprise two types of systems. Host systems are the
physical servers that host the virtual servers. Guest systems are the
virtual server operating systems that run on top of a host OS.

Getting started

We will use CentOS version 4.2 as the operating system on which to test Linux-VServer, and the process should not be too different on any Linux distribution running Linux 2.6. There are a few guides to running
VServer for Fedora and Ubuntu on the Web.

Start out with a fresh install of CentOS 4.2. Keep the host system
as minimal as possible; I rarely see any reason to run any more than
SSH and iptables.

Boot from the first CentOS 4.2 CD. The installation is relatively
simple for anyone who has installed Linux before. Create a large
/vservers partition, and be sure to select the Development Packages
during package selection. We will be running most services on the guest
system, so we don't need much else installed. When the install is done,
check that your Internet connection and other services are working
properly.

Now log in as root and upgrade the system to install the latest
version of all the packages as well as security updates:

yum -y upgrade

Once the updates are installed, disable SELinux. Edit the file
/etc/selinux/config and modify the SELINUX entry to look like this:

SELINUX=disabled

You want as few services running on the host system as possible for
two reasons. First, you don't want to waste CPU cycles on services that
are never used. Second, the fewer services that are running, the fewer
vulnerabilities the system will have.

To get a list of services currently running, first find your run
level:

# runlevel

This will return a number, which most likely will be 3
if you're logged in as root. To find which services run at boot, run:

# chkconfig --list | grep "3: on"

To find what package does what, query each package:

# rpm -qi package_name

If you find a service that you do not require, stop it from starting
on boot by using the ntsysv tool. Reboot your system to
apply these settings.

Here are some packages that I find non-essential on a server:

  • autofs - a daemon that automatically mounts file systems
  • apmd - a set of programs for controlling the Advanced
    Power Management daemon and utilities found in most modern laptop
    computers
  • pcmcia - a module of another package
  • cups - the Common Unix Printing System
  • xinetd - a secure replacement for inetd
  • gpm - mouse support to text-based Linux applications
  • kudzu - hardware analyzer run at boot time to check for
    added/removed hardware
  • iptables - firewall; despite selecting not to install at
    setup, this will still install iptables but blank its config file
  • anacron - a periodic command scheduler that executes
    commands at intervals specified in days. Unlike cron, it does not
    assume that the system is running continuously.
  • isdn - only required if you are using an ISDN connection
  • nfs - server functionality for file sharing across TCP/IP
    networks
  • netfs - mounts/unmounts all Network File Systems and Samba
    mount points. Not needed if you don't need to automount remote File
    Systems.
  • nfslock - server functionality for file sharing across
    TCP/IP networks
  • atd - controls the at command, which is used
    to schedule commands
  • rpcgssd / rpcsvcgssd / rpcidmapd - these are Network File
    System daemons. If you do not use NFS, turn it off.
  • cpuspeed - adjusts the CPU speed dynamically based on the
    demand for processing power. Disable it unless you are using a laptop.
  • mdmonitor - manages your sofware RAID. We're using
    hardware RAID.
  • HALdaemon / DBUS - desktop-oriented services

The kernel

Now we come to the coolest part of the process. As I mentioned
earlier, enabling VServer on Linux requires some OS-level
virtualisation. For this to happen you need to make sure the kernel
supports VServers. The standard kernel that comes with CentOS does not,
so you need to get the sources for the kernel, patch it with the
VServer patch, and compile it.

Start by getting the kernel sources. Currently the linux-vserver
latest stable release is for the 2.6.14.3 kernel. Follow these steps to
download the sources:

# cd /usr/src
# wget
ftp://ftp.probe-networks.lkams.kernel.org/pub/linux/kernel/v2.6/linux-2.6.14.3.tar.bz2

Get the latest kernel patch from linux-vserver.org or
13thfloor.at/vserver:

# wget
http://www.13thfloor.at/vserver/s_rel26/v2.01/patch-2.6.14.3-vs2.01.diff.bz2
# tar xjf linux-2.6.14.3.tar.bz2

Patch the kernel sources:

# cd /usr/src/linux-2.6.14.3
# bzip2 -dc ../patch-2.6.14.3-vs2.01.diff.bz2 | patch -p1

If you're already running a similar 2.6.x kernel, you can copy your
current config before building -- but don't attempt to use a 2.4.X
config file:

# cp /boot/config-`uname -r` .config

There are a few things that you want to include when you compile to
give the kernel VServer support. If you face any problems with kernel
compilation, refer to this page.
Otherwise, continue by running:

# make menuconfig

You will see a category for "Linux VServer" toward the bottom of the
list. The default selections should be fine. Make sure the following
are checked:

Enable Legacy kernel API
Enable Proc Security
Enable Hard CPU Limits

Now that the config information is ready, it's time to make the
kernel. The following command will compile and install the kernel. This
will take some time, so make yourself a cup of coffee and order some
pizza.

# make bzImage && make modules && make
modules_install && make install

Now edit the GRUB configuration file /boot/grub/menu.lst. Go to the
line that says "default=" and make sure that the line "default" is set
to "0". It will look something like the following.

default=0
title CentOS (2.6.14.3-vs2.0.1)
root (hd0,0)
kernel /vmlinuz-2.6.14.3-vs2.0.1 ro root=/dev/VolGroup00/LogVol00 rhgb
quiet

Now you should be able to reboot your machine and run your new
kernel with VServer support. Check the kernel version after you boot up
with the command uname -r to make sure you're running on
the new one. If all went well, you should see something like 2.6.14.3-vs2.0.1.
If not, go back to the section above and see where you went wrong.

VServer binaries

Now that you have a CentOS 4.2 installation ready with support for
VServers, you're ready to install the VServer binaries. These are
userland utilities that you use to create and manage the VServers you
will create. Start by downloading and extracting the binaries:

# cd /usr/src/
# wget
http://www.13thfloor.at/vserver/s_rel26/v2.01/util-vserver-0.30.209.tar.gz
# tar -zxvf util-vserver-0.30.209.tar.gz
# cd util-vserver-0.30.209

At this point, make sure you have installed dietlibc and
beecrypt/-devel using the following command:

# yum install -y dietlibc beecrypt-devel

Now build and install the util-vserver tools. Here's an example
(installing tools in /lib and /sbin and also /etc/init.d):

# cd /usr/src/util-vserver-0.30.209
# ./configure --prefix= --sysconfdir=/etc
# make && make install && make install-distribution

Test that all went well:

# wget http://vserver.13thfloor.at/Stuff/SCRIPT/testme.sh
# chmod 700 testme.sh;./testme.sh

If all went well you should see something like this:

Linux-VServer Test [V0.15] Copyright (C) 2003-2006 H.Poetzl
chcontext is working.
chbind is working.
Linux 2.6.14.3-vs2.0.1 #1 SMP Thu Mar 2 12:45:32 IST 2006 i686
Ea 0.30.209 273/glibc (DSa)
<compat,v11,v13,fscompat,net,oldproc,olduts>
VCI: 0002:0001 273 03110036 (TbLgnPD)
---
[000]# succeeded.
[001]# succeeded.
[011]# succeeded.
[031]# succeeded.
[101]# succeeded.
[102]# succeeded.
[201]# succeeded.
[202]# succeeded.

Setting up the virtual servers

Creating virtual servers is a one-time task, and it's pretty simple
from here on, though it may take some time. First up you have to create
a template from your host system. For that you have to take a dump of
the entire filesystem minus a few directories, mainly /proc, and /dev:

# mkdir /vservers/template/
# dump 0f - /usr | (cd /vservers/template/ && restore rf -)

Similarly, take a dump for the following directories:

/bin, /etc, /home, /include, /initrd, /lib, /opt, /root, /sbin,
/tmp,
/usr, and /var

You can clean up the template to improve on the speed and size of
the VServers by patiently going through the copied files and detecting
what you do not need in your VServer and removing it, but I suggest you
skip that for now.

Now create a VServer based on the following command:

# /sbin/vserver <VSERVER_NAME> build -m
<BUILD_METHOD> --hostname <VSERVER_HOSTNAME> --interface
<VSERVER_NAME>=<NET_DEVICE>:<IP>/<CIDR>

Here's a real example:

# /sbin/vserver calvin build -m skeleton --hostname
calvin --interface calvin=eth0:192.168.0.10/24

So, our first virtual server will have the following information:

VSERVER_NAME calvin
FQDN calvin
NET_DEVICE eth0
IP 192.168.0.10
CIDR 24 (255.255.255.0)
BUILD_METHOD skeleton

Now you have to populate your new VServer with the data from your
template:

# cp -a /vservers/template/. /vservers/calvin/

Edit the /etc/hosts in the VServer to reflect the networking
settings of your VServer:

# vi /vservers/calvin/etc/hosts

Finally, start a VServer-related script that enables the
partitioning of resources. The script will need to be started after
every reboot.

# /etc/init.d/vprocunhide start

You are now done setting up the VServers. Keep your fingers crossed
and start the new VServer:

# /sbin/vserver calvin start

If you got some errors, like some services failing, that may be OK. If you are unable to start your VServer, look on the VServer mailing
list archive
for help. If it started
successfully you can now enter the VServer:

# /sbin/vserver calvin enter

Here are some basic commands to get you started with VServers:

# /sbin/vserver <VSERVER_NAME> [ start | stop
| restart | enter ]

A good thing to do now is to run either ntsysv or chkconfig
and remove all the services that you don't need from startup. Remove
all networking and kernel-related services especially, such as iptables
and kudzu.

To get statistics on the activity in the VServers, run:

# /sbin/vserver-stat

If you run into problems or have questions, two sources may be of
immense help. The first is the man page for the VServer packages, and
the other is the VServer mailing list.

Category:

  • Security
Click Here!