Par yttrium.
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.
Cela sert à plusieurs choses, notamment
samba
, apache
, ftpd
, etc...) à la place de l'hôte ;ssh
, le risque de se voir pirater est alors extrêmement faible. Personnellement, les logs de ma machine hôte sont pratiquement vides désormais =).scp
et les récupérer depuis l'hôte par crontab
.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
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
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
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
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.
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
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.