Accueil

Installer et configurer Vserver sur Slackware

Par yttrium.

Sommaire

Qu'est-ce que vserver ?

Un vserver est un patch appliqué au noyau linux qui permet de faire fonctionner sur une seule machine plusieurs systèmes d'exploitation de type GNU/linux grâce à un isolateur de contexte également appelé « zone d'exécution ». Pour résumer, les processus partagent les ressources du noyau mais sont exécutés dans un contexte isolé duquel il ne leur est pas possible de s'échapper.

A quoi est-ce que cela sert ?

Cela sert à plusieurs choses, notamment

Procédure d'installation sur une Slackware 12.0

Il est tout d'abord indispensable de télécharger les sources du noyau 2.6.22.19 sur kernel.org. Sources qu'on décompressera dans /usr/src/

wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.22.19.tar.gz
tar -zxvf linux-2.6.22.19.tar.gz -C /usr/src

Ensuite, on télécharge le patch vserver pour le noyau 2.6.22.19 et on l'applique sur le code source du noyau grâce à la commande patch, notre noyau sera alors capable de prendre en charge les vservers

wget http://ftp.linux-vserver.org/pub/kernel/vs2.2/patch-2.6.22.19-vs2.2.0.7.diff
cp patch-2.6.22.19-vs2.2.0.7.diff /usr/src
ln -s /usr/src/linuc /usr/src/linux-2.6.22.19
cd /usr/src/linux
patch -p1 < ../patch-2.6.22.19-vs2.2.0.7.diff

Après quoi on configure le noyau grâce à la commande make menuconfig

make menuconfig

On se rend dans le sous-menu Linux VServer et on configure comme suit

Linux VServer --->
  [*] Enable Legacy Kernel API
  [ ]   Show a Legacy Version ID
  [*]   Enable dynamic context IDs
  [*] Enable Legacy Networking Kernel API
  [ ] Remap Source IP Address
  [*] Enable COW Immutable Link Breaking
  [ ] Enable Virtualized Guest Time
  [*] Enable Proc Security
  [*] Enable Hard CPU Limits
  [*]   Avoid idle CPUs by skipping Time
  [ ]   Limit the IDLE task
      Persistent Inode Tagging (UID24/GID24)  --->
  [ ] Tag NFSD User Auth and Files
  [ ] Enable Inode Tag Propagation
  [*] Honor Privacy Aspects of Guests
  [*] VServer Warnings
  [ ] VServer Debugging Code

On n'oublie pas non plus de configurer en dur le Virtual Root device support qui est indispensable pour le fonctionnement des vservers :

Device Drivers --->
  Block Devices --->
    <*> Virtual Root device support

Je vous conseille également de mettre en module la fonction dummy, elle vous permettra d'émuler une carte réseau pour chacun de vos vservers en attachant un module dummy à chaque interface virtuelle.

Device Drivers --->
  Network device support --->
    <M> Dummy net driver support

Après cela, configurez le noyau pour votre machine, je vous conseille de vous aider des sites internet hardware4linux.info et www.linuxcompatible.org pour valider votre configuration matérielle.

Maintenant, nous pouvons passer à la compilation du nouveau noyau grâce aux commandes habituelles :

make clean bzImage modules modules install

Au bout de laquelle on pourra démouler le magnifique gâteau aux pépites de chocolat qu'on découpera sur assiette pour le service (salut Cyril) ;-). En bref, on va copier notre nouveau noyau dans le répertoire système /boot :

cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.22.19
cp System.map /boot/System.map-2.6.22.19
cp .config /boot/config-2.6.22.19

Après quoi on modifiera le fichier lilo.conf en conséquence afin de demander au système de démarrer sur notre nouveau noyau et de conserver l'ancien en cas de problème :

# lignes précédentes
default = Linux-2.6.22.19
image = /boot/vmlinuz
  root = /dev/hda #remplacez /dev/hda par /dev/md0 si vous utilisez du raid logiciel
  label = Linux
  read-only
image = /boot/vmlinuz-2.6.22.19
  root = /dev/hda
  label = Linux-2.6.22.19
  read-only

On valide le changement en appelant la commande lilo en étant administrateur du système (root) :

lilo

Maintenant on n'a plus qu'à tester le bébé en redémarrant le système :

reboot

Dès que tout fonctionne parfaitement bien (vidéo, son, pci, usb, disque(s) dur(s), etc...) vous pouvez enlever l'ancien noyau ainsi que ses sources :

removepkg /var/log/packages/kernel-*tgz

On enlèvera également du fichier de configuration lilo.conf les références à l'ancien noyau :

vi /etc/lilo.conf
# lignes précédentes
default = Linux
image = /boot/vmlinuz-2.6.22.19
  root = /dev/hda (ou /dev/md0)
  label = Linux
  read-only
lilo

Pour information, il est préférable de ne pas mettre à jour le noyau de manière automatique si vous utilisez un logiciel du genre swaret ou slackpkg. Ci-dessous, on va donc proscrire les mises à jour du noyau dans le fichier de configuration de slackpkg :

vi /etc/blacklist
# lignes précédentes
kernel-ide
kernel-modules
kernel-source
kernel-headers
kernel-generic
kernel-huge
kernel-generic-smp
kernel-huge-smp
# lignes suivantes

Préparation du terrain

Avant de pouvoir créer nos premiers vservers, on va commencer par télécharger les outils vservers et leurs dépendances :

wget http://www2.linuxpackages.net/packages/Slackware-12.0/Console/util-vserver/util-vserver-0.30.214-i486-5tfx.tgz
wget http://www2.linuxpackages.net/packages/Slackware-12.0/Library/BeeCrypt/beecrypt-4.1.2-i486-1tfx.tgz
wget http://www2.linuxpackages.net/packages/Slackware-12.0/Library/dietlibc/dietlibc-0.31-i486-3tfx.tgz

On crée ensuite un répertoire vservers à la racine du système. Essayez dans la mesure du possible de créer le répertoire vservers sur une nouvelle partition afin d'éviter tout problème en cas de saturation de la partition à cause d'un problème sur l'un des vservers :

mkdir /vservers

Création de la liste et des scripts nécessaires

On va maintenant définir une liste minimale de paquets à installer pour nos vservers, ci-dessous vous trouverez la liste des paquets indispensables à reporter dans le fichier liste_packages :

cd /root
vi liste_packages
extra/libsafe-2.0-16/libsafe-2.0.16-i386-1.tgz
patches/packages/openssh-5.0p1-i486-1_slack12.0.tgz
patches/packages/glibc-zoneinfo-2.5-noarch-7_slack12.0.tgz
patches/packages/m4-1.4.11-i486-1_slack12.0.tgz
patches/packages/bzip2-1.0.5-i486-1_slack12.0.tgz
patches/packages/tcpdump-3.9.7-i486-1_slack12.0.tgz
slackware/a/aaa_base-12.0.0-noarch-1.tgz
slackware/a/aaa_elflibs-12.0.0-i486-3.tgz
slackware/a/aaa_terminfo-5.6-noarch-1.tgz
slackware/a/acl-2.2.39_1-i486-2.tgz
slackware/a/attr-2.4.32_1-i486-2.tgz
slackware/a/bash-3.1.017-i486-2.tgz
slackware/a/bin-11.1-i486-1.tgz
slackware/a/coreutils-6.9-i486-1.tgz
slackware/a/cpio-2.5-i486-3.tgz
slackware/a/cryptsetup-1.0.5-i486-2.tgz
slackware/a/cxxlibs-6.0.8-i486-4.tgz
slackware/a/dcron-2.3.3-i486-6.tgz
slackware/a/devs-2.3.1-noarch-25.tgz
slackware/a/dialog-1.1_20070528-i486-1.tgz
slackware/a/e2fsprogs-1.39-i486-1.tgz
slackware/a/elvis-2.2_0-i486-2.tgz
slackware/a/etc-11.1-noarch-6.tgz
slackware/a/file-4.21-i486-1.tgz
slackware/a/findutils-4.2.31-i486-1.tgz
slackware/a/gawk-3.1.5-i486-3.tgz
slackware/a/gettext-0.16.1-i486-3.tgz
slackware/a/glibc-solibs-2.5-i486-4.tgz
slackware/a/grep-2.5-i486-3.tgz
slackware/a/gzip-1.3.12-i486-1.tgz
slackware/a/infozip-5.52-i486-2.tgz
slackware/a/kbd-1.12-i486-2.tgz
slackware/a/less-394-i486-1.tgz
slackware/a/logrotate-3.7.4-i486-1.tgz
slackware/a/module-init-tools-3.2.2-i486-3.tgz
slackware/a/openssl-solibs-0.9.8e-i486-3.tgz
slackware/a/patch-2.5.4-i486-1.tgz
slackware/a/pkgtools-12.0.0-noarch-4.tgz
slackware/a/procps-3.2.7-i486-2.tgz
slackware/a/rpm2tgz-1.0-i486-1.tgz
slackware/a/sed-4.1.5-i486-1.tgz
slackware/a/shadow-4.0.3-i486-14.tgz
slackware/a/slocate-3.1-i486-1.tgz
slackware/a/sysfsutils-2.1.0-i486-1.tgz
slackware/a/sysklogd-1.4.1-i486-10.tgz
slackware/a/sysvinit-2.86-i486-5.tgz
slackware/a/sysvinit-functions-8.53-i486-2.tgz
slackware/a/sysvinit-scripts-1.2-noarch-13.tgz
slackware/a/tar-1.16.1-i486-1.tgz
slackware/a/time-1.7-i486-1.tgz
slackware/a/tree-1.5.0-i486-1.tgz
slackware/a/udev-111-i486-5.tgz
slackware/a/utempter-1.1.4-i486-1.tgz
slackware/a/util-linux-2.12r-i486-6.tgz
slackware/a/which-2.16-i486-1.tgz
slackware/ap/at-3.1.10-i486-1.tgz
slackware/ap/diffutils-2.8.1-i486-3.tgz
slackware/ap/groff-1.19.2-i486-1.tgz
slackware/ap/lsof-4.78-i486-1.tgz
slackware/ap/man-1.6c-i486-2.tgz
slackware/ap/man-pages-2.55-noarch-1.tgz
slackware/ap/mc-4.6.1_20070309-i486-2.tgz
slackware/ap/most-4.10.2-i486-2.tgz
slackware/ap/rpm-4.2.1-i486-3.tgz
slackware/ap/screen-4.0.3-i486-1.tgz
slackware/ap/sudo-1.6.8p12-i486-1.tgz
slackware/ap/sysstat-7.0.0-i486-1.tgz
slackware/ap/texinfo-4.8-i486-1.tgz
slackware/ap/vim-7.1.012-i486-1.tgz
slackware/d/binutils-2.17.50.0.17-i486-1.tgz
slackware/d/bison-2.3-i486-1.tgz
slackware/d/flex-2.5.33-i486-3.tgz
slackware/d/libtool-1.5.24-i486-1.tgz
slackware/d/perl-5.8.8-i486-4.tgz
slackware/l/db42-4.2.52-i486-3.tgz
slackware/l/db44-4.4.20-i486-2.tgz
slackware/l/glibc-2.5-i486-4.tgz
slackware/l/glibc-i18n-2.5-noarch-4.tgz
slackware/l/lzo-2.02-i486-1.tgz
slackware/l/ncurses-5.6-i486-2.tgz
slackware/l/pcre-7.0-i486-1.tgz
slackware/l/popt-1.7-i486-2.tgz
slackware/l/readline-5.2-i486-2.tgz
slackware/l/zlib-1.2.3-i486-2.tgz
slackware/n/inetd-1.79s-i486-8.tgz
slackware/n/iproute2-2.6.16_060323-i486-1.tgz
slackware/n/iputils-s20070202-i486-2.tgz
slackware/n/lftp-3.5.10-i486-1.tgz
slackware/n/links-2.1pre28-i486-1.tgz
slackware/n/lynx-2.8.6rel.5-i486-1.tgz
slackware/n/mtr-0.72-i486-1.tgz
slackware/n/net-tools-1.60-i486-1.tgz
slackware/n/network-scripts-12.0-noarch-4.tgz
slackware/n/ntp-4.2.4p0-i486-1.tgz
slackware/n/openssl-0.9.8e-i486-3.tgz
slackware/n/tcp_wrappers-7.6-i486-1.tgz
slackware/n/traceroute-1.4a12-i386-2.tgz
slackware/n/wget-1.10.2-i486-2.tgz
slackware/n/whois-4.7.21-i486-1.tgz

Après quoi nous allons créer un script bash appelé slackget.sh pour télécharger automatiquement ces paquets :

  vi slackget.sh
#/bin/sh
SERVER=http://ftp.belnet.be
REP=/mirror/ftp.slackware.com/slackware-12.0
mkdir slacktgz
cd slacktgz
for i in `cat ../liste_packages`
do
  if ! wget $SERVER$REP/$i; then
    echo "Erreur de téléchargement"
    exit
  fi
done

On va alors créer un autre script appelé slackinst.sh pour installer automatiquement les paquets dans un modèle de vserver stocké dans la partition /vservers :

vi slackinst.sh
#/bin/sh
PKG=liste_packages
VSR=modele
if [ ! -f /vservers/$VSR ]
then
    mkdir -p /vservers/$VSR
fi
if [ ! -f $PKG ]
then
  echo "Il manque la liste des packages !!"
  exit
fi
if [ $(whoami) != "root" ]
then
  echo "Vous n'etes pas admin !!"
  exit 
fi
for i in $(cat $PKG | awk -F '/' '{print $3}')
do
  if ! installpkg -root /vservers/$VSR/ slacktgz/$i; then
     echo "Probleme lors de l'installation !!"
     exit
  fi
done

Nous allons maintenant créer les scripts de démarrage fonctionnels pour nos vservers. On commence par créer un répertoire rc.d et à l'intérieur de celui-ci le fichier rc.0 :

mkdir rc.d
cd rc.d
vi rc.0
#! /bin/sh
#
PATH=/sbin:/etc:/bin:/usr/bin
if [ -x /etc/rc.d/rc.sysvinit ]; then
  . /etc/rc.d/rc.sysvinit
fi
/bin/stty onlcr
echo "Running shutdown script $0:"
case "$0" in
      *0)
              command="halt"
              ;;
      *6)
              command=reboot
              ;;
      *)
              echo "$0: call me as \"rc.0\" or \"rc.6\" please!"
              exit 1
              ;;
esac
if [ -x /etc/rc.d/rc.local_shutdown ]; then
  /etc/rc.d/rc.local_shutdown stop
fi
if [ -x /etc/rc.d/rc.httpd ]; then
  /etc/rc.d/rc.httpd stop
fi
if [ -r /var/run/mysql/mysql.pid ]; then
  . /etc/rc.d/rc.mysqld stop
fi
if [ -x /etc/rc.d/rc.samba ]; then
  . /etc/rc.d/rc.samba stop
fi
if [ -x /etc/rc.d/rc.nfsd ]; then
  /etc/rc.d/rc.nfsd stop
fi
if [ -x /etc/rc.d/rc.sshd ]; then
  /etc/rc.d/rc.sshd stop
fi
if [ -x /etc/rc.d/rc.saslauthd ]; then
  /etc/rc.d/rc.saslauthd stop
fi
if [ -x /etc/rc.d/rc.openldap ]; then
  /etc/rc.d/rc.openldap stop
fi
if [ -x /etc/rc.d/rc.messagebus ]; then
  sh /etc/rc.d/rc.messagebus stop
fi
if ! /bin/mount | /bin/grep -q 'on / type nfs' ; then
  if [ -x /etc/rc.d/rc.inet1 ]; then
    . /etc/rc.d/rc.inet1 stop
  fi
fi
if /bin/ls /etc/dhcpc/*.pid 1> /dev/null 2> /dev/null ; then
  /sbin/dhcpcd -k 1> /dev/null 2> /dev/null
  sleep 2
fi
if [ -x /sbin/accton -a -r /var/log/pacct ]; then
  echo "Turning off process accounting."
  /sbin/accton
fi
if [ ! "$1" = "fast" ]; then # shutdown did not already kill all processes
  /sbin/killall5 -15
  /bin/sleep 5
  /sbin/killall5 -9
fi
echo "Saving random seed from /dev/urandom in /etc/random-seed."
if [ -r /proc/sys/kernel/random/poolsize ]; then
  /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=$(cat /proc/sys/kernel/random/poolsize) 2> /dev/null
else
  /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=512 2> /dev/null
fi
/bin/chmod 600 /etc/random-seed
$command -w
if [ -d /var/lock/subsys ]; then
  rm -f /var/lock/subsys/*
fi
/bin/sync
 if [ -f /etc/crypttab -a -x /sbin/cryptsetup.static ]; then
  cat /etc/crypttab | grep -v "^#" | grep -v "^$" | while read line; do
    LUKS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f1 -d' ')
    DEV=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f2 -d' ')
    OPTS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f4 -d' ')
    if /sbin/cryptsetup.static isLuks $DEV 2>/dev/null ; then
      echo "Locking LUKS crypt volume '${LUKS}':"
      /sbin/cryptsetup.static luksClose ${LUKS}
  elif echo $OPTS | grep -wq swap ; then
      echo "Erasing encrypted swap '${LUKS}' and restoring normal swap on ${DEV}:"
      /sbin/cryptsetup.static remove ${LUKS}
      mkswap $DEV
    fi
  done
  fi
  /bin/sync
  /bin/sleep 3
  wait

Le fichier rc.6 qui sert au redémarrage des vservers est identique à rc.0, on se contente donc de le dupliquer :

  cp -a rc.0 rc.6

Il est alors temps de créer le fichierrc.K qui est chargé de l'arrêt des processus de nos vservers :

vi rc.K
#! /bin/sh
#
PATH=/sbin:/bin:/usr/bin:/usr/sbin
if [ -x /etc/rc.d/rc.keymap ]; then
  . /etc/rc.d/rc.keymap
fi
if [ -x /etc/rc.d/rc.sysvinit ]; then
  . /etc/rc.d/rc.sysvinit
fi
if [ -x /sbin/accton -a -r /var/log/pacct ]; then
  echo "Turning off accounting."
  /sbin/accton
fi
if [ -x /etc/rc.d/rc.local_shutdown ]; then
  /etc/rc.d/rc.local_shutdown stop
fi
if [ -x /etc/rc.d/rc.httpd ]; then
  /etc/rc.d/rc.httpd stop
fi
if [ -x /etc/rc.d/rc.samba ]; then
  . /etc/rc.d/rc.samba stop
fi
if [ -x /etc/rc.d/rc.nfsd ]; then
  /etc/rc.d/rc.nfsd stop
fi
echo "Unmounting remote filesystems."
umount -a -r -t nfs,smbfs,cifs
if [ -x /etc/rc.d/rc.pcmcia ] ; then
  . /etc/rc.d/rc.pcmcia stop
  sleep 5
fi
echo
echo "Sending all processes the SIGHUP signal."
killall5 -1
echo -n "Waiting for processes to hang up"
for loop in 0 1 2 3 4 5 ; do
  sleep 1
  echo -n "."
done
echo
echo "Sending all processes the SIGTERM signal."
killall5 -15
echo -n "Waiting for processes to terminate"
for loop in 0 1 2 3 4 5 ; do
  sleep 1
  echo -n "."
done
echo
echo "Sending all processes the SIGKILL signal."
killall5 -9
echo -n "Waiting for processes to exit"
for loop in 0 1 2 3 4 5 ; do
  sleep 1
  echo -n "."
done
echo
echo "Going to single user mode..."
telinit -t 1 1

Puis on crée le fichier rc.M qui va lancer les processus de nos vservers au démarrage de ceux-ci :

 vi rc.M
#!/bin/sh
#
echo "Going multiuser..."
if [ -x /sbin/ldconfig ]; then
  echo "Updating shared library links:  /sbin/ldconfig &"
  /sbin/ldconfig &
fi
if [ -r /etc/HOSTNAME ]; then
  /bin/hostname $(cat /etc/HOSTNAME | cut -f1 -d .)
else
  echo "darkstar.example.net" > /etc/HOSTNAME
  /bin/hostname darkstar
fi
/bin/dmesg -s 65536 > /var/log/dmesg
if [ -x /etc/rc.d/rc.syslog -a -x /usr/sbin/syslogd -a -d /var/log ]; then
  . /etc/rc.d/rc.syslog start
fi
if [ -x /usr/bin/fc-cache ]; then
  echo "Updating X font indexes:  /usr/bin/fc-cache -f &"
  /usr/bin/fc-cache -f &
fi
if [ -x /etc/rc.d/rc.inet1 ]; then
  . /etc/rc.d/rc.inet1
fi
if [ -x /etc/rc.d/rc.inet2 ]; then
  . /etc/rc.d/rc.inet2
fi
if [ -x /etc/rc.d/rc.ntpd ]; then
  sh /etc/rc.d/rc.ntpd start
fi
/bin/rm -f /var/lock/* /var/spool/uucp/LCK..* /tmp/.X*lock /tmp/core /core 2> /dev/null
if [ -r /tmp/hunt -o -r /tmp/hunt.stats ]; then
  echo "Removing your stale hunt sockets from /tmp."
  /bin/rm -f /tmp/hunt*
fi
chmod 755 / 2> /dev/null
chmod 1777 /tmp /var/tmp
if [ -x /etc/rc.d/rc.messagebus ]; then
  sh /etc/rc.d/rc.messagebus start
fi
if [ -x /etc/rc.d/rc.hald ]; then
  sh /etc/rc.d/rc.hald start
fi
if [ -x /etc/rc.d/rc.dnsmasq ]; then
  /etc/rc.d/rc.dnsmasq start
fi
if [ -x /etc/rc.d/rc.cups ]; then
  if [ -x /etc/rc.d/rc.hplip ]; then
    /etc/rc.d/rc.hplip start
  fi
  /etc/rc.d/rc.cups start
elif [ -x /etc/rc.d/rc.lprng ]; then
  . /etc/rc.d/rc.lprng start
fi
if [ -x /etc/rc.d/rc.atalk ]; then
  /etc/rc.d/rc.atalk
fi
if [ -x /sbin/accton -a -r /var/log/pacct ]; then
  /sbin/accton /var/log/pacct
  chmod 640 /var/log/pacct
  echo "Process accounting turned on."
fi
if [ -x /usr/sbin/crond ]; then
  /usr/sbin/crond -l10 >>/var/log/cron 2>&1
fi
if [ -x /usr/sbin/atd ]; then
  /usr/sbin/atd -b 15 -l 1
fi
if [ -x /etc/rc.d/rc.saslauthd ]; then
  . /etc/rc.d/rc.saslauthd start
fi
if [ -x /etc/rc.d/rc.sendmail ]; then
  . /etc/rc.d/rc.sendmail start
fi
if [ -x /etc/rc.d/rc.font ]; then
  . /etc/rc.d/rc.font
fi
if [ -x /etc/rc.d/rc.keymap ]; then
  . /etc/rc.d/rc.keymap
fi
if [ -x /etc/rc.d/rc.mysqld ]; then
  . /etc/rc.d/rc.mysqld start
fi
if [ -x /etc/rc.d/rc.httpd ]; then
  . /etc/rc.d/rc.httpd start
fi
if [ -x /etc/rc.d/rc.openldap ]; then
  . /etc/rc.d/rc.openldap start
fi
if [ -x /etc/rc.d/rc.samba ]; then
  . /etc/rc.d/rc.samba start
fi
if [ -x /etc/rc.d/rc.sysvinit ]; then
  . /etc/rc.d/rc.sysvinit
fi
if [ -x /etc/rc.d/rc.local ]; then
  . /etc/rc.d/rc.local
fi

On crée le fichier rc.inet2 afin de lancer des processus indispensables :

vi rc.inet2
#!/bin/sh
#
if [ -x /etc/rc.d/rc.rpc ]; then
  sh /etc/rc.d/rc.rpc start
fi
if [ -x /etc/rc.d/rc.syslog -a -d /var/log -a ! -r /var/run/syslogd.pid ]; then
  . /etc/rc.d/rc.syslog start
fi
if [ -x /etc/rc.d/rc.firewall ]; then
  /etc/rc.d/rc.firewall start
fi
if [ -x /etc/rc.d/rc.ip_forward ]; then
  . /etc/rc.d/rc.ip_forward start
fi
if [ -x /etc/rc.d/rc.inetd ]; then
  /etc/rc.d/rc.inetd start
fi
if [ -x /etc/rc.d/rc.sshd ]; then
  echo "Starting OpenSSH SSH daemon:  /usr/sbin/sshd"
  /etc/rc.d/rc.sshd start
fi
if [ -x /etc/rc.d/rc.bind ]; then
  /etc/rc.d/rc.bind start
fi
if [ -x /etc/rc.d/rc.yp ]; then
  . /etc/rc.d/rc.yp start
fi
if [ -x /etc/rc.d/rc.nfsd ]; then
  /etc/rc.d/rc.nfsd start
fi

On va créer le script de démarrage indispensable au bon lancement de nos vservers appelé rc

cd ..
vi rc
if [ $1 -eq 3 ]; then
  echo "entering runlevel 3: multi";
  /etc/rc.d/rc.M
fi
if [ $1 -eq 6 ]; then
  echo "entering runlevel 6: reboot";
  /etc/rc.d/rc.6
fi
if [ $1 -eq 0 ]; then
  echo "entering runlevel 0: shutdown";
  /etc/rc.d/rc.0
fi
if [ $1 -eq 4 ]; then
  echo "entering runlevel 4";
fi
if [ $1 -eq 5 ]; then
  echo "entering runlevel 5";
fi
if [ $1 -eq 1 ]; then
  echo "entering runlevel 1:single";
  /etc/rc.d/rc.K
fi
if [ $1 -eq 2 ]; then
  echo "entering runlevel 2:multi";
  /etc/rc.d/rc.M
fi

On va à présent créer un script pour copier automatiquement nos scripts de démarrage dans notre modèle de vserver :

vi slackrcd.sh
#/bin/sh
VSR=modele
if [ ! -f /vservers/$VSR ]
then
  mkdir -p /vservers/$VSR
fi
if [ $(whoami) != "root" ]
then
  echo "Vous n'etes pas admin !!"
  exit
fi
cp -a rc /vservers/$VSR/etc/init.d
chmod 755 /vservers/$VSR/etc/init.d/rc
rm -rf /vservers/$VSR/dev/*
chmod 444 /vservers/$VSR/etc/rc.d/rc.inet1
cp -a rc.d /vservers/$VSR/etc

On va créer un script chargé de créer nos futurs vservers :

vi newvserver.sh
#!/bin/sh
VSR=modele
NAME=nom_vserver # remplacez nom_vserver par le nom de votre vserver
CONTEXT=1000
vserver ${NAME} build -m skeleton --context ${CONTEXT} --flags lock,virt_mem,virt_uptime,virt_cpu,virt_load,sched_hard,hide_netif
cp -a /vservers/$VSR /vservers/$NAME

On va créer un script pour attribuer une interface réseau virtuelle ainsi qu'une interface loopback (127.0.0.1) à notre vserver :

vi create_eth.sh
#!/bin/sh
NAME=nom_vserver # remplacez nom_vserver par le nom de votre vserver
INET=dummy0 # remplacez dummy0 par l'interface réseau virtuelle de votre vserver
ADIP=192.168.1.1 # remplacez 192.168.1.1 par l'adresse ip de votre vserver
MASK=24 # remplacez 24 par le masque de sous-réseau de votre vserver
mkdir /etc/vservers/$NAME/interfaces/0
echo $INET > /etc/vservers/$NAME/interfaces/0/dev
echo $ADIP > /etc/vservers/$NAME/interfaces/0/ip
echo $MASK > /etc/vservers/$NAME/interfaces/0/prefix
mkdir /etc/vservers/$NAME/interfaces/1
echo lo > /etc/vservers/$NAME/interfaces/1/dev
echo 127.0.0.1 > /etc/vservers/$NAME/interfaces/1/ip
echo 32 > /etc/vservers/$NAME/interfaces/1/prefix

Utilisation des scripts

Nous allons créer un modèle également appelé squelette pour nos futurs vservers. On commence par télécharger nos paquets définis dans le fichier liste_packages en exécutant le script slackget.sh :

chmod 755 slackget.sh
./slackget.sh

On installe les paquets dans notre répertoire /vservers/modele qui va contenir le futur squelette en exécutant le script slackinst.sh :

chmod 755 slackinst.sh
./slackinst.sh

On copie nos scripts de démarrage dans notre modèle de vservers grâce au script slackrcd.sh :

chmod 755 slackrcd.sh
./slackrcd.sh

Notre squelette est maintenant correctement configuré. On va pouvoir créer notre premier véritable vserver grâce aux scripts newvserver.sh et create_eth :

chmod 755 newvserver.sh
./newvserver.sh
chmod 755 create_eth.sh
./create_eth.sh

Derniers paramétrages système

On va demander au système de lancer automatiquement notre vserver à chaque démarrage en ajoutant des lignes au fichier rc.local, vous noterez que l'on demande au système de pouvoir utiliser les vservers grâce à la commande vprocunhide

vi /etc/rc.d/rc.local
# lignes précédentes
/usr/lib/util-vserver/vprocunhide
vserver nom_vserver start

On va demander au système de créer nos modules dummy pour l'interface virtuelle réseau de nos vservers en modifiant le fichier rc.modules :

vi /etc/rc.d/rc.modules

On recherche la ligne modprobe dummy dans le fichier rc.modules :

/modproble dummy

Puis on la décommente et on rajoute les lignes suivantes dans le fichier :

# lignes précédentes
/sbin/modprobe dummy # interface réseau virtuelle du premier vserver
/sbin/modprobe dummy -o dummy1 # interface réseau virtuelle du second vserver
/sbin/modprobe dummy -o dummy2 # interface réseau virtuelle du troisième vserver
/sbin/modprobe dummy -o dummy3 # interface réseau virtuelle du quatrième vserver
# lignes suivantes

La commande dummy -o dummyX permet de créer une nouvelle interface réseau virtuelle pour chacun de nos vservers.

Lancement de la fusée dans l'espace

On va lancer notre premier vserver, attachez votre ceinture :-P On demande au système de pouvoir utiliser les vservers en appelant la commande vprocunhide et on démarre notre vserver grâce à la commande start :

/usr/lib/util-vserver/vprocunhide
vserver nom_vserver start

On va entrer dans notre vserver grâce à la commande enter :

vserver nom_vserver enter

On ressort de notre vserver grâce à la commande exit :

exit

Voici les commandes indispensables pour avoir les informations sur vos vservers et sur leur prise en charge par votre noyau :

vserver-copy --> permet de dupliquer un vserver
vserver-info --> affiche des infos sur le système
vserver-stat --> affiche les infos sur les vservers en cours d'exécution

Sécurisation de l'hôte

Notre vserver est opérationnel et sera désormais lancé automatiquement à chaque démarrage par le système. Par défaut, le daemon sshd est lancé automatiquement en écoute sur le port 22. Que se passe-t-il si le serveur hôte exécute également un daemon sshd sur le port 22 ? Il y aura un conflit entre les deux services ssh et le daemon du vserver ne pourra pas s'exécuter. Il est donc nécessaire de reconfigurer le fichier sshd_config sur l'hôte en lui spécifiant le port d'écoute (23 de préférence car telnet n'est plus couramment utilisé) et en lui spécifiant l'adresse de l'interface réseau physique à écouter :

vi /etc/ssh/sshd_config
# lignes précédentes
Port 23
ListenAddress 192.168.1.254 # Adresse IP du serveur hôte
Protocol 2
# lignes suivantes

On redémarre le service sshd sur l'hôte

/./etc/rc.d/sshd restart

On va configurer le daemon sshd sur le vserver en éditant le fichier sshd_config afin de lui spécifier le port à écouter (22 pour ssh) et en lui spécifiant l'adresse de l'interface réseau virtuelle à écouter :

vi /vserver/nom_vserver/etc/ssh/sshd_config
# lignes précédentes
Port 22
ListenAddress 192.168.1.1 # Adresse IP du vserver
Protocol 2
# lignes suivantes

On redémarre le service sshd sur le vserver :

vserver nom_vserver enter
/./etc/rc.d/rc.sshd restart
logout

Est-ce que l'on est sûr que notre hôte est sécurisé ? Pour le savoir, il faut lancer la commande netstat sur l'hôte en premier lieu :

netstat -aelptu

Exemple de résultat de la commande sur un hôte mal configuré et ayant donc un risque accru de se voir piraté. En effet, la majorité des services écoutent sur toutes les interfaces (amavisd, postfix, spamassassin). On peut le voir grâce à la ligne *:XXX située sous Local Address.
Ici, seul le service sshd est bien configuré car il écoute sur son interface réseau (192.168.1.254 port 23)

Proto Recv-Q Send-Q Local Address        Foreign Address         State      User       Inode      PID/Program name   
tcp        0      0 *:10024              *:*                     LISTEN     root       25424      2698/amavisd (ch16- 
tcp        0      0 *:10025              *:*                     LISTEN     root       25839      4967/master         
tcp        0      0 *:3306               *:*                     LISTEN     root       19327      3724/mysqld         
tcp        0      0 *:netbios-ssn        *:*                     LISTEN     root       19805      3743/smbd           
tcp        0      0 *:netbios-ssn        *:*                     LISTEN     root       19803      3743/smbd           
tcp        0      0 *:783                *:*                     LISTEN     root       24110      4580/spamd.pid
tcp        0      0 192.168.1.254:telnet *:*                     LISTEN     root       17337      3569/sshd                
tcp        0      0 *:x11                *:*                     LISTEN     root       28888      5713/X              
tcp        0      0 *:8080               *:*                     LISTEN     root       26009      5038/havp           
tcp        0      0 *:http               *:*                     LISTEN     root       19360      3736/httpd          
tcp        0      0 *:smtp               *:*                     LISTEN     root       25666      4967/master         
tcp        0      0 *:smtp               *:*                     LISTEN     root       25665      4967/master         
tcp        0      0 *:microsoft-ds       *:*                     LISTEN     root       19804      3743/smbd           
tcp        0      0 *:microsoft-ds       *:*                     LISTEN     root       19802      3743/smbd           

Comme notre hôte ci-dessus n'est pas bien configuré, il faut demander à tous les services d'écouter sur leur interface réseau. Pour ce faire, il faut modifier leur fichier de configuration respectif en rajoutant la commande qui permet d'écouter sur une seule interface. Vous pourrez trouver ces infos sur le net ou par la commande man. Voici ci-dessous quelques exemples de configuration basique.

mysql --> fichier de conf /etc/my.cnf --> bind-address = 127.0.0.1
samba --> fichier de conf /etc/samba/smb.conf --> interfaces = eth0 192.168.1. 127.0.0.
samba --> fichier de conf /etc/samba/smb.conf --> bind interfaces only = true

Lançons maintenant la commande netstat sur un hôte bien configuré pour voir ce que cela donne. On peut voir que les services écoutent sur leur interface réseau respective (localhost:XXX, serveur.example.net:XXX, etc...). Cela signifie que les services ne seront plus accessibles sur les vservers mais uniquement à partir du réseau interne géré par l'hôte. Je suppose ici que l'hôte est un routeur pare-feu.

Proto Recv-Q Send-Q Local Address           Foreign Address         State      User       Inode      PID/Program name   
tcp        0      0 localhost:10024         *:*                     LISTEN     root       25424      2698/amavisd (ch16- 
tcp        0      0 localhost:10025         *:*                     LISTEN     root       25839      4967/master         
tcp        0      0 localhost:svn           *:*                     LISTEN     root       21595      4149/svnserve       
tcp        0      0 localhost:3306          *:*                     LISTEN     root       19327      3724/mysqld         
tcp        0      0 serveur.exa:netbios-ssn *:*                     LISTEN     root       19805      3743/smbd           
tcp        0      0 localhost:netbios-ssn   *:*                     LISTEN     root       19803      3743/smbd           
tcp        0      0 localhost:783           *:*                     LISTEN     root       24110      4580/spamd.pid       
tcp        0      0 serveur.example.ne:8080 *:*                     LISTEN     root       26009      5038/havp           
tcp        0      0 localhost:http          *:*                     LISTEN     root       19360      3736/httpd          
tcp        0      0 serveur.example.net:ipp *:*                     LISTEN     root       19039      3650/cupsd          
tcp        0      0 localhost:ipp           *:*                     LISTEN     root       19038      3650/cupsd          
tcp        0      0 serveur.example.:telnet *:*                     LISTEN     root       17337      3569/sshd           
tcp        0      0 serveur.example.ne:smtp *:*                     LISTEN     root       25666      4967/master         
tcp        0      0 localhost:smtp          *:*                     LISTEN     root       25665      4967/master         
tcp        0      0 localhost:https         *:*                     LISTEN     root       19359      3736/httpd          
tcp        0      0 serveur.ex:microsoft-ds *:*                     LISTEN     root       19804      3743/smbd           
tcp        0      0 localhost:microsoft-ds  *:*                     LISTEN     root       19802      3743/smbd           
tcp        0      0 localhost:2207          *:*                     LISTEN     root       18901      3637/python         

Vérification de la sécurité sur mon vserver personnel appelé « yttrium » (j'ai craqué sur cet élément chimique faisant partie des métaux dits « terres rares », allez donc savoir pourquoi) ;-) :

vserver yttrium enter
netstat -aelptu
Proto Recv-Q Send-Q Local Address           Foreign Address         State      User       Inode      PID/Program name   
tcp        0      0 yttrium.example.net:ssh *:*                     LISTEN     root       1414021    27474/sshd          

Mon vserver est sécurisé, le daemon sshd écoute sur le port 22 sur son interface yttrium.example.net. A savoir que le vserver yttrium est connecté en frontal à l'internet et c'est lui qui gère les accès ssh. J'ai combiné le service ssh avec denyhost qui permet de blacklister dans le fichier /etc/hosts.deny les adresses ip qui tentent de se connecter à mon système sur le port 22 avec une mauvaise authentification par brute force. Pour accéder à mon serveur, il faut donc arriver à rentrer dans yttrium et se connecter sur le port 23 à mon hôte en sachant que j'ai également couplé denyhost au service ssh. Sur yttrium, j'ai désinstallé les commandes lynx, links, wget, telnet, etc. Le pirate potentiel peut toujours tenter de rapatrier ses outils avec scp mais il devra faire vite car l'hôte veille et enregistre l'activité du vserver yttrium ;-)

Thèmes : #administration #articles #installation #noyau #patch #virtualisation #yttrium

Sauf indication contraire, ce document est placé sous licence CC-BY-SA 3.0.