Cahier 2016 groupe n°3 : Différence entre versions

De Wiki d'activités IMA
(Sécurisation de données via RAID5)
(Sauvegarde complète et automatisée des machines virtuelles)
 
(85 révisions intermédiaires par 3 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 
= Tâche spécifique =
 
= Tâche spécifique =
  
//TODO : Expliquer en quoi consiste notre tâche perso
+
Nous devons mettre en place un système de sauvegarde en réseau pour pouvoir sauvegarder l'état et les données de nos machines virtuelles.
 +
 
 +
Pour cela, nous allons utiliser un serveur de type DAS (Direct Attach Storage).
 +
 
 +
Cela consiste à une baie de stockage directement branchée sur le réseau via un câble et accessible comme n'importe quel périphérique.
 +
 
 +
<center>
 +
{|
 +
| [[Fichier:schema_infra_das.png|thumb|upright=4|Schéma minimaliste de l'infrastructure]]
 +
|}
 +
</center>
  
 
== Gestion du serveur DAS ==
 
== Gestion du serveur DAS ==
 +
 
=== Installation des outils HP ===
 
=== Installation des outils HP ===
  
Ligne 201 : Ligne 212 :
 
</pre>
 
</pre>
  
== Script and cie TODO ==
+
=== Mise en réseau du disque ===
//sauvegarder etat vm OK
+
Lors de la sauvegarde des machines virtuelles, nous aurons besoin d'accéder à notre disque de sauvegarde.
//sauvegarder les vd vm TODO
+
 
//script en sh TODO
+
Pour cela, nous avons mis en place un partage de type NFS (Network File System) :
//cron pour lancer tous les jours TODO
+
<pre>
//faire un listing sur le site TODO
+
apt-get install nfs-kernel-server
//boutons pour commander les vms TODO
+
</pre>
 +
 
 +
 
 +
Il suffit de paramétrer le partage de façon à autoriser un ordinateur distant à accéder à un dossier en particulier (/etc/exports/) :
 +
<pre>
 +
/backup/vm_backup cordouan.insecserv.deule.net(rw,sync,no_root_squash)
 +
</pre>
 +
Ici, on autorise le serveur Cordouan à accéder au sous-dossier /backup/vm_backup/ en lecture et écriture.
 +
 
 +
== Scripts de sauvegarde et de restauration de machine virtuelle ==
 +
=== Commandes utiles ===
 +
Sauvegarder l'état d'une machine virtuelle :
 +
<pre>
 +
xl save -c Deadpool /usr/local/xen/domains/vm_backup/Deadpool.vmbackup
 +
</pre>
 +
 
 +
Restaurer l'état d'une machine virtuelle :
 +
<pre>
 +
xl restore /usr/local/xen/domains/vm_backup/Deadpool.vmbackup
 +
</pre>
 +
 
 +
 
 +
Snapshot des LVM d'une machine virtuelle :
 +
<pre>
 +
lvcreate -l 10%ORIGIN -s -n ima5-Deadpool-home-snapshot /dev/virtual/ima5-Deadpool-home
 +
lvcreate -l 10%ORIGIN -s -n ima5-Deadpool-var-snapshot /dev/virtual/ima5-Deadpool-var
 +
</pre>
 +
 
 +
Suppression des snapshots LVM :
 +
<pre>
 +
lvremove /usr/local/xen/domains/vm_backup/ima5-Deadpool-home-snapshot
 +
lvremove /usr/local/xen/domains/vm_backup/ima5-Deadpool-var-snapshot
 +
</pre>
 +
 
 +
=== Sauvegarde des états des machines virtuelles ===
 +
Nous avons créé un script capable de sauvegarder l'état de toutes les machines virtuelles en cours d’exécution.
 +
 
 +
Ces machines virtuelles sont mis en pause pendant une à deux secondes le temps de la sauvegarde, ce qui est très rapide.
 +
 
 +
Voici le script disponible sur notre serveur DAS (/backup/script_backup/save_running_vm.sh) :
 +
<pre>
 +
#!/bin/bash#
 +
#Script de sauvegarde pour les VM en cours d?exécution
 +
 
 +
DATE=`date +%d%b%Y-%H%M%S`
 +
MOUNTPOINT=/mnt/vm_backup
 +
LIST_VM_FILE=/tmp/vm_list.txt
 +
NFS_SERVER_IP="172.26.64.15"
 +
 
 +
### Create mount point
 +
echo "Creating mount point...";
 +
mkdir -p ${MOUNTPOINT}
 +
 
 +
### Mounting remote nfs share backup drive
 +
 
 +
#[ ! -d ${MOUNTPOINT} ]  && echo "No mount point found, kindly check"; exit 0
 +
echo "Mounting backup nfs...";
 +
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}
 +
 
 +
BACKUPPATH=${MOUNTPOINT}/${DATE}
 +
mkdir -p ${BACKUPPATH}
 +
#[ ! -d ${BACKUPPATH} ]  && echo "No backup directory found"; exit 0
 +
 
 +
### get all running vm
 +
xl vm-list | tail -n +2 | cut -d" " -f7 > ${LIST_VM_FILE}
 +
 
 +
#[ ! -f ${LIST_VM_FILE} ] && echo "No UUID list file found"; exit 0
 +
 
 +
while read VMUUID
 +
do
 +
    echo "Saving ${VMUUID}...";
 +
mkdir -p ${BACKUPPATH}/${VMUUID}/
 +
    xl save -c $VMUUID ${BACKUPPATH}/${VMUUID}/${VMUUID}.vmbackup
 +
done < ${LIST_VM_FILE}
 +
 
 +
### Umounting remote nfs share backup drive
 +
echo "Umounting backup nfs...";
 +
umount ${MOUNTPOINT}
 +
rm ${MOUNTPOINT} -r
 +
echo "ALL DONE !";
 +
</pre>
 +
Le script consiste à monter sur la machine le dossier mis en réseau précédemment, puis il récupère le nom de toutes les machines virtuelles en cours de fonctionnement, et enfin il sauvegarde l'état des machines virtuelles une par une dans des dossiers spécifiques.
 +
 
 +
Une fois terminé, il démonte le dossier monté précédemment.
 +
 
 +
 
 +
Ce script doit être exécuté sur la machine hôte des machines virtuelles, à savoir Cordouan.
 +
 
 +
Pour cela, il suffit d'un petit script avec une commande pour exécuter le script ci-dessus sur une machine distante (/backup/script_backup/save_running_vm_remote.sh) :
 +
<pre>
 +
#!/bin/bash#
 +
ssh root@cordouan.insecserv.deule.net 'bash -s' < save_running_vm.sh
 +
</pre>
 +
 
 +
 
 +
On exécute notre nouveau script :
 +
<pre>
 +
sh /backup/script_backup/save_running_vm_remote.sh
 +
</pre>
 +
 
 +
 
 +
Et on laisse le travail se faire :
 +
<pre>
 +
Creating mount point...
 +
Mounting backup nfs...
 +
Saving Wolverine...
 +
Saving to /mnt/vm_backup/04janv.2017-210539/Wolverine/Wolverine.vmbackup new xl format (info 0x0/0x0/1094)
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
 +
...
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
 +
Saving Ironman...
 +
Saving to /mnt/vm_backup/04janv.2017-210539/Ironman/Ironman.vmbackup new xl format (info 0x0/0x0/919)
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
 +
...
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 30720/32768  93%
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
 +
Saving Batman...
 +
Saving to /mnt/vm_backup/04janv.2017-210539/Batman/Batman.vmbackup new xl format (info 0x0/0x0/1049)
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
 +
...
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
 +
Saving Frotteman...
 +
Saving to /mnt/vm_backup/04janv.2017-210539/Frotteman/Frotteman.vmbackup new xl format (info 0x0/0x0/1056)
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 7168/131072    5%
 +
...
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
 +
Saving Deadpool...
 +
Saving to /mnt/vm_backup/04janv.2017-210539/Deadpool/Deadpool.vmbackup new xl format (info 0x0/0x0/1054)
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 7168/131072    5%
 +
...
 +
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
 +
Umounting backup nfs...
 +
ALL DONE !
 +
</pre>
 +
 
 +
 
 +
Nous pouvons accéder facilement à nos sauvegardes :
 +
<pre>
 +
root@baleine:/backup/vm_backup/04janv.2017-210539# ls
 +
Batman  Deadpool  Frotteman  Ironman  Wolverine
 +
root@baleine:/backup/vm_backup/04janv.2017-210539# cd Deadpool/
 +
root@baleine:/backup/vm_backup/04janv.2017-210539/Deadpool# ls
 +
Deadpool.vmbackup
 +
</pre>
 +
 
 +
=== Sauvegarde des LVM liés aux machines virtuelles ===
 +
Nous avons créé un script qui permet d'enregistrer les LVM d'une machine virtuelle donnée en argument :
 +
<pre>
 +
#!/bin/bash
 +
#Script de sauvegarde pour toutes les LVM souhaitées
 +
#Run with "ssh remote_machine 'bash -s' < /backup/script_backup/save_lvm_data_vm.sh arg"
 +
 
 +
LIST_LVM_FILE=/tmp/lvm_list.txt
 +
VM_NAME=$1
 +
LVM_PATH=/dev/virtual/
 +
LVM_MOUNT_PATH=/mnt/lvm_snap
 +
MOUNTPOINT=/mnt/vm_backup
 +
NFS_SERVER_IP="172.26.64.15"
 +
 
 +
echo "Creating mount point for NFS...";
 +
mkdir -p ${MOUNTPOINT}
 +
 
 +
echo "Mounting backup nfs...";
 +
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}
 +
 
 +
echo "Creating directory for LVM mount point...";
 +
mkdir -p ${LVM_MOUNT_PATH}
 +
 
 +
echo "Cheking for $1 LVM...";
 +
ls ${LVM_PATH} | grep -i $1 | grep -i 'var\|home' > ${LIST_LVM_FILE}
 +
 
 +
while read LVM_NAME
 +
do
 +
    echo "Snapshot of ${LVM_NAME} LVM...";
 +
lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
 +
 +
echo "Mounting ${LVM_NAME}-snapshot...";
 +
mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
 +
 +
echo "Doing the backup of ${LVM_NAME}-snapshot...";
 +
tar -cf ${MOUNTPOINT}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
 +
 +
echo "Unmounting ${LVM_NAME} LVM...";
 +
umount ${LVM_MOUNT_PATH}
 +
 +
echo "Cleaning snapshot of ${LVM_NAME} LVM...";
 +
yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
 +
done < ${LIST_LVM_FILE}
 +
 
 +
rm ${LVM_MOUNT_PATH} -r
 +
 
 +
echo "Unmounting backup NFS...";
 +
umount ${MOUNTPOINT}
 +
 
 +
rm ${MOUNTPOINT} -r
 +
 
 +
echo "ALL DONE !";
 +
</pre>
 +
 
 +
 
 +
On essaye le script pour notre machine virtuelle en mettant "Deadpool" comme argument :
 +
<pre>
 +
Creating mount point for NFS...
 +
Mounting backup nfs...
 +
Creating directory for LVM mount point...
 +
Cheking for Deadpool LVM...
 +
Snapshot of ima5-Deadpool-home LVM...
 +
  Logical volume "ima5-Deadpool-home-snapshot" created
 +
Mounting ima5-Deadpool-home-snapshot...
 +
Doing the backup of ima5-Deadpool-home-snapshot...
 +
tar: Suppression de « / » au début des noms des membres
 +
Unmounting ima5-Deadpool-home LVM...
 +
Cleaning snapshot of ima5-Deadpool-home LVM...
 +
Do you really want to remove active logical volume ima5-Deadpool-home-snapshot? [y/n]:  Logical volume "ima5-Deadpool-home-snapshot" successfully removed
 +
Snapshot of ima5-Deadpool-var LVM...
 +
  Logical volume "ima5-Deadpool-var-snapshot" created
 +
Mounting ima5-Deadpool-var-snapshot...
 +
Doing the backup of ima5-Deadpool-var-snapshot...
 +
tar: Suppression de « / » au début des noms des membres
 +
Unmounting ima5-Deadpool-var LVM...
 +
Cleaning snapshot of ima5-Deadpool-var LVM...
 +
Do you really want to remove active logical volume ima5-Deadpool-var-snapshot? [y/n]:  Logical volume "ima5-Deadpool-var-snapshot" successfully removed
 +
Unmounting backup NFS...
 +
ALL DONE !
 +
</pre>
 +
 
 +
 
 +
On récupère bien nos fichiers :
 +
<pre>
 +
root@baleine:/backup/vm_backup# ls
 +
ima5-Deadpool-home-snapshot.tar  ima5-Deadpool-var-snapshot.tar
 +
</pre>
 +
 
 +
=== Sauvegarde complète et automatisée des machines virtuelles ===
 +
Maintenant, il faut enregistrer à la fois les états des machines virtuelles allumées avec leurs LVM, ainsi que les LVM des machines virtuelles éteintes.
 +
 
 +
Pour celà, nous avons modifié le script et ajouter un fichier de configuration comportant le nom de toutes les machines virtuelles que l'on souhaite sauvegarder.
 +
 
 +
Le script reste largement simplifiable, car il s'agit ici des deux précédents scripts plus ou moins arrangés.
 +
 
 +
Lors de la soutenance, nous avons modifié le script pour qu'il sauvegarde aussi le disque image des machines virtuelles, ainsi, une sauvegarde totale de la machine virtuelle est effectuée, et non pas seulement l'état mémoire et les LVM.
 +
 
 +
De plus la machine virtuelle est mise en pause durant sa sauvegarde.
 +
 
 +
<pre>
 +
#!/bin/bash#
 +
#Script effectuant le backup de toutes les VM
 +
 
 +
DATE=`date +%d%b%Y-%H%M%S`
 +
MOUNTPOINT=/mnt/vm_backup
 +
LVM_MOUNT_PATH=/mnt/lvm_snap
 +
LVM_PATH=/dev/virtual/
 +
LIST_VM_FILE=/tmp/vm_list.txt
 +
LIST_VM_CLOSED=/tmp/vm_closed_list.txt
 +
LIST_LVM_FILE=/tmp/lvm_list.txt
 +
NFS_SERVER_IP="172.26.64.15"
 +
BACKUPPATH=${MOUNTPOINT}/${DATE}
 +
CONFIGPATH=${MOUNTPOINT}/vm_backup.cfg
 +
 
 +
### Create mount point
 +
echo "Creating mount point...";
 +
mkdir -p ${MOUNTPOINT}
 +
 
 +
echo "Creating directory for LVM mount point...";
 +
mkdir -p ${LVM_MOUNT_PATH}
 +
 
 +
### Mounting remote nfs share backup drive
 +
echo "Mounting backup nfs...";
 +
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}
 +
 
 +
echo "Creating dated backup folder...";
 +
mkdir -p ${BACKUPPATH}
 +
 
 +
### get all running vm
 +
xl vm-list | tail -n +2 | cut -d" " -f7 > ${LIST_VM_FILE}
 +
 
 +
while read VMUUID
 +
do
 +
mkdir -p ${BACKUPPATH}/${VMUUID}/
 +
 +
    echo "Saving ${VMUUID} state...";
 +
    xl save -p $VMUUID ${BACKUPPATH}/${VMUUID}/${VMUUID}.vmbackup
 +
 
 +
    echo "Creating disk.img snapshot...";
 +
    qemu-img create -f qcow2 -b /usr/local/xen/domains/${VMUUID}/disk.img /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
    modprobe nbd max_part=63
 +
    qemu-nbd -c /dev/nbd0 /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
 
 +
    echo "Mounting ${LVM_NAME} disk.img...";
 +
    mount /dev/nbd0 ${LVM_MOUNT_PATH}
 +
 
 +
    echo "Doing the backup of disk...";
 +
    tar -cf ${BACKUPPATH}/${VMUUID}/disk.img-snapshot.tar ${LVM_MOUNT_PATH}
 +
 
 +
    echo "Unmounting ..."
 +
    umount ${LVM_MOUNT_PATH}
 +
 
 +
    echo "Cleaning snapshot..."
 +
    rm /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
 
 +
echo "Cheking for ${VMUUID} LVM...";
 +
ls ${LVM_PATH} | grep -i ${VMUUID} | grep -i 'var\|home' > ${LIST_LVM_FILE}
 +
 +
while read LVM_NAME
 +
do
 +
echo "Snapshot of ${LVM_NAME} LVM...";
 +
lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
 +
 +
echo "Mounting ${LVM_NAME}-snapshot...";
 +
mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
 +
 +
echo "Doing the backup of ${LVM_NAME}-snapshot...";
 +
tar -cf ${BACKUPPATH}/${VMUUID}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
 +
 +
echo "Unmounting ${LVM_NAME} LVM...";
 +
umount ${LVM_MOUNT_PATH}
 +
 +
echo "Cleaning snapshot of ${LVM_NAME} LVM...";
 +
yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
 +
done < ${LIST_LVM_FILE}
 +
xl unpause ${VMUUID}
 +
done < ${LIST_VM_FILE}
 +
 
 +
### get all closed vm
 +
awk 'NR==FNR {t[$0]++; next} !t[$0]' ${LIST_VM_FILE} ${CONFIGPATH} > ${LIST_VM_CLOSED}
 +
 
 +
while read VMUUID
 +
do
 +
mkdir -p ${BACKUPPATH}/${VMUUID}/
 +
echo "Creating disk.img snapshot...";
 +
qemu-img create -f qcow2 -b /usr/local/xen/domains/${VMUUID}/disk.img /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
modprobe nbd max_part=63
 +
qemu-nbd -c /dev/nbd0 /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
 
 +
echo "Mounting ${LVM_NAME} disk.img...";
 +
mount /dev/nbd0 ${LVM_MOUNT_PATH}
 +
 
 +
echo "Doing the backup of disk...";
 +
tar -cf ${BACKUPPATH}/${VMUUID}/disk.img-snapshot.tar ${LVM_MOUNT_PATH}
 +
 
 +
echo "Unmounting ..."
 +
umount ${LVM_MOUNT_PATH}
 +
 
 +
        echo "Cleaning snapshot..."
 +
        rm /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
 +
 +
echo "Cheking for ${VMUUID} LVM...";
 +
ls ${LVM_PATH} | grep -i ${VMUUID} | grep -i 'var\|home' > ${LIST_LVM_FILE}
 +
 +
while read LVM_NAME
 +
do
 +
echo "Snapshot of ${LVM_NAME} LVM...";
 +
lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
 +
 +
echo "Mounting ${LVM_NAME}-snapshot...";
 +
mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
 +
 +
echo "Doing the backup of ${LVM_NAME}-snapshot...";
 +
tar -cf ${BACKUPPATH}/${VMUUID}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
 +
 +
echo "Unmounting ${LVM_NAME} LVM...";
 +
umount ${LVM_MOUNT_PATH}
 +
 +
echo "Cleaning snapshot of ${LVM_NAME} LVM...";
 +
yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
 +
done < ${LIST_LVM_FILE}
 +
 
 +
done < ${LIST_VM_CLOSED}
 +
 
 +
###Cleaning lvm mount path
 +
rm ${LVM_MOUNT_PATH} -r
 +
 
 +
### Umounting remote nfs share backup drive
 +
echo "Umounting backup nfs...";
 +
umount ${MOUNTPOINT}
 +
rm ${MOUNTPOINT} -r
 +
echo "ALL DONE !";
 +
</pre>
 +
 
 +
 
 +
Une fois avoir exécuté celui-ci sur Cordouan, on peut observer le résultat obtenu sur notre DAS :
 +
<pre>
 +
tree /backup/vm_backup/05janv.2017-205758/
 +
</pre>
 +
<pre>
 +
/backup/vm_backup/06janv.2017-175650/
 +
├── Batman
 +
│   ├── Batman.vmbackup
 +
│   ├── disk.img-snapshot.tar
 +
│   ├── ima5-Batman-home-snapshot.tar
 +
│   └── ima5-Batman-var-snapshot.tar
 +
├── Deadpool
 +
│   ├── Deadpool.vmbackup
 +
│   ├── disk.img-snapshot.tar
 +
│   ├── ima5-Deadpool-home-snapshot-snapshot.tar
 +
│   ├── ima5-Deadpool-home-snapshot.tar
 +
│   ├── ima5-Deadpool-var-snapshot-snapshot.tar
 +
│   └── ima5-Deadpool-var-snapshot.tar
 +
├── Flash
 +
│   ├── disk.img-snapshot.tar
 +
│   └── Flash.vmbackup
 +
├── Frotteman
 +
│   ├── disk.img-snapshot.tar
 +
│   ├── Frotteman.vmbackup
 +
│   ├── ima5-Frotteman-home-snapshot.tar
 +
│   └── ima5-Frotteman-var-snapshot.tar
 +
├── GreenArrow
 +
│   ├── disk.img-snapshot.tar
 +
│   ├── GreenArrow.vmbackup
 +
│   ├── ima5-GreenArrow-home-snapshot.tar
 +
│   └── ima5-GreenArrow-var-snapshot.tar
 +
├── Ironman
 +
│   ├── disk.img-snapshot.tar
 +
│   └── Ironman.vmbackup
 +
├── Mulan
 +
│   ├── disk.img-snapshot.tar
 +
│   ├── ima5-Mulan-home-snapshot.tar
 +
│   ├── ima5-Mulan-var-snapshot.tar
 +
│   └── Mulan.vmbackup
 +
├── Spiderman
 +
│   └── Spiderman.vmbackup
 +
└── Wolverine
 +
    ├── disk.img-snapshot.tar
 +
    ├── wolverine-home-snapshot.tar
 +
    ├── wolverine-var-snapshot.tar
 +
    └── Wolverine.vmbackup
 +
</pre>
 +
 
 +
 
 +
Pour automatiser notre tâche, nous avons configuré Cron.
 +
 
 +
Cet utilitaire permet d’exécuter une commande automatiquement à n'importe quel moment : toutes les 2 heures, tous les jeudis à 15h48...
 +
 
 +
Nous avons donc configuré Cron pour exécuter une sauvegarde toutes les 6 heures :
 +
<pre>
 +
crontab -e
 +
</pre>
 +
<pre>
 +
# m h  dom mon dow  command
 +
0 */6 * * * sh /backup/script_backup/vm_backup_script_remote.sh
 +
</pre>
 +
 
 +
 
 +
Le script de sauvegarde automatique pourrait être modifié de manière à ne garder que les 10 dernière sauvegardes sur notre DAS pour ne pas le surcharger ou ne pas supprimer manuellement toutes les semaines les sauvegardes trop vielles.
 +
 
 +
=== Restauration d'une machine virtuelle ===
 +
Nous avons créé un script capable de restaurer une machine virtuelle depuis un dossier de sauvegarde voulu :
 +
<pre>
 +
#!/bin/bash#
 +
 
 +
#UTILISATION : ./restore_state_vm.sh Deadpool 05janv.2017-205758
 +
#UTILISATION : ./restore_state_vm.sh VM_NAME FOLDER_NAME
 +
 
 +
VM_NAME=$1
 +
DATE_FOLDER=$2
 +
MOUNTPOINT=/mnt/vm_backup
 +
NFS_SERVER_IP="172.26.64.15"
 +
 
 +
### Create mount point
 +
echo "Creating mount point...";
 +
mkdir -p ${MOUNTPOINT}
 +
 
 +
### Mounting remote nfs share backup drive
 +
echo "Mounting backup nfs...";
 +
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}
 +
 
 +
### restoring vm
 +
echo "Restoring ${VM_NAME} ...";
 +
xl destroy ${VM_NAME}
 +
xl restore ${MOUNTPOINT}/${DATE_FOLDER}/${VM_NAME}/${VM_NAME}.vmbackup
 +
echo "${VM_NAME} RESTORED !";
 +
 
 +
### Umounting remote nfs share backup drive
 +
echo "Umounting backup nfs...";
 +
umount ${MOUNTPOINT}
 +
 
 +
#BUSY ERROR
 +
#rm ${MOUNTPOINT} -r
 +
echo "ALL DONE !";
 +
</pre>
 +
 
 +
 
 +
Le script fonctionne, mais le disque en réseau devient occupé et il est impossible de le démonter de Cordouan.
 +
 
 +
Il est nécessaire d'éteindre la machine virtuelle, puis de la redémarrer pour pouvoir démonter le disque réseau correctement.
 +
 
 +
Ici, la restauration des LVM n'est pas effectuée.
 +
 
 +
=== Amélioration du site ===
 +
 
 +
On installe de quoi exécuter du PHP sur notre site web :
 +
 
 +
<pre>
 +
apt-get install php5-common libapache2-mod-php5 php5-cli
 +
</pre>
 +
 
 +
 
 +
On a revu un peu l'index de notre page :
 +
<pre>
 +
<html>
 +
 
 +
<link rel="icon" type="image/png" href="images/Deadpool_ico.png" />
 +
<meta charset="utf-8">
 +
<!--[if IE]><link rel="shortcut icon" type="image/x-icon" href="images/Deadpool_ico.png" /><![endif]-->
 +
 
 +
  <head>
 +
    <title>PISCINEMORTE.NET</title>
 +
  </head>
 +
  <body bgcolor=#CEECF5>
 +
 
 +
<center>
 +
 
 +
          <img src="images/Deadpool.png" height="25%" width="25%">
 +
 
 +
          <h1><FONT color="#0B0B61">Bienvenue sur PISCINEMORTE.NET !</FONT></h1>
 +
 
 +
 
 +
        <p><FONT color="#0B0B61">Ce site internet est dédié à notre projet de système et réseaux à l'école Polytech Lille.</FONT></p>
 +
<p><FONT color="#0B0B61">Par Geoffrey PIEKACZ et Nathan RICHEZ</FONT></p>
 +
<p><FONT color="#0B0B61">Lien vers <a href="http://projets-ima.plil.net/mediawiki/index.php?title=Cahier_2016_groupe_n%C2%B03">notre Wiki</a></FONT></p>
 +
</center>
 +
  </body>
 +
</html>
 +
</pre>
 +
 
 +
 
 +
Nous devons maintenant trouver le moyen d'afficher les machines virtuelles démarrées sur notre site.
 +
 
 +
Pour cela, nous nous sommes inspirés de la commande ci-dessous :
 +
 
 +
<pre>
 +
ssh [user]@[server] 'bash -s' < [local_script]
 +
</pre>
 +
Cette commande va nous permettre de lancer un script de Deadpool vers Cordouan.
 +
 
 +
 
 +
Le script est le suivant (/var/www/www.piscinemorte.net/show_vm_list.sh):
 +
<pre>
 +
#!/bin/bash
 +
 +
ssh root@cordouan.insecserv.deule.net 'xl vm-list'
 +
</pre>
 +
 
 +
 
 +
Il affichera une liste des VM démarrées via un code PHP ajouté dans notre index :
 +
<pre>
 +
<?php
 +
echo "Liste des machines virtuelles en cours de fonctionnement :";
 +
$output = shell_exec('sh /var/www/www.piscinemorte.net/show_vm_list.sh');
 +
echo "$output";
 +
?>
 +
</pre>
 +
 
 +
 
 +
Ensuite, nous avons rencontré un problème.
 +
 
 +
En effet, cette commande fonctionne dans un bash mais le résultat n'est pas directement affiché sur notre site.
 +
 
 +
Cela s'explique par le fait que nous avons exécuté cette commande en root mais que apache via php execute cette commande dans un shell via l'utilisateur www-data.
 +
 
 +
Nous avions précédemment créé une clé pour pouvoir exécuter notre commande en root sans remettre à chaque fois le mot de passe.
 +
 
 +
Nous avons donc réitéré la démarche pour l'utilisateur www-data:
 +
<pre>
 +
root@Deadpool:/home/Deadpool-key# ssh-keygen -t rsa  //on génère une clé sans mot de passe dans ~/.ssh sauvegardée dans /root/.ssh/id_rsa
 +
</pre>
 +
 
 +
 
 +
On copiera cette clé sur Cordouan et sur Baleine (notre DAS) pour permettre à nos machines de se connecter en ssh sans demande de mot de passe :
 +
<pre>
 +
root@Deadpool:~# cp /root/.ssh/id_rsa /var/www/.ssh/  //pour copier notre clé pour l'utilisateur www-data
 +
root@Deadpool:~# chown www-data:www-data /var/www/.ssh/ -R  // pour donner les droits de manière récursive à www-data
 +
root@Deadpool:~# sudo -u www-data -s                  //Pour changer l'utilisateur à www-data
 +
</pre>
 +
 
 +
 
 +
Ainsi, notre commande est bien exécutée depuis notre site et affiche toutes les VM fonctionnant à l'instant t.
 +
<center>
 +
{|
 +
| [[Fichier:piscinemorte_vm_list.png|thumb|upright=4|Affichage des machines virtuelles sur notre site]]
 +
|}
 +
</center>
  
 
= Tâches communes =
 
= Tâches communes =
Ligne 270 : Ligne 862 :
  
 
=== Configuration de la machine virtuelle ===
 
=== Configuration de la machine virtuelle ===
 
 
 
On utilise lvcreate pour faire en sorte que les répertoires var et home de la machine virtuelle soient sur des partitions LVM de l'hôte :
 
On utilise lvcreate pour faire en sorte que les répertoires var et home de la machine virtuelle soient sur des partitions LVM de l'hôte :
 
<pre>
 
<pre>
Ligne 294 : Ligne 884 :
 
<pre>
 
<pre>
 
xl destroy Deadpool
 
xl destroy Deadpool
 +
</pre>
 +
 +
 +
On transforme nos disques logiques en partition ext4 :
 +
<pre>
 +
mkfs.ext4 /dev/xvdb
 +
mkfs.ext4 /dev/xvdc
 +
</pre>
 +
 +
 +
On sauvegarde les fichiers déjà existants dans home et var et on les met dans nos nouvelles partitions :
 +
<pre>
 +
mkdir /mnt/home/
 +
mkdir /mnt/var/
 +
mount /dev/xvdc/ /mnt/home/
 +
mount /dev/xvdb/ /mnt/var/
 +
cp -r /home/* /mnt/home/
 +
cp -r /var/* /mnt/var/
 +
</pre>
 +
 +
 +
Afin de monter automatiquement notre partition à chaque démarrage, il suffit d'ajouter les lignes suivantes dans fstab :
 +
<pre>
 +
nano /etc/fstab
 +
</pre>
 +
<pre>
 +
/dev/xvdc /home ext3 defaults 0 2
 +
/dev/xvdb /var ext3 defaults 0 2
 +
</pre>
 +
 +
 +
Après redémarrage de la machine virtuelle, on vérifie si nos disques sont montés automatiquement :
 +
<pre>
 +
df -h
 +
</pre>
 +
<pre>
 +
Filesystem      Size  Used Avail Use% Mounted on
 +
/dev/xvda2      3.9G  700M  3.0G  19% /
 +
udev            10M    0  10M  0% /dev
 +
tmpfs            99M  13M  87M  13% /run
 +
tmpfs          247M    0  247M  0% /dev/shm
 +
tmpfs          5.0M    0  5.0M  0% /run/lock
 +
tmpfs          247M    0  247M  0% /sys/fs/cgroup
 +
/dev/xvdb      9.8G  262M  9.0G  3% /var
 +
/dev/xvdc      9.8G  23M  9.2G  1% /home
 
</pre>
 
</pre>
  
Ligne 370 : Ligne 1 005 :
 
Decrypted correctly: 100%
 
Decrypted correctly: 100%
 
</pre>
 
</pre>
La clé est décrypté en quelques secondes !
+
La clé est décryptée en quelques secondes !
  
 
=== Cassage de clef WPA-PSK par force brute ===
 
=== Cassage de clef WPA-PSK par force brute ===
blablabla
+
 
 +
 
 +
De même que pour le cassage de clé WEP, nous allons utiliser les mêmes outils mais pour un craquage WPA.
 +
 
 
<pre>
 
<pre>
airmon-ng start wlx40a5ef01370a
+
airmon-ng start wlx40a5ef01370a   //On lance le mode monitoring sur notre carte wifi
crunch 8 8 0123456789 > dico.txt
+
airmon-ng mon0                    //On liste ensuite toutes les interfaces wifi disponible
airmon-ng check kill
+
crunch 8 8 0123456789 > dico.txt //On sait que la clé possède 8 chiffres, on créé donc un dictionnaire contenant toutes les possibilités de clé avec l'outil crunch
airodump-ng --encrypt wpa wlx40a5ef01370a
+
airodump-ng --encrypt wpa wlx40a5ef01370a //Nous choisissons ensuite le réseau à attaquer en wpa
 
</pre>
 
</pre>
 
<pre>
 
<pre>
Ligne 407 : Ligne 1 045 :
  
  
blablabla
+
On observe ensuite (seulement) la cible choisie (cracotte03)
 
<pre>
 
<pre>
airodump-ng --essid cracotte03 -c 13 --bssid 04:DA:D2:9C:50:52 -w dump wlx40a5ef01370a
+
airodump-ng --essid cracotte03 -c 13 --bssid 04:DA:D2:9C:50:52 -w dump mon0
 
</pre>
 
</pre>
 
<pre>
 
<pre>
Ligne 424 : Ligne 1 062 :
  
  
blablabla
+
On lance l'attaque avec le handshake récupéré :
 
<pre>
 
<pre>
 
#aireplay-ng --deauth=5 -a 04:DA:D2:9C:50:52
 
#aireplay-ng --deauth=5 -a 04:DA:D2:9C:50:52
 
</pre>
 
</pre>
 +
  
 
+
Et enfin, on lance le décodage grâce au fichier généré et notre dictionnaire:
Et enfin, on lance le décodage grâce au dictionnaire généré :
 
 
<pre>
 
<pre>
 
aircrack-ng dump-03.cap -w dico.txt -l KEY
 
aircrack-ng dump-03.cap -w dico.txt -l KEY
 
</pre>
 
</pre>
Malheuresement, le décodage étant très long avec un eePC, nous avons recommencé et relancé le décodage sur notre Zabeth préférée.
+
 
 +
Malheureusement, le décodage étant très long avec un eePC, nous avons recommencé et relancé le décodage sur notre Zabeth préférée.
  
  
Ligne 762 : Ligne 1 401 :
 
<pre>
 
<pre>
 
mount /dev/md0 /mnt
 
mount /dev/md0 /mnt
 +
</pre>
 +
 +
 +
Après avoir créer un fichier dans notre RAID5, nous supprimons une des répartitions pour voir si le RAID5 se reconstruit correctement :
 +
<pre>
 +
mdadm --set-faulty /dev/md0 /dev/xvdd2
 +
mdadm --remove /dev/md0 /dev/xvdd2
 +
</pre>
 +
 +
 +
On voit que la partition a bien été supprimée et nos données toujours présents :
 +
<pre>
 +
cat /proc/mdstat
 +
</pre>
 +
<pre>
 +
Personalities : [raid6] [raid5] [raid4]
 +
md0 : active raid5 xvdd1[0] xvdd3[2]
 +
      2095104 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [U_U]
 +
</pre>
 +
<pre>
 +
mount /dev/md0 /mnt
 +
</pre>
 +
<pre>
 +
[88763.077524] EXT4-fs (md0): recovery complete
 +
[88763.077545] EXT4-fs (md0): mounted filesystem with ordered data mode. Opts: (null)
 +
<pre>
 +
root@Deadpool:/mnt# ls
 +
lost+found  test.txt
 +
</pre>
 +
 +
 +
Nous remettons la partition :
 +
<pre>
 +
mdadm --add /dev/md0 /dev/xvdd2
 +
</pre>
 +
 +
 +
Et on observe la reconstruction grâce à cat /proc/mdstat :
 +
<pre>
 +
Personalities : [raid6] [raid5] [raid4]
 +
md0 : active raid5 xvdd2[3] xvdd1[0] xvdd3[2]
 +
      2095104 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [U_U]
 +
      [==========>..........]  recovery = 51.9% (544664/1047552) finish=0.2min speed=30259K/sec
 
</pre>
 
</pre>
  
 
=== Cryptage de données ===
 
=== Cryptage de données ===
 +
 +
Dans cette partie, nous allons voir comment crypter des données sur une carte SD.
 +
 +
On cherche notre carte sd dans dev :
 +
 +
<pre>
 +
ls /dev
 +
</pre>
 +
 +
puis on va configurer notre carte :
 +
 +
<pre>
 +
fdisk /dev/mmcblk1
 +
  "d pour supprimer les partitions 1-2-3"
 +
  "n pour ajouter des partitions"
 +
  "w pour enregistrer"
 +
</pre>
 +
 +
On créé donc une unique partition de taille 15G sur mmcblk1p1.
 +
 +
On va maintenant configurer la carte SD en type Luks avec un chiffrement aes et un algorithme de hachage SHA256:
 +
 +
<pre>
 +
cryptsetup luksFormat -c eas -h sha256 /dev/mmcblk1
 +
</pre>
 +
 +
Avec la phrase secrète : pasglop
 +
 +
On peut vérifier les infos de la partitions avec :
 +
 +
<pre>
 +
cryptsetup luksDump /dev/mmcblk1
 +
</pre>
 +
 +
On ouvre notre partition cryptée avec :
 +
 +
<pre>
 +
cryptsetup luksOpen /dev/mmcblk1
 +
</pre>
 +
en saisissant la phrase secrète.
 +
 +
et on ajoute des fichiers :
 +
<pre>
 +
mkfs.ext3 /dev/mapper/kadoc
 +
</pre>
 +
 +
On décide de créer un dossier contenant un fichier txt contenant une phrase.
 +
Pour écrire dedans il faut monter notre carte :
 +
 +
<pre>
 +
 +
mount -t ext3 /dev/mapper/kadoc /mnt/    pour monter la partition.
 +
 +
umount /mnt/                            pour démonter la partition.   
 +
</pre>
 +
 +
Il faut re-encrypter notre partition avec
 +
 +
<pre>
 +
cryptsetup luksClose kadoc
 +
</pre>
 +
 +
On peut vérifier avec GParted que notre partition n'est plus accessible, à moins d'avoir le mot de passe pour la décrypter.
 +
<pre>
 +
gparted /dev/mmcblk1
 +
</pre>
  
 
== Création de deux points d'accès Wi-Fi avec serveur d'authentification FreeRADIUS ==
 
== Création de deux points d'accès Wi-Fi avec serveur d'authentification FreeRADIUS ==
Ligne 795 : Ligne 1 543 :
  
 
client VLAN3 {
 
client VLAN3 {
         ipaddr = 172.20.3.0
+
         ipaddr = 10.60.4.0
 
         secret = mot_de_passe
 
         secret = mot_de_passe
 
}
 
}
Ligne 842 : Ligne 1 590 :
  
 
dot11 ssid Deadpool
 
dot11 ssid Deadpool
vlan 3
+
vlan 4
 
authentication open eap eap_deadpool
 
authentication open eap eap_deadpool
 
authentication network-eap eap_deadpool
 
authentication network-eap eap_deadpool
Ligne 850 : Ligne 1 598 :
  
 
interface Dot11Radio0
 
interface Dot11Radio0
encryption vlan 3 mode ciphers aes-ccm tkip
+
encryption vlan 4 mode ciphers aes-ccm tkip
 
ssid Deadpool
 
ssid Deadpool
 
exit
 
exit
  
interface Dot11Radio0.3
+
interface Dot11Radio0.4
encapsulation dot1Q 3
+
encapsulation dot1Q 4
 
no ip route-cache
 
no ip route-cache
bridge-group 3
+
bridge-group 4
bridge-group 3 subscriber-loop-control
+
bridge-group 4 subscriber-loop-control
bridge-group 3 spanning-disabled
+
bridge-group 4 spanning-disabled
bridge-group 3 block-unknown-source
+
bridge-group 4 block-unknown-source
no bridge-group 3 source-learning
+
no bridge-group 4 source-learning
no bridge-group 3 unicast-flooding  
+
no bridge-group 4 unicast-flooding  
 
exit
 
exit
  
interface GigabitEthernet0.3
+
interface GigabitEthernet0.4
encapsulation dot1Q 3
+
encapsulation dot1Q 4
bridge-group 3
+
bridge-group 4
 
exit
 
exit
 
   
 
   
Ligne 881 : Ligne 1 629 :
 
auto wlan0
 
auto wlan0
 
iface wlan0 inet static
 
iface wlan0 inet static
  address 172.20.3.3
+
  address 10.60.4.10
 
  netmask 255.255.255.0
 
  netmask 255.255.255.0
  gateway 172.20.3.254
+
  gateway 10.60.4.1
 
  wpa-ssid Deadpool
 
  wpa-ssid Deadpool
 
  wpa-key-mgmt WPA-EAP
 
  wpa-key-mgmt WPA-EAP
Ligne 894 : Ligne 1 642 :
 
<pre>
 
<pre>
 
ifup wlan0
 
ifup wlan0
ifconfig
+
iwconfig
 
</pre>
 
</pre>
 
<pre>
 
<pre>
//résultats à recup
+
wlan0    IEEE 802.11bgn  ESSID:"Deadpool" 
 +
          Mode:Managed  Frequency:2.447 GHz  Access Point: 44:AD:D9:5F:87:00 
 +
          Bit Rate=1 Mb/s  Tx-Power=20 dBm 
 +
          Retry short limit:7  RTS thr:off  Fragment thr:off
 +
          Encryption key:off
 +
          Power Management:off
 +
          Link Quality=59/70  Signal level=-51 dBm 
 +
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
 +
          Tx excessive retries:1  Invalid misc:53  Missed beacon:0
 +
</pre>
 +
 
 +
 
 +
On arrive à ping notre eePC depuis la machine virtuelle :
 +
<pre>
 +
root@Deadpool:/# ping 10.60.4.10
 +
PING 10.60.4.10 (10.60.4.10) 56(84) bytes of data.
 +
64 bytes from 10.60.4.10: icmp_seq=1 ttl=62 time=1.22 ms
 +
64 bytes from 10.60.4.10: icmp_seq=2 ttl=62 time=1.57 ms
 +
64 bytes from 10.60.4.10: icmp_seq=3 ttl=62 time=8.32 ms
 +
64 bytes from 10.60.4.10: icmp_seq=4 ttl=62 time=9.30 ms
 +
64 bytes from 10.60.4.10: icmp_seq=5 ttl=62 time=1.55 ms
 +
64 bytes from 10.60.4.10: icmp_seq=6 ttl=62 time=1.29 ms
 +
^C
 +
--- 10.60.4.10 ping statistics ---
 +
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
 +
rtt min/avg/max/mdev = 1.226/3.879/9.304/3.501 ms
 
</pre>
 
</pre>
  
Ligne 912 : Ligne 1 685 :
 
== DHCP et PCBX ==
 
== DHCP et PCBX ==
 
=== Configuration du DHCP ===
 
=== Configuration du DHCP ===
 +
On installe de quoi faire un serveur DHCP sur notre eePC :
 +
<pre>
 +
apt-get install isc-dhcp-server
 +
</pre>
 +
 +
 +
On configure notre serveur DHCP via le fichier de configuration (/etc/dhcp/dhcpd.conf)
 +
<pre>
 +
    option domain-name "piscinemorte.net";
 +
    option domain-name-servers ns.piscinemorte.net;
 +
   
 +
    subnet 10.60.4.0 netmask 255.255.255.0 {
 +
        range 10.60.4.11 10.60.4.30
 +
        option routers 10.60.4.254
 +
    }
 +
</pre>
 +
 +
 +
Après avoir redémarré notre serveur DHCP, on se connecte facilement à notre point d'accès grâce au DHCP qui nous attribue une adresse IP dans la plage voulue :
 +
<center>
 +
{|
 +
| [[Fichier:Screenshot_2016-12-12-11-08-16.png|thumb|upright=1|Informations de connexion sur un Sony Xperia S]]
 +
| [[Fichier:Bvxfbdbd.jpg|thumb|upright=1|Informations de connexion sur un Iphone]]
 +
|}
 +
</center>
 +
 
=== Configuration et utilisation du PCBX ===
 
=== Configuration et utilisation du PCBX ===
 +
On installe Asterisk pour créer un serveur permettant une communication SIP :
 +
<pre>
 +
apt-get install asterisk
 +
</pre>
 +
 +
 +
Configuration via /etc/asterisk/sip.conf :
 +
<pre>
 +
[general]
 +
allowguest=no
 +
alwaysauthreject=yes
 +
contactacl=local_ip_acl
 +
hasvoicemail = yes
 +
hassip = yes
 +
hasiax = yes
 +
callwaiting = yes
 +
threewaycalling = yes
 +
callwaitingcallerid = yes
 +
tranfer = yes
 +
canpark = yes
 +
cancallforward = yes
 +
callreturn = yes
 +
callgroup = yes
 +
pickupgroup = yes
 +
nat = yes
 +
 +
[6001]
 +
type=peer
 +
host=dynamic
 +
dtmfmode=rfc2833
 +
disallow=all
 +
allow=ulaw
 +
fullname=dpl1
 +
username=dpl1
 +
secret=secret
 +
context=work
 +
acl=acl1
 +
 +
[6002]
 +
type=peer
 +
host=dynamic
 +
dtmfmode=rfc2833
 +
disallow=all
 +
allow=ulaw
 +
fullname=dpl2
 +
username=dpl2
 +
secret=secret
 +
context=work
 +
acl=acl1
 +
</pre>
 +
 +
 +
Configuration via /etc/asterisk/extensions.conf :
 +
<pre>
 +
[work]
 +
exten => _6XXX,1,Dial(SIP/${EXTEN},20)
 +
exten => _6XXX,2,Hangup()
 +
</pre>
 +
 +
 +
Configuration des autorisations via /etc/asterisk/acl.conf :
 +
<pre>
 +
acl = acl1
 +
 +
[acl1]
 +
permit=0.0.0.0/0.0.0.0
 +
</pre>
 +
 +
 +
On se connecte à un compte SIP (dpl1 et dpl2) et on passe un appel grâce à l'identifiant configuré précédemment :
 +
<center>
 +
{|
 +
| [[Fichier:20161212 123958.jpg|thumb|upright=2|Serveur asterisk avec les téléphones connectés]]
 +
| [[Fichier:20161212 124022.jpg|thumb|upright=2|Communication entre les deux téléphones via SIP]]
 +
|}
 +
</center>
 +
 
== Références ==
 
== Références ==
 
Pour la gestion du serveur DAS :
 
Pour la gestion du serveur DAS :
Ligne 921 : Ligne 1 797 :
 
*[http://wiki.csnu.org/index.php/Installation_des_outils_HP_pour_debian Wiki CSNU - Installation des outils HP pour debian]
 
*[http://wiki.csnu.org/index.php/Installation_des_outils_HP_pour_debian Wiki CSNU - Installation des outils HP pour debian]
 
*[https://oitibs.com/hp-acu-command-line-reference/ Oitibs - Commandes disponibles pour hpssacli]
 
*[https://oitibs.com/hp-acu-command-line-reference/ Oitibs - Commandes disponibles pour hpssacli]
 
 
Pour les scripts de sauvegarde :
 
*TODO
 

Version actuelle datée du 6 janvier 2017 à 15:59

Tâche spécifique

Nous devons mettre en place un système de sauvegarde en réseau pour pouvoir sauvegarder l'état et les données de nos machines virtuelles.

Pour cela, nous allons utiliser un serveur de type DAS (Direct Attach Storage).

Cela consiste à une baie de stockage directement branchée sur le réseau via un câble et accessible comme n'importe quel périphérique.

Schéma minimaliste de l'infrastructure

Gestion du serveur DAS

Installation des outils HP

Ajout du dépôt dans /etc/apt/sources.net :

deb http://downloads.linux.hpe.com/SDR/repo/mcp/ jessie/current non-free

Copier / Coller le contenu des clés et les ajouter, liens des clés disponibles à ces adresses :

http://downloads.linux.hpe.com/SDR/hpPublicKey1024.pub
http://downloads.linux.hpe.com/SDR/hpPublicKey2048.pub
http://downloads.linux.hpe.com/SDR/hpPublicKey2048_key1.pub

Ajout des clefs :

apt-key add ./hpPublicKey1024.pub
apt-key add ./hpPublicKey2048.pub
apt-key add ./hpPublicKey2048_key1.pub

On met à jour les paquets et on installe l'utilitaire HP hpssacli :

aptitude update
aptitude install hp-health hpssacli

Liste des commandes disponibles pour hpssacli

Configuration des disques

Après avoir installé l'utilitaire HP pour gérer nos disques, nous pouvons enfin savoir les caractéristiques des baies :

hpssacli ctrl all show config


On obtient alors :

Smart Array P800 in Slot 4                (sn: P98690E9SV10C3)


   Port Name: 1I

   Port Name: 2I

   Port Name: 1E

   Port Name: 2E

   Internal Drive Cage at Port 3I, Box 1, OK

   Internal Drive Cage at Port 4I, Box 1, OK

   StorageWorks MSA 60 at Port 1E, Box 1, OK
   array A (SAS, Unused Space: 0  MB)


      logicaldrive 1 (820.2 GB, RAID 5, OK)

      physicaldrive 3I:1:1 (port 3I:box 1:bay 1, SAS, 146 GB, OK)
      physicaldrive 3I:1:2 (port 3I:box 1:bay 2, SAS, 146 GB, OK)
      physicaldrive 3I:1:3 (port 3I:box 1:bay 3, SAS, 146 GB, OK)
      physicaldrive 3I:1:4 (port 3I:box 1:bay 4, SAS, 146 GB, OK)
      physicaldrive 4I:1:5 (port 4I:box 1:bay 5, SAS, 146 GB, OK)
      physicaldrive 4I:1:6 (port 4I:box 1:bay 6, SAS, 146 GB, OK)
      physicaldrive 4I:1:8 (port 4I:box 1:bay 8, SAS, 146 GB, OK)
      physicaldrive 4I:1:7 (port 4I:box 1:bay 7, SAS, 146 GB, OK, spare)

   array B (SATA, Unused Space: 0  MB)


      logicaldrive 2 (1.9 TB, RAID 5, Recovering, 0% complete)
      logicaldrive 3 (1.9 TB, RAID 5, Ready for Rebuild)
      logicaldrive 4 (751.2 GB, RAID 5, Ready for Rebuild)

      physicaldrive 1E:1:1 (port 1E:box 1:bay 1, SATA, 1 TB, OK)
      physicaldrive 1E:1:2 (port 1E:box 1:bay 2, SATA, 1 TB, OK)
      physicaldrive 1E:1:4 (port 1E:box 1:bay 4, SATA, 1 TB, OK)
      physicaldrive 1E:1:5 (port 1E:box 1:bay 5, SATA, 1 TB, OK)
      physicaldrive 1E:1:6 (port 1E:box 1:bay 6, SATA, 1 TB, OK)
      physicaldrive 1E:1:11 (port 1E:box 1:bay 11, SATA, 1 TB, Rebuilding)
      physicaldrive 1E:1:3 (port 1E:box 1:bay 3, SATA, 1 TB, OK, spare)

   array C (SATA, Unused Space: 0  MB)


      logicaldrive 5 (1.9 TB, RAID 5, OK)
      logicaldrive 6 (1.7 TB, RAID 5, OK)

      physicaldrive 1E:1:7 (port 1E:box 1:bay 7, SATA, 1 TB, OK)
      physicaldrive 1E:1:8 (port 1E:box 1:bay 8, SATA, 1 TB, OK)
      physicaldrive 1E:1:9 (port 1E:box 1:bay 9, SATA, 1 TB, OK)
      physicaldrive 1E:1:10 (port 1E:box 1:bay 10, SATA, 1 TB, OK)
      physicaldrive 1E:1:12 (port 1E:box 1:bay 12, SATA, 1 TB, OK)
      physicaldrive 1E:1:3 (port 1E:box 1:bay 3, SATA, 1 TB, OK, spare)


Nous avons supprimé (et formaté) tous les disques logiques liés aux disques physiques du StorageWorks MSA 60

hpssacli ctrl slot=4 ld 6 delete
hpssacli ctrl slot=4 ld 5 delete
...
hpssacli ctrl slot=4 ld 2 delete


Puis créé un disque logique en RAID 10 avec tous les disques physiques du MSA60 qui sera notre disque réservé pour la sauvegarde des VM

hpssacli ctrl slot=4 create type=ld drives=1E:1:1,1E:1:2,1E:1:3,1E:1:4,1E:1:5,1E:1:6,1E:1:7,1E:1:8,1E:1:9,1E:1:10,1E:1:11,1E:1:12 raid=1+0


Enfin, on s'assure que le disque logique a correctement été généré

 array B (SATA, Unused Space: 0  MB)


      logicaldrive 2 (5.5 TB, RAID 1+0, OK)

      physicaldrive 1E:1:1 (port 1E:box 1:bay 1, SATA, 1 TB, OK)
      physicaldrive 1E:1:2 (port 1E:box 1:bay 2, SATA, 1 TB, OK)
      physicaldrive 1E:1:3 (port 1E:box 1:bay 3, SATA, 1 TB, OK)
      physicaldrive 1E:1:4 (port 1E:box 1:bay 4, SATA, 1 TB, OK)
      physicaldrive 1E:1:5 (port 1E:box 1:bay 5, SATA, 1 TB, OK)
      physicaldrive 1E:1:6 (port 1E:box 1:bay 6, SATA, 1 TB, OK)
      physicaldrive 1E:1:7 (port 1E:box 1:bay 7, SATA, 1 TB, OK)
      physicaldrive 1E:1:8 (port 1E:box 1:bay 8, SATA, 1 TB, OK)
      physicaldrive 1E:1:9 (port 1E:box 1:bay 9, SATA, 1 TB, OK)
      physicaldrive 1E:1:10 (port 1E:box 1:bay 10, SATA, 1 TB, OK)
      physicaldrive 1E:1:11 (port 1E:box 1:bay 11, SATA, 1 TB, OK)
      physicaldrive 1E:1:12 (port 1E:box 1:bay 12, SATA, 1 TB, OK)

Montage du disque de sauvegarde sur le serveur Debian

Les disques logiques et leurs partitions sont répertoriés à l'emplacement suivant :

ls /dev/cciss/
c0d0  c0d0p1  c0d0p2  c0d0p5  c0d0p6  c0d0p7  c0d0p8  c0d1

Ici, c0d0 représente le disque logique (p1,p2,...,p8 les partitions) où est installé Debian (disques physiques liés à la station DL380 G5).


On retrouve notre disque logique (disques physiques liés au MSA60) créé précédemment identifié c0d1 :

fdisk -l /dev/cciss/c0d1
Disque /dev/cciss/c0d1 : 5,5 TiB, 6001026883584 octets, 11720755632 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets


On transforme notre disque logique en partition ext4 :

mkfs.ext4 /dev/cciss/c0d1


On créer le dossier qui servira de point de montage, puis on monte notre partition dans celui-ci :

mkdir /backup
mount -t auto /dev/cciss/c0d1 /backup


Afin de monter automatiquement notre partition à chaque démarrage, il suffit d'ajouter la ligne suivante dans fstab :

vi /etc/fstab
/dev/cciss/c0d1     /backup    ext4    defaults    0    2


Après redémarrage du serveur, on vérifie si notre disque logique est monté automatiquement :

df -h
Sys. de fichiers  Taille Utilisé Dispo Uti% Monté sur
/dev/cciss/c0d0p1   8,2G    881M  6,9G  12% /
udev                 10M       0   10M   0% /dev
tmpfs               775M    456K  775M   1% /run
tmpfs               5,0M       0  5,0M   0% /run/lock
tmpfs               4,8G       0  4,8G   0% /run/shm
/dev/cciss/c0d0p8   781G     69M  741G   1% /home
/dev/cciss/c0d0p7   360M    2,1M  335M   1% /tmp
/dev/cciss/c0d0p5   2,7G    339M  2,3G  14% /var
/dev/cciss/c0d1     5,5T     58M  5,2T   1% /backup

Mise en réseau du disque

Lors de la sauvegarde des machines virtuelles, nous aurons besoin d'accéder à notre disque de sauvegarde.

Pour cela, nous avons mis en place un partage de type NFS (Network File System) :

apt-get install nfs-kernel-server


Il suffit de paramétrer le partage de façon à autoriser un ordinateur distant à accéder à un dossier en particulier (/etc/exports/) :

/backup/vm_backup cordouan.insecserv.deule.net(rw,sync,no_root_squash)

Ici, on autorise le serveur Cordouan à accéder au sous-dossier /backup/vm_backup/ en lecture et écriture.

Scripts de sauvegarde et de restauration de machine virtuelle

Commandes utiles

Sauvegarder l'état d'une machine virtuelle :

xl save -c Deadpool /usr/local/xen/domains/vm_backup/Deadpool.vmbackup

Restaurer l'état d'une machine virtuelle :

xl restore /usr/local/xen/domains/vm_backup/Deadpool.vmbackup


Snapshot des LVM d'une machine virtuelle :

lvcreate -l 10%ORIGIN -s -n ima5-Deadpool-home-snapshot /dev/virtual/ima5-Deadpool-home
lvcreate -l 10%ORIGIN -s -n ima5-Deadpool-var-snapshot /dev/virtual/ima5-Deadpool-var

Suppression des snapshots LVM :

lvremove /usr/local/xen/domains/vm_backup/ima5-Deadpool-home-snapshot
lvremove /usr/local/xen/domains/vm_backup/ima5-Deadpool-var-snapshot

Sauvegarde des états des machines virtuelles

Nous avons créé un script capable de sauvegarder l'état de toutes les machines virtuelles en cours d’exécution.

Ces machines virtuelles sont mis en pause pendant une à deux secondes le temps de la sauvegarde, ce qui est très rapide.

Voici le script disponible sur notre serveur DAS (/backup/script_backup/save_running_vm.sh) :

#!/bin/bash#
#Script de sauvegarde pour les VM en cours d?exécution

DATE=`date +%d%b%Y-%H%M%S`
MOUNTPOINT=/mnt/vm_backup
LIST_VM_FILE=/tmp/vm_list.txt
NFS_SERVER_IP="172.26.64.15"

### Create mount point
echo "Creating mount point...";
mkdir -p ${MOUNTPOINT}

### Mounting remote nfs share backup drive

#[ ! -d ${MOUNTPOINT} ]  && echo "No mount point found, kindly check"; exit 0
echo "Mounting backup nfs...";
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}

BACKUPPATH=${MOUNTPOINT}/${DATE}
mkdir -p ${BACKUPPATH}
#[ ! -d ${BACKUPPATH} ]  && echo "No backup directory found"; exit 0

### get all running vm
xl vm-list | tail -n +2 | cut -d" " -f7 > ${LIST_VM_FILE}

#[ ! -f ${LIST_VM_FILE} ] && echo "No UUID list file found"; exit 0

while read VMUUID
do
    echo "Saving ${VMUUID}...";
	mkdir -p ${BACKUPPATH}/${VMUUID}/
    xl save -c $VMUUID ${BACKUPPATH}/${VMUUID}/${VMUUID}.vmbackup
done < ${LIST_VM_FILE}

### Umounting remote nfs share backup drive
echo "Umounting backup nfs...";
umount ${MOUNTPOINT}
rm ${MOUNTPOINT} -r
echo "ALL DONE !";

Le script consiste à monter sur la machine le dossier mis en réseau précédemment, puis il récupère le nom de toutes les machines virtuelles en cours de fonctionnement, et enfin il sauvegarde l'état des machines virtuelles une par une dans des dossiers spécifiques.

Une fois terminé, il démonte le dossier monté précédemment.


Ce script doit être exécuté sur la machine hôte des machines virtuelles, à savoir Cordouan.

Pour cela, il suffit d'un petit script avec une commande pour exécuter le script ci-dessus sur une machine distante (/backup/script_backup/save_running_vm_remote.sh) :

#!/bin/bash#
ssh root@cordouan.insecserv.deule.net 'bash -s' < save_running_vm.sh


On exécute notre nouveau script :

sh /backup/script_backup/save_running_vm_remote.sh


Et on laisse le travail se faire :

Creating mount point...
Mounting backup nfs...
Saving Wolverine...
Saving to /mnt/vm_backup/04janv.2017-210539/Wolverine/Wolverine.vmbackup new xl format (info 0x0/0x0/1094)
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
...
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
Saving Ironman...
Saving to /mnt/vm_backup/04janv.2017-210539/Ironman/Ironman.vmbackup new xl format (info 0x0/0x0/919)
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
...
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 30720/32768   93%
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
Saving Batman...
Saving to /mnt/vm_backup/04janv.2017-210539/Batman/Batman.vmbackup new xl format (info 0x0/0x0/1049)
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 2048/32768    6%
...
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 32768/32768  100%
Saving Frotteman...
Saving to /mnt/vm_backup/04janv.2017-210539/Frotteman/Frotteman.vmbackup new xl format (info 0x0/0x0/1056)
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 7168/131072    5%
...
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
Saving Deadpool...
Saving to /mnt/vm_backup/04janv.2017-210539/Deadpool/Deadpool.vmbackup new xl format (info 0x0/0x0/1054)
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 7168/131072    5%
...
xc: progress: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
Umounting backup nfs...
ALL DONE !


Nous pouvons accéder facilement à nos sauvegardes :

root@baleine:/backup/vm_backup/04janv.2017-210539# ls
Batman  Deadpool  Frotteman  Ironman  Wolverine
root@baleine:/backup/vm_backup/04janv.2017-210539# cd Deadpool/
root@baleine:/backup/vm_backup/04janv.2017-210539/Deadpool# ls
Deadpool.vmbackup

Sauvegarde des LVM liés aux machines virtuelles

Nous avons créé un script qui permet d'enregistrer les LVM d'une machine virtuelle donnée en argument :

#!/bin/bash
#Script de sauvegarde pour toutes les LVM souhaitées
#Run with "ssh remote_machine 'bash -s' < /backup/script_backup/save_lvm_data_vm.sh arg"

LIST_LVM_FILE=/tmp/lvm_list.txt
VM_NAME=$1
LVM_PATH=/dev/virtual/
LVM_MOUNT_PATH=/mnt/lvm_snap
MOUNTPOINT=/mnt/vm_backup
NFS_SERVER_IP="172.26.64.15"

echo "Creating mount point for NFS...";
mkdir -p ${MOUNTPOINT}

echo "Mounting backup nfs...";
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}

echo "Creating directory for LVM mount point...";
mkdir -p ${LVM_MOUNT_PATH}

echo "Cheking for $1 LVM...";
ls ${LVM_PATH} | grep -i $1 | grep -i 'var\|home' > ${LIST_LVM_FILE}

while read LVM_NAME
do
    echo "Snapshot of ${LVM_NAME} LVM...";
	lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
	
	echo "Mounting ${LVM_NAME}-snapshot...";
	mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
	
	echo "Doing the backup of ${LVM_NAME}-snapshot...";
	tar -cf ${MOUNTPOINT}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
	
	echo "Unmounting ${LVM_NAME} LVM...";
	umount ${LVM_MOUNT_PATH}
	
	echo "Cleaning snapshot of ${LVM_NAME} LVM...";
	yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
done < ${LIST_LVM_FILE}

rm ${LVM_MOUNT_PATH} -r

echo "Unmounting backup NFS...";
umount ${MOUNTPOINT}

rm ${MOUNTPOINT} -r

echo "ALL DONE !";


On essaye le script pour notre machine virtuelle en mettant "Deadpool" comme argument :

Creating mount point for NFS...
Mounting backup nfs...
Creating directory for LVM mount point...
Cheking for Deadpool LVM...
Snapshot of ima5-Deadpool-home LVM...
  Logical volume "ima5-Deadpool-home-snapshot" created
Mounting ima5-Deadpool-home-snapshot...
Doing the backup of ima5-Deadpool-home-snapshot...
tar: Suppression de « / » au début des noms des membres
Unmounting ima5-Deadpool-home LVM...
Cleaning snapshot of ima5-Deadpool-home LVM...
Do you really want to remove active logical volume ima5-Deadpool-home-snapshot? [y/n]:   Logical volume "ima5-Deadpool-home-snapshot" successfully removed
Snapshot of ima5-Deadpool-var LVM...
  Logical volume "ima5-Deadpool-var-snapshot" created
Mounting ima5-Deadpool-var-snapshot...
Doing the backup of ima5-Deadpool-var-snapshot...
tar: Suppression de « / » au début des noms des membres
Unmounting ima5-Deadpool-var LVM...
Cleaning snapshot of ima5-Deadpool-var LVM...
Do you really want to remove active logical volume ima5-Deadpool-var-snapshot? [y/n]:   Logical volume "ima5-Deadpool-var-snapshot" successfully removed
Unmounting backup NFS...
ALL DONE !


On récupère bien nos fichiers :

root@baleine:/backup/vm_backup# ls
ima5-Deadpool-home-snapshot.tar  ima5-Deadpool-var-snapshot.tar

Sauvegarde complète et automatisée des machines virtuelles

Maintenant, il faut enregistrer à la fois les états des machines virtuelles allumées avec leurs LVM, ainsi que les LVM des machines virtuelles éteintes.

Pour celà, nous avons modifié le script et ajouter un fichier de configuration comportant le nom de toutes les machines virtuelles que l'on souhaite sauvegarder.

Le script reste largement simplifiable, car il s'agit ici des deux précédents scripts plus ou moins arrangés.

Lors de la soutenance, nous avons modifié le script pour qu'il sauvegarde aussi le disque image des machines virtuelles, ainsi, une sauvegarde totale de la machine virtuelle est effectuée, et non pas seulement l'état mémoire et les LVM.

De plus la machine virtuelle est mise en pause durant sa sauvegarde.

#!/bin/bash#
#Script effectuant le backup de toutes les VM

DATE=`date +%d%b%Y-%H%M%S`
MOUNTPOINT=/mnt/vm_backup
LVM_MOUNT_PATH=/mnt/lvm_snap
LVM_PATH=/dev/virtual/
LIST_VM_FILE=/tmp/vm_list.txt
LIST_VM_CLOSED=/tmp/vm_closed_list.txt
LIST_LVM_FILE=/tmp/lvm_list.txt
NFS_SERVER_IP="172.26.64.15"
BACKUPPATH=${MOUNTPOINT}/${DATE}
CONFIGPATH=${MOUNTPOINT}/vm_backup.cfg

### Create mount point
echo "Creating mount point...";
mkdir -p ${MOUNTPOINT}

echo "Creating directory for LVM mount point...";
mkdir -p ${LVM_MOUNT_PATH}

### Mounting remote nfs share backup drive
echo "Mounting backup nfs...";
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}

echo "Creating dated backup folder...";
mkdir -p ${BACKUPPATH}

### get all running vm
xl vm-list | tail -n +2 | cut -d" " -f7 > ${LIST_VM_FILE}

while read VMUUID
do
	mkdir -p ${BACKUPPATH}/${VMUUID}/
	
    echo "Saving ${VMUUID} state...";
    xl save -p $VMUUID ${BACKUPPATH}/${VMUUID}/${VMUUID}.vmbackup

    echo "Creating disk.img snapshot...";
    qemu-img create -f qcow2 -b /usr/local/xen/domains/${VMUUID}/disk.img /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
    modprobe nbd max_part=63
    qemu-nbd -c /dev/nbd0 /usr/local/xen/domains/${VMUUID}/disk-snapshot.img

    echo "Mounting ${LVM_NAME} disk.img...";
    mount /dev/nbd0 ${LVM_MOUNT_PATH}

    echo "Doing the backup of disk...";
    tar -cf ${BACKUPPATH}/${VMUUID}/disk.img-snapshot.tar ${LVM_MOUNT_PATH}

    echo "Unmounting ..."
    umount ${LVM_MOUNT_PATH}

    echo "Cleaning snapshot..."
    rm /usr/local/xen/domains/${VMUUID}/disk-snapshot.img

	echo "Cheking for ${VMUUID} LVM...";
	ls ${LVM_PATH} | grep -i ${VMUUID} | grep -i 'var\|home' > ${LIST_LVM_FILE}
	
	while read LVM_NAME
	do
		echo "Snapshot of ${LVM_NAME} LVM...";
		lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
		
		echo "Mounting ${LVM_NAME}-snapshot...";
		mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
		
		echo "Doing the backup of ${LVM_NAME}-snapshot...";
		tar -cf ${BACKUPPATH}/${VMUUID}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
		
		echo "Unmounting ${LVM_NAME} LVM...";
		umount ${LVM_MOUNT_PATH}
		
		echo "Cleaning snapshot of ${LVM_NAME} LVM...";
		yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
	done < ${LIST_LVM_FILE}
	xl unpause ${VMUUID}
done < ${LIST_VM_FILE}

### get all closed vm
awk 'NR==FNR {t[$0]++; next} !t[$0]' ${LIST_VM_FILE} ${CONFIGPATH} > ${LIST_VM_CLOSED}

while read VMUUID
do
	mkdir -p ${BACKUPPATH}/${VMUUID}/
	echo "Creating disk.img snapshot...";
	qemu-img create -f qcow2 -b /usr/local/xen/domains/${VMUUID}/disk.img /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
	modprobe nbd max_part=63
	qemu-nbd -c /dev/nbd0 /usr/local/xen/domains/${VMUUID}/disk-snapshot.img

	echo "Mounting ${LVM_NAME} disk.img...";
	mount /dev/nbd0 ${LVM_MOUNT_PATH}

	echo "Doing the backup of disk...";
	tar -cf ${BACKUPPATH}/${VMUUID}/disk.img-snapshot.tar ${LVM_MOUNT_PATH}

	echo "Unmounting ..."
	umount ${LVM_MOUNT_PATH}

        echo "Cleaning snapshot..."
        rm /usr/local/xen/domains/${VMUUID}/disk-snapshot.img
	
	echo "Cheking for ${VMUUID} LVM...";
	ls ${LVM_PATH} | grep -i ${VMUUID} | grep -i 'var\|home' > ${LIST_LVM_FILE}
	
	while read LVM_NAME
	do
		echo "Snapshot of ${LVM_NAME} LVM...";
		lvcreate -l 10%ORIGIN -s -n ${LVM_NAME}-snapshot ${LVM_PATH}${LVM_NAME}
		
		echo "Mounting ${LVM_NAME}-snapshot...";
		mount ${LVM_PATH}${LVM_NAME}-snapshot ${LVM_MOUNT_PATH}
		
		echo "Doing the backup of ${LVM_NAME}-snapshot...";
		tar -cf ${BACKUPPATH}/${VMUUID}/${LVM_NAME}-snapshot.tar ${LVM_MOUNT_PATH}
		
		echo "Unmounting ${LVM_NAME} LVM...";
		umount ${LVM_MOUNT_PATH}
		
		echo "Cleaning snapshot of ${LVM_NAME} LVM...";
		yes | lvremove ${LVM_PATH}${LVM_NAME}-snapshot
	done < ${LIST_LVM_FILE}

done < ${LIST_VM_CLOSED}

###Cleaning lvm mount path
rm ${LVM_MOUNT_PATH} -r

### Umounting remote nfs share backup drive
echo "Umounting backup nfs...";
umount ${MOUNTPOINT}
rm ${MOUNTPOINT} -r
echo "ALL DONE !";


Une fois avoir exécuté celui-ci sur Cordouan, on peut observer le résultat obtenu sur notre DAS :

tree /backup/vm_backup/05janv.2017-205758/
/backup/vm_backup/06janv.2017-175650/
├── Batman
│   ├── Batman.vmbackup
│   ├── disk.img-snapshot.tar
│   ├── ima5-Batman-home-snapshot.tar
│   └── ima5-Batman-var-snapshot.tar
├── Deadpool
│   ├── Deadpool.vmbackup
│   ├── disk.img-snapshot.tar
│   ├── ima5-Deadpool-home-snapshot-snapshot.tar
│   ├── ima5-Deadpool-home-snapshot.tar
│   ├── ima5-Deadpool-var-snapshot-snapshot.tar
│   └── ima5-Deadpool-var-snapshot.tar
├── Flash
│   ├── disk.img-snapshot.tar
│   └── Flash.vmbackup
├── Frotteman
│   ├── disk.img-snapshot.tar
│   ├── Frotteman.vmbackup
│   ├── ima5-Frotteman-home-snapshot.tar
│   └── ima5-Frotteman-var-snapshot.tar
├── GreenArrow
│   ├── disk.img-snapshot.tar
│   ├── GreenArrow.vmbackup
│   ├── ima5-GreenArrow-home-snapshot.tar
│   └── ima5-GreenArrow-var-snapshot.tar
├── Ironman
│   ├── disk.img-snapshot.tar
│   └── Ironman.vmbackup
├── Mulan
│   ├── disk.img-snapshot.tar
│   ├── ima5-Mulan-home-snapshot.tar
│   ├── ima5-Mulan-var-snapshot.tar
│   └── Mulan.vmbackup
├── Spiderman
│   └── Spiderman.vmbackup
└── Wolverine
    ├── disk.img-snapshot.tar
    ├── wolverine-home-snapshot.tar
    ├── wolverine-var-snapshot.tar
    └── Wolverine.vmbackup


Pour automatiser notre tâche, nous avons configuré Cron.

Cet utilitaire permet d’exécuter une commande automatiquement à n'importe quel moment : toutes les 2 heures, tous les jeudis à 15h48...

Nous avons donc configuré Cron pour exécuter une sauvegarde toutes les 6 heures :

crontab -e
# m h  dom mon dow   command
0 */6 * * * sh /backup/script_backup/vm_backup_script_remote.sh


Le script de sauvegarde automatique pourrait être modifié de manière à ne garder que les 10 dernière sauvegardes sur notre DAS pour ne pas le surcharger ou ne pas supprimer manuellement toutes les semaines les sauvegardes trop vielles.

Restauration d'une machine virtuelle

Nous avons créé un script capable de restaurer une machine virtuelle depuis un dossier de sauvegarde voulu :

#!/bin/bash#

#UTILISATION : ./restore_state_vm.sh Deadpool 05janv.2017-205758
#UTILISATION : ./restore_state_vm.sh VM_NAME FOLDER_NAME

VM_NAME=$1
DATE_FOLDER=$2
MOUNTPOINT=/mnt/vm_backup
NFS_SERVER_IP="172.26.64.15"

### Create mount point
echo "Creating mount point...";
mkdir -p ${MOUNTPOINT}

### Mounting remote nfs share backup drive
echo "Mounting backup nfs...";
mount -t nfs ${NFS_SERVER_IP}:/backup/vm_backup ${MOUNTPOINT}

### restoring vm
echo "Restoring ${VM_NAME} ...";
xl destroy ${VM_NAME}
xl restore ${MOUNTPOINT}/${DATE_FOLDER}/${VM_NAME}/${VM_NAME}.vmbackup
echo "${VM_NAME} RESTORED !";

### Umounting remote nfs share backup drive
echo "Umounting backup nfs...";
umount ${MOUNTPOINT}

#BUSY ERROR
#rm ${MOUNTPOINT} -r
echo "ALL DONE !";


Le script fonctionne, mais le disque en réseau devient occupé et il est impossible de le démonter de Cordouan.

Il est nécessaire d'éteindre la machine virtuelle, puis de la redémarrer pour pouvoir démonter le disque réseau correctement.

Ici, la restauration des LVM n'est pas effectuée.

Amélioration du site

On installe de quoi exécuter du PHP sur notre site web :

apt-get install php5-common libapache2-mod-php5 php5-cli


On a revu un peu l'index de notre page :

<html>

	<link rel="icon" type="image/png" href="images/Deadpool_ico.png" />
	<meta charset="utf-8">
	<!--[if IE]><link rel="shortcut icon" type="image/x-icon" href="images/Deadpool_ico.png" /><![endif]-->

  <head>
    <title>PISCINEMORTE.NET</title>
  </head>
  <body bgcolor=#CEECF5>

	<center>

          <img src="images/Deadpool.png" height="25%" width="25%">

          <h1><FONT color="#0B0B61">Bienvenue sur PISCINEMORTE.NET !</FONT></h1>


        <p><FONT color="#0B0B61">Ce site internet est dédié à notre projet de système et réseaux à l'école Polytech Lille.</FONT></p>
	<p><FONT color="#0B0B61">Par Geoffrey PIEKACZ et Nathan RICHEZ</FONT></p>
	<p><FONT color="#0B0B61">Lien vers <a href="http://projets-ima.plil.net/mediawiki/index.php?title=Cahier_2016_groupe_n%C2%B03">notre Wiki</a></FONT></p>
	</center>
  </body>
</html>


Nous devons maintenant trouver le moyen d'afficher les machines virtuelles démarrées sur notre site.

Pour cela, nous nous sommes inspirés de la commande ci-dessous :

ssh [user]@[server] 'bash -s' < [local_script]

Cette commande va nous permettre de lancer un script de Deadpool vers Cordouan.


Le script est le suivant (/var/www/www.piscinemorte.net/show_vm_list.sh):

#!/bin/bash
 
ssh root@cordouan.insecserv.deule.net 'xl vm-list'


Il affichera une liste des VM démarrées via un code PHP ajouté dans notre index :

<?php
		echo "Liste des machines virtuelles en cours de fonctionnement :";
		$output = shell_exec('sh /var/www/www.piscinemorte.net/show_vm_list.sh');
		echo "$output";
?>


Ensuite, nous avons rencontré un problème.

En effet, cette commande fonctionne dans un bash mais le résultat n'est pas directement affiché sur notre site.

Cela s'explique par le fait que nous avons exécuté cette commande en root mais que apache via php execute cette commande dans un shell via l'utilisateur www-data.

Nous avions précédemment créé une clé pour pouvoir exécuter notre commande en root sans remettre à chaque fois le mot de passe.

Nous avons donc réitéré la démarche pour l'utilisateur www-data:

root@Deadpool:/home/Deadpool-key# ssh-keygen -t rsa  //on génère une clé sans mot de passe dans ~/.ssh sauvegardée dans /root/.ssh/id_rsa


On copiera cette clé sur Cordouan et sur Baleine (notre DAS) pour permettre à nos machines de se connecter en ssh sans demande de mot de passe :

root@Deadpool:~# cp /root/.ssh/id_rsa /var/www/.ssh/   //pour copier notre clé pour l'utilisateur www-data
root@Deadpool:~# chown www-data:www-data /var/www/.ssh/ -R  // pour donner les droits de manière récursive à www-data
root@Deadpool:~# sudo -u www-data -s                   //Pour changer l'utilisateur à www-data


Ainsi, notre commande est bien exécutée depuis notre site et affiche toutes les VM fonctionnant à l'instant t.

Affichage des machines virtuelles sur notre site

Tâches communes

Gestion de la machine virtuelle

Installation de la machine virtuelle avec Xen

Pour créé la machine virtuelle, on utilise xen-create-image avec les paramètres souhaités :

xen-create-image --hostname=Deadpool --ip=193.48.57.163 --netmask=255.255.255.240 --gateway=193.48.57.171 --dir=/usr/local/xen
     --mirror=http://debian.polytech-lille.fr/debian/ --dist=jessie --password=********


Puis, on récupère les informations suivantes afin de vérifier diverses paramètres :

General Information
--------------------
Hostname       :  Deadpool
Distribution   :  jessie
Mirror         :  http://debian.polytech-lille.fr/debian/
Partitions     :  swap            128M  (swap)
                  /               4G    (ext3)
Image type     :  sparse
Memory size    :  128M
Kernel path    :  /boot/vmlinuz-3.14-2-amd64
Initrd path    :  /boot/initrd.img-3.14-2-amd64

Networking Information
----------------------
IP Address 1   : 193.48.57.163 [MAC: 00:16:3E:FF:6F:DC]
Netmask        : 255.255.255.240
Gateway        : 193.48.57.171


Creating partition image: /usr/local/xen/domains/Deadpool/swap.img
Done

Creating swap on /usr/local/xen/domains/Deadpool/swap.img
Done

Creating partition image: /usr/local/xen/domains/Deadpool/disk.img
Done

Creating ext3 filesystem on /usr/local/xen/domains/Deadpool/disk.img

(...)

Logfile produced at:
	 /var/log/xen-tools/Deadpool.log

Installation Summary
---------------------
Hostname        :  Deadpool
Distribution    :  jessie
MAC Address     :  00:16:3E:FF:6F:DC
IP Address(es)  :  193.48.57.163 
RSA Fingerprint :  d0:38:7b:89:c7:72:e7:52:d9:b7:5c:5b:ab:3e:fe:3f
Root Password   :  hZsEGmZX

Configuration de la machine virtuelle

On utilise lvcreate pour faire en sorte que les répertoires var et home de la machine virtuelle soient sur des partitions LVM de l'hôte :

lvcreate -L 10G -n /dev/virtual/ima5-Deadpool-home -v
lvcreate -L 10G -n /dev/virtual/ima5-Deadpool-var -v


Commande pour démarrer la machine virtuelle :

xl create /etc/xen/Deadpool.cfg

Commande pour se connecter à la machine virtuelle par console :

xl console Deadpool

Commande pour éteindre la machine virtuelle :

xl shutdown Deadpool

Commande pour détruire la machine virtuelle :

xl destroy Deadpool


On transforme nos disques logiques en partition ext4 :

mkfs.ext4 /dev/xvdb
mkfs.ext4 /dev/xvdc


On sauvegarde les fichiers déjà existants dans home et var et on les met dans nos nouvelles partitions :

mkdir /mnt/home/
mkdir /mnt/var/
mount /dev/xvdc/ /mnt/home/
mount /dev/xvdb/ /mnt/var/
cp -r /home/* /mnt/home/
cp -r /var/* /mnt/var/


Afin de monter automatiquement notre partition à chaque démarrage, il suffit d'ajouter les lignes suivantes dans fstab :

nano /etc/fstab
/dev/xvdc /home ext3 defaults 0 2
/dev/xvdb /var ext3 defaults 0 2


Après redémarrage de la machine virtuelle, on vérifie si nos disques sont montés automatiquement :

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda2      3.9G  700M  3.0G  19% /
udev             10M     0   10M   0% /dev
tmpfs            99M   13M   87M  13% /run
tmpfs           247M     0  247M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           247M     0  247M   0% /sys/fs/cgroup
/dev/xvdb       9.8G  262M  9.0G   3% /var
/dev/xvdc       9.8G   23M  9.2G   1% /home

Tests d'intrusion

Cassage de clef WEP

Via airodump-ng, on liste les réseaux wi-fi protégés par WEP :

airodump-ng --encrypt wep wlx40a5ef01370a

wlx40a5ef01370a représente ici notre interface réseau (équivalant à wlan0 par exemple)


On obtient la liste des réseaux wi-fi suivante :

[ CH  5 ][ Elapsed: 2 mins ][ 2016-11-07 10:30 ][ WPA handshake: 04:DA:D2:CF:01:93 ]                    
                                                                                                      
 BSSID              PWR  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                      
 44:AD:D9:5F:87:00  -50       73        0    0  11  54e. WEP  WEP         Wolverine                   
 04:DA:D2:9C:50:51  -64       90        0    0  13  54e. WEP  WEP         cracotte02                  
 04:DA:D2:9C:50:53  -67       58        0    0  13  54e. WEP  WEP         cracotte04                  
 04:DA:D2:9C:50:59  -68       85        0    0  13  54e. WEP  WEP         cracotte10                  
 04:DA:D2:9C:50:56  -74       88     1329   17  13  54e. WEP  WEP         cracotte07                  
 04:DA:D2:9C:50:52  -75       87     2279   14  13  54e. WEP  WEP         cracotte03                  
 04:DA:D2:9C:50:58  -75       87     1751   14  13  54e. WEP  WEP         cracotte09                  
 04:DA:D2:9C:50:57  -75       86     1293    7  13  54e. WEP  WEP         cracotte08                  
 04:DA:D2:9C:50:54  -76       88     1460   15  13  54e. WEP  WEP         cracotte05                  
 04:DA:D2:9C:50:50  -76       80     1345   11  13  54e. WEP  WEP         cracotte01                  
 04:DA:D2:9C:50:55  -76       83     1501   10  13  54e. WEP  WEP         cracotte06                  
 00:3A:7D:12:DC:F2   -1        0        0    0   6  -1                    <length:  0>                


On lance le monitoring sur le réseau que l'on souhaite cracker :

airodump-ng --essid cracotte07 --channel 13 -w testcrack wlx40a5ef01370a
[ CH 13 ][ Elapsed: 1 min ][ 2016-11-07 10:46 ]                                   
                                                                                                      
 BSSID              PWR RXQ  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                      
 04:DA:D2:9C:50:56  -72  12      608     8283   91  13  54e. WEP  WEP         cracotte07


Nous pouvons ensuite lancer le crackage à l'aide de aircrack-ng :

aircrack-ng testcarck-03.cap
                       Aircrack-ng 1.2 beta3


                 [00:00:00] Tested 84483 keys (got 35490 IVs)

   KB    depth   byte(vote)
    0    0/  5   EE(46080) EF(44032) 53(43008) 7B(43008) FC(43008) 
    1    3/ 15   EE(41984) 8D(41728) DD(41472) 16(41216) 28(41216) 
    2    0/  2   EE(47616) 29(45824) C9(43776) 27(43264) 42(43008) 
    3    0/ 10   EE(44800) A9(44288) 15(43264) C5(42496) 2C(42496) 
    4    0/  1   EE(49920) 2A(45312) 9D(43520) DA(43008) FD(41216) 
    5    0/  4   EE(45312) A1(43520) C6(42240) E8(42240) 76(41472) 
    6    0/  1   EE(50944) 98(42496) BB(42496) 4C(41728) B3(41728) 
    7    0/  1   EE(54272) D3(42752) 19(42240) 08(41984) 58(41984) 
    8    5/  8   F4(41216) 39(40960) 5E(40960) D7(40960) 1E(40704) 
    9    1/  2   E4(45312) 51(43264) A7(42752) 5F(41984) CA(41728) 
   10    0/  1   44(51200) 12(43264) CD(41984) 9C(41216) E5(41216) 
   11    0/  1   44(50176) B0(42240) D2(41728) DC(41728) 62(41472) 
   12    0/  1   44(47872) 0B(44032) B4(42752) D9(42496) 43(41728) 

             KEY FOUND! [ EE:EE:EE:EE:EE:EE:EE:EE:EE:E4:44:44:44 ] 
	Decrypted correctly: 100%

La clé est décryptée en quelques secondes !

Cassage de clef WPA-PSK par force brute

De même que pour le cassage de clé WEP, nous allons utiliser les mêmes outils mais pour un craquage WPA.

airmon-ng start wlx40a5ef01370a   //On lance le mode monitoring sur notre carte wifi
airmon-ng mon0                    //On liste ensuite toutes les interfaces wifi disponible
crunch 8 8 0123456789 > dico.txt  //On sait que la clé possède 8 chiffres, on créé donc un dictionnaire contenant toutes les possibilités de clé avec l'outil crunch
airodump-ng --encrypt wpa wlx40a5ef01370a //Nous choisissons ensuite le réseau à attaquer en wpa
[ CH  3 ][ Elapsed: 8 s ][ 2016-11-07 11:30 ]                                      
                                                                                                      
 BSSID              PWR  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                      
 04:DA:D2:9D:82:A2  -75        2        0    0   4  54e. WPA2 CCMP   PSK  <length:  1>                
 00:19:07:C5:0F:A6  -62        7        0    0   1  54e. WPA2 CCMP   MGT  <length:  1>                
 00:19:07:C5:0F:A0  -63        6        4    0   1  54e. WPA2 CCMP   MGT  LILLE1                      
 00:19:07:C5:0F:A5  -62        6        0    0   1  54e. WPA2 CCMP   PSK  <length:  1>                
 00:19:07:C5:0F:A3  -64        7        0    0   1  54e. WPA2 CCMP   PSK  PolytechGuests              
 00:19:07:C5:0F:A7  -62        6        0    0   1  54e. WPA2 CCMP   MGT  PolytechLilleStaff          
 00:19:07:C5:0F:A2  -63        7        0    0   1  54e. WPA2 CCMP   PSK  <length:  1>                
 00:19:07:C5:0F:A8  -62        6        4    0   1  54e. WPA2 CCMP   MGT  eduroam                     
 00:19:07:C5:0F:A4  -63        8        2    0   1  54e. WPA2 CCMP   MGT  PolytechLille                
 00:19:07:C5:0F:A1  -64        8        6    1   1  54e. WPA2 CCMP   MGT  <length:  1>                
 04:DA:D2:9C:50:58  -70        6        0    0  13  54e. WPA2 CCMP   PSK  cracotte09                  
 04:DA:D2:9C:50:50  -71        6        0    0  13  54e. WPA2 CCMP   PSK  cracotte01                  
 04:DA:D2:9C:50:55  -71        6        0    0  13  54e. WPA2 CCMP   PSK  cracotte06                  
 04:DA:D2:9C:50:53  -71        7        0    0  13  54e. WPA2 CCMP   PSK  cracotte04                   
 04:DA:D2:9C:50:57  -71        7        0    0  13  54e. WPA2 CCMP   PSK  cracotte08                   
 04:DA:D2:9C:50:51  -72        9        0    0  13  54e. WPA2 CCMP   PSK  cracotte02                  
 04:DA:D2:9C:50:56  -72        9        0    0  13  54e. WPA2 CCMP   PSK  cracotte07                  
 04:DA:D2:9C:50:52  -72        8        0    0  13  54e. WPA2 CCMP   PSK  cracotte03                  
 04:DA:D2:9C:50:59  -71        8        0    0  13  54e. WPA2 CCMP   PSK  cracotte10 


On observe ensuite (seulement) la cible choisie (cracotte03)

airodump-ng --essid cracotte03 -c 13 --bssid 04:DA:D2:9C:50:52 -w dump mon0
[ CH 13 ][ Elapsed: 4 mins ][ 2016-11-07 11:36 ][ WPA handshake: 04:DA:D2:9C:50:52                     
                                                                                                      
 BSSID              PWR RXQ  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                      
 04:DA:D2:9C:50:52  -74   9     2573      259    0  13  54e. WPA2 CCMP   PSK  cracotte03              
                                                                                                      
 BSSID              STATION            PWR   Rate    Lost    Frames  Probe                            
                                                                                                      
 04:DA:D2:9C:50:52  00:0F:B5:92:23:6A  -58    1e- 1e     0      185 


On lance l'attaque avec le handshake récupéré :

#aireplay-ng --deauth=5 -a 04:DA:D2:9C:50:52


Et enfin, on lance le décodage grâce au fichier généré et notre dictionnaire:

aircrack-ng dump-03.cap -w dico.txt -l KEY

Malheureusement, le décodage étant très long avec un eePC, nous avons recommencé et relancé le décodage sur notre Zabeth préférée.


Après une heure d'acharnement, nous avons enfin une clé !

Opening dump-01.cap
Read 5625 packets.

   #  BSSID              ESSID                     Encryption

   1  04:DA:D2:9C:50:52  cracotte03                WPA (1 handshake)

Choosing first network as target.

Opening dump-01.cap
Reading packets, please wait...

                                 Aircrack-ng 1.2 beta3


                   [00:59:31] 12399952 keys tested (3160.12 k/s)


                           KEY FOUND! [ 12399903 ]


      Master Key     : 33 2B 69 DD 95 0A 5A E0 01 22 7E FF 98 DA 99 87 
                       40 7A CB CC 8A E5 32 9F FE 4E 5C 44 91 38 13 93 

      Transient Key  : 27 04 CB E4 68 2F D2 F6 CE 7D DF 51 25 60 2E 34 
                       D0 D1 87 B9 A9 A5 3E 6E A6 6A EC 1E 05 29 12 D8 
                       26 E5 DA 78 E4 87 AE 71 7A 5F AC BB 44 41 4E 2F 
                       9D 18 A4 2C BF 88 82 59 BB F8 50 15 82 45 77 35 

      EAPOL HMAC     : B6 83 11 A0 AC E3 AC 73 9D 7F 15 0A F1 A6 68 62
Terminal affichant le résultat

Services Internet

Serveur SSH

Il suffit d'installer ssh sur notre machine virtuelle si ce n'est pas déjà fait :

apt-get install ssh


Ensuite, pour autoriser la connexion en root en ssh, on remplace un paramètre dans le fichier /etc/ssh/sshd_config :

#PermitRootLogin without-password
PermitRootLogin yes


Et on redémarre le service :

service ssh restart


Une fois le DNS configuré ci-après, nous pouvons facilement accéder à notre machine virtuelle depuis n'importe où :

ssh root@www.piscinemorte.net
root@www.piscinemorte.net's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Dec  6 18:13:23 2016
root@Deadpool:~# 

Serveur DNS

Nous avons d'abord réservé sur Gandi notre nom de domaine : piscinemorte.net

Ensuite, nous avons installé les paquets bind et apache sur notre machine virtuelle (le dossier /var/www/www.piscinemorte.net servira pour la page web) :

apt-get update
apt-get install apache2 bind9
mkdir /var/www/www.piscinemorte.net


Une fois bind installé, on créer un fichier de zone db.piscinemorte.net (appellé également une "table de DNS") :

;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     ns.piscinemorte.net. root.piscinemorte.net (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
        IN      NS      ns.piscinemorte.net.
ns      IN      A       193.48.57.163
www     IN      A       193.48.57.163

Notre DNS (ns) a pour adresse 193.48.57.163, c'est à dire l'IP de notre machine virtuelle.


Enfin, nous configurons le fichier named.conf.local pour autoriser le transfert de paquets vers le DNS Esclave (l'adresse de Gandi dans notre cas) :

zone "piscinemorte.net" {
        type master;
        file "/etc/bind/db.piscinemorte.net";
        allow-transfer {217.70.177.40;};
};


Pour finir, on redémarre notre service bind :

service bind9 restart


Sur le site Gandi, depuis la gestion des domaines, nous avons besoin de gérer les 'glue records' et signaler nos serveurs DNS :

(Pour les 'glues records')
'Nom du serveur' : ns.piscinemorte.net
'IP' : 193.48.57.163
(Pour les DNS)
'DNS1' : ns.piscinemorte.net
'DNS2' : ns6.gandi.net 

Sécurisation de site web par certificat

Pour avoir un certificat SSL généré Gandi, nous avons généré un CSR de la façon suivante :

openssl req -nodes -newkey rsa:2048 -sha1 -keyout piscinemorte.net.key -out piscinemorte.net.csr


Nous avons complété les différentes informations demandés (pas vraiment important ici) :

Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Nord
Locality Name (eg, city) []:Lille
Organization Name (eg, company) [Internet Widgits Pty Ltd]:piscinemorte.net
Organizational Unit Name (eg, section) []:piscinemorte.net
Common Name (e.g. server FQDN or YOUR name) []:piscinemorte.net


Une fois notre certificat généré et validé par Gandi, nous plaçons nos fichiers de certification dans les dossiers adéquates :

cp piscinemorte.net.crt /etc/ssl/certs/piscinemorte.net.crt
cp piscinemorte.net.key /etc/ssl/private/piscinemorte.net.key  
cp GandiStandardSSLCA2.pem /etc/ssl/certs/GandiStandardSSLCA2.pem

On notera que GandiStandardSSLCA2.pem est un certificat intermédiaire qui permet de certifier notre certificat.


Nous refaisons un hashage de la structure pour prendre en compte notre certificat :

c_rehash /etc/ssl/certs
Doing /etc/ssl/certs
piscinemorte.net.crt => 651ac028.0
piscinemorte.net.crt => 179c2ae2.0
GandiStandardSSLCA2.pem => 8544bf03.0
GandiStandardSSLCA2.pem => e279a80b.0
ssl-cert-snakeoil.pem => ac2485cc.0
ssl-cert-snakeoil.pem => 1682ec15.0


On créé le fichier 000-piscinemorte.net-ssl.conf dans /etc/apache2/sites-available/ pour associer apache2 avec notre nom de serveur :

#NameVirtualHost *:443
        <VirtualHost 193.48.57.163:443>
                ServerName www.piscinemorte.net
                ServerAlias piscinemorte.net
                DocumentRoot /var/www/www.piscinemorte.net/
                CustomLog /var/log/apache2/secure_acces.log combined

                SSLEngine on
                SSLCertificateFile /etc/ssl/certs/piscinemorte.net.crt
                SSLCertificateKeyFile /etc/ssl/private/piscinemorte.net.key
                SSLCertificateChainFile /etc/ssl/certs/GandiStandardSSLCA2.pem
                SSLVerifyClient None
        </VirtualHost>
        <Directory /var/www/www.piscinemorte.net>
                Require all granted
        </Directory>
ServerName "piscinemorte.net"


Nous avons modifié le fichier ports.conf du serveur Apache pour qu'il écoute le port 443 (SSL):

Listen 80 443

<IfModule ssl_module>
        Listen 443
</IfModule>


Il ne suffit plus qu'à activer le module SSL de Apache :

a2enmod ssl


Puis activer notre site avec notre certificat :

a2ensite 000-piscinemorte.net-ssl.conf
service apache2 reload
Cadenas vert visible depuis la barre de lien
Certificat délivré pour notre domaine

Sécurisation de serveur DNS par DNSSEC

Tout d'abord, on ajoute une option dans /etc/bind/named.conf.options pour activer dnssec :

dnssec-enable yes;


On créé un répertoire spécial pour y générer les clés

mkdir piscinemorte.net.dnssec
cd piscinemorte.net.dnssec


Puis on génère la clé de signature de clefs de zone (KSK) et la clé de la zone pour signer les enregistrements (ZSK)

dnssec-keygen -a RSASHA1 -b 2048 -f KSK -r /dev/urandom -n ZONE piscinemorte.net
dnssec-keygen -a RSASHA1 -b 1024 -r /dev/urandom -n ZONE piscinemorte.net

L'option "-r /dev/urandom" sert à accélérer la génération des clés


Après avoir renommé les clés générées, on les inclue dans notre fichier de zone /etc/bind/db.piscinemorte.net

$include /etc/bind/piscinemorte.net.dnssec/piscinemorte.net-ksk.key
$include /etc/bind/piscinemorte.net.dnssec/piscinemorte.net-zsk.key


On signe les enregistrements de la zone :

dnssec-signzone -o piscinemorte.net -k piscinemorte.net-ksk ../db.piscinemorte.net piscinemorte.net-zsk
Verifying the zone using the following algorithms: RSASHA1.
Zone fully signed:
Algorithm: RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
                    ZSKs: 1 active, 0 stand-by, 0 revoked
../db.piscinemorte.net.signed


Pour finir, il ne reste plus qu'à communiquer la partie publique de la KSK (et ZSK) à notre registrar (sur gandi.net via "Gérer DNSSEC") et vérifier la sécurisation :

Partie publie de la KSK (et ZSK) sur Gandi
Test du DNSSEC

Sécurisation et cryptage de données

Sécurisation de données via RAID5

On créer 3 disques virtuels avec lvcreate :

lvcreate -L 1G -n /dev/virtual/Deadpool-raid1
lvcreate -L 1G -n /dev/virtual/Deadpool-raid2
lvcreate -L 1G -n /dev/virtual/Deadpool-raid3


On les rajoute à notre configuration de machine virtuelle (/etc/xen/Deadpool.cfg) :

'phy:/dev/virtual/Deadpool-raid1,xvdd1, w',
'phy:/dev/virtual/Deadpool-raid2,xvdd2, w',
'phy:/dev/virtual/Deadpool-raid3,xvdd3, w',


Ensuite, nous avons besoin d'installer mdadm et mettre à jour le kernel sinon nous aurons une erreur de mdadm lors de la création du RAID5 :

apt-get install mdadm linux-image.3.16.0-4-amd64


Il ne nous reste plus qu'à créer notre disque RAID5 md0 :

mdadm --create /dev/md0 --level=5 --assume-clean --raid-devices=3 /dev/xvdd1 /dev/xvdd2 /dev/xvdd3


On installe un système de fichier ext4 dessus:

mkfs -t ext4 /dev/md0


On sauvegarde notre configuration :

mdadm --detail --scan >> /etc/mdadm/mdadm.conf


On le monte :

mount /dev/md0 /mnt


Après avoir créer un fichier dans notre RAID5, nous supprimons une des répartitions pour voir si le RAID5 se reconstruit correctement :

mdadm --set-faulty /dev/md0 /dev/xvdd2
mdadm --remove /dev/md0 /dev/xvdd2


On voit que la partition a bien été supprimée et nos données toujours présents :

cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid5 xvdd1[0] xvdd3[2]
      2095104 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [U_U]
mount /dev/md0 /mnt
[88763.077524] EXT4-fs (md0): recovery complete
[88763.077545] EXT4-fs (md0): mounted filesystem with ordered data mode. Opts: (null)
<pre>
root@Deadpool:/mnt# ls
lost+found  test.txt


Nous remettons la partition :

mdadm --add /dev/md0 /dev/xvdd2


Et on observe la reconstruction grâce à cat /proc/mdstat :

Personalities : [raid6] [raid5] [raid4] 
md0 : active raid5 xvdd2[3] xvdd1[0] xvdd3[2]
      2095104 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [U_U]
      [==========>..........]  recovery = 51.9% (544664/1047552) finish=0.2min speed=30259K/sec

Cryptage de données

Dans cette partie, nous allons voir comment crypter des données sur une carte SD.

On cherche notre carte sd dans dev :

ls /dev

puis on va configurer notre carte :

fdisk /dev/mmcblk1
  "d pour supprimer les partitions 1-2-3"
  "n pour ajouter des partitions"
  "w pour enregistrer"

On créé donc une unique partition de taille 15G sur mmcblk1p1.

On va maintenant configurer la carte SD en type Luks avec un chiffrement aes et un algorithme de hachage SHA256:

cryptsetup luksFormat -c eas -h sha256 /dev/mmcblk1

Avec la phrase secrète : pasglop

On peut vérifier les infos de la partitions avec :

cryptsetup luksDump /dev/mmcblk1

On ouvre notre partition cryptée avec :

cryptsetup luksOpen /dev/mmcblk1

en saisissant la phrase secrète.

et on ajoute des fichiers :

mkfs.ext3 /dev/mapper/kadoc

On décide de créer un dossier contenant un fichier txt contenant une phrase. Pour écrire dedans il faut monter notre carte :

 
mount -t ext3 /dev/mapper/kadoc /mnt/    pour monter la partition.
 
umount /mnt/                             pour démonter la partition.    

Il faut re-encrypter notre partition avec

 cryptsetup luksClose kadoc 

On peut vérifier avec GParted que notre partition n'est plus accessible, à moins d'avoir le mot de passe pour la décrypter.

gparted /dev/mmcblk1

Création de deux points d'accès Wi-Fi avec serveur d'authentification FreeRADIUS

Création du serveur FreeRADIUS

Tout d'abord, nous mettons en place un serveur d'identification FreeRADIUS en PEAP-MSCHAPv2 qui va tourner sur notre machine virtuelle.

Pour cela, il faut installer FreeRADIUS :

apt-get install freeradius


Puis, on ajoute un utilisateur dans le fichier /etc/freeradius/users pour s'authentifier sur le réseau WiFi :

nom_de_l_utilisateur Cleartext-password := "mot_de_passe"


On rajoute aussi les clients (correspondants aux deux points d'accès Wifi et à notre futur VLAN) dans le fichier /etc/freeradius/clients.conf :

client E304 {
        ipaddr = 10.60.1.6
        secret = mot_de_passe
}

client E306 {
        ipaddr = 10.60.1.2
        secret = mot_de_passe
}

client VLAN3 {
        ipaddr = 10.60.4.0
        secret = mot_de_passe
}


Pour utiliser le PEAP-MSCHAPv2, on modifie dans le fichier /etc/freeradius/eap.conf les valeurs suivantes :

eap
{
    default_eap_type = peap
    peap
    {
      default_eap_type = mschapv2
    }
}


On fini par redémarrer FreeRADIUS pour bien prendre en compte les nouveaux paramètres :

service freeradius restart

Configuration des bornes Wi-Fi

Une fois les points d'accès Wifi disponibles, nous pouvons les configurer afin de créer notre propre SSID protégé par la méthode WPA2-EAP avec notre serveur d'authentification FreeRadius.

On commence par se connecter à l'une des deux bornes Wifi via Telnet :

telnet 10.60.1.2


Nous configurons le point d'accès (login : Cisco / password : Cisco) de la manière suivante pour créer notre VLAN et notre SSID :

enable

conf t

aaa new-model
aaa authentication login eap_deadpool group radius_deadpool
radius-server host 193.48.57.163 auth-port 1812 acct-port 1813 key mot_de_passe
aaa group server radius radius_deadpool
server 193.48.57.163 auth-port 1812 acct-port 1813
exit

dot11 ssid Deadpool
vlan 4
authentication open eap eap_deadpool
authentication network-eap eap_deadpool
authentication key-management wpa
mbssid guest-mode
exit

interface Dot11Radio0
encryption vlan 4 mode ciphers aes-ccm tkip
ssid Deadpool
exit

interface Dot11Radio0.4
encapsulation dot1Q 4
no ip route-cache
bridge-group 4
bridge-group 4 subscriber-loop-control
bridge-group 4 spanning-disabled
bridge-group 4 block-unknown-source
no bridge-group 4 source-learning
no bridge-group 4 unicast-flooding 
exit

interface GigabitEthernet0.4
encapsulation dot1Q 4
bridge-group 4
exit
 
exit

Pour le deuxième point d'accès, il suffit de refaire la même chose.

Connexion à notre Wi-Fi

On se connecte à notre point d'accès grâce à nos identifiants créés précédemment dans la configuration de FreeRadius.

On configure l'accès sur un eeepc en modifiant le fichier /etc/network/interfaces :

auto wlan0
iface wlan0 inet static
 address 10.60.4.10
 netmask 255.255.255.0
 gateway 10.60.4.1
 wpa-ssid Deadpool
 wpa-key-mgmt WPA-EAP
 wpa-identity nom_de_l_utilisateur
 wpa-password mot_de_passe


Enfin, on démarre l'interface pour se connecter sur notre point d'accès :

ifup wlan0
iwconfig
wlan0     IEEE 802.11bgn  ESSID:"Deadpool"  
          Mode:Managed  Frequency:2.447 GHz  Access Point: 44:AD:D9:5F:87:00   
          Bit Rate=1 Mb/s   Tx-Power=20 dBm   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=59/70  Signal level=-51 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:1  Invalid misc:53   Missed beacon:0


On arrive à ping notre eePC depuis la machine virtuelle :

root@Deadpool:/# ping 10.60.4.10
PING 10.60.4.10 (10.60.4.10) 56(84) bytes of data.
64 bytes from 10.60.4.10: icmp_seq=1 ttl=62 time=1.22 ms
64 bytes from 10.60.4.10: icmp_seq=2 ttl=62 time=1.57 ms
64 bytes from 10.60.4.10: icmp_seq=3 ttl=62 time=8.32 ms
64 bytes from 10.60.4.10: icmp_seq=4 ttl=62 time=9.30 ms
64 bytes from 10.60.4.10: icmp_seq=5 ttl=62 time=1.55 ms
64 bytes from 10.60.4.10: icmp_seq=6 ttl=62 time=1.29 ms
^C
--- 10.60.4.10 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
rtt min/avg/max/mdev = 1.226/3.879/9.304/3.501 ms


En ayant préalablement activé les logs des connexions dans la configuration de FreeRadius, on peut observer les authentifications dans /var/log/freeradius/radius.log :

Thu Dec  8 13:56:09 2016 : Info: Loaded virtual server <default>
Thu Dec  8 13:56:09 2016 : Info: Loaded virtual server inner-tunnel
Thu Dec  8 13:56:09 2016 : Info: Ready to process requests.
Thu Dec  8 13:59:58 2016 : Auth: Login OK: [pifou/<via Auth-Type = EAP>] (from client E306 port 0 via TLS tunnel)
Thu Dec  8 13:59:58 2016 : Auth: Login OK: [pifou/<via Auth-Type = EAP>] (from client E306 port 326 cli 40a5.ef05.a110)

DHCP et PCBX

Configuration du DHCP

On installe de quoi faire un serveur DHCP sur notre eePC :

apt-get install isc-dhcp-server


On configure notre serveur DHCP via le fichier de configuration (/etc/dhcp/dhcpd.conf)

    option domain-name "piscinemorte.net";
    option domain-name-servers ns.piscinemorte.net;
    
    subnet 10.60.4.0 netmask 255.255.255.0 {
         range 10.60.4.11 10.60.4.30
         option routers 10.60.4.254
    }


Après avoir redémarré notre serveur DHCP, on se connecte facilement à notre point d'accès grâce au DHCP qui nous attribue une adresse IP dans la plage voulue :

Informations de connexion sur un Sony Xperia S
Informations de connexion sur un Iphone

Configuration et utilisation du PCBX

On installe Asterisk pour créer un serveur permettant une communication SIP :

apt-get install asterisk


Configuration via /etc/asterisk/sip.conf :

[general]
allowguest=no
alwaysauthreject=yes
contactacl=local_ip_acl
hasvoicemail = yes
hassip = yes
hasiax = yes
callwaiting = yes
threewaycalling = yes
callwaitingcallerid = yes
tranfer = yes
canpark = yes
cancallforward = yes
callreturn = yes
callgroup = yes
pickupgroup = yes
nat = yes

[6001]
type=peer
host=dynamic
dtmfmode=rfc2833
disallow=all
allow=ulaw
fullname=dpl1
username=dpl1
secret=secret
context=work
acl=acl1

[6002]
type=peer
host=dynamic
dtmfmode=rfc2833
disallow=all
allow=ulaw
fullname=dpl2
username=dpl2
secret=secret
context=work
acl=acl1


Configuration via /etc/asterisk/extensions.conf :

[work]
exten => _6XXX,1,Dial(SIP/${EXTEN},20)
exten => _6XXX,2,Hangup()


Configuration des autorisations via /etc/asterisk/acl.conf :

acl = acl1

[acl1]
permit=0.0.0.0/0.0.0.0


On se connecte à un compte SIP (dpl1 et dpl2) et on passe un appel grâce à l'identifiant configuré précédemment :

Serveur asterisk avec les téléphones connectés
Communication entre les deux téléphones via SIP

Références

Pour la gestion du serveur DAS :