Application automatique des mises à jour de sécurité

Une mésaventure m’est arrivée ce matin sur ma VM hebergeant un site LAMP avec une installation TURNKEY. J’avais activé les mise à jour automatique de sécurité en voulant m’éviter d’aller manuellement faire des “apt-get dist-upgrade” quand apticron m’alerte par mail.

Ce matin Jetpack me previent que mon site est indisponible. Rien d’affolant jusque là car je n’ai jamais eu le temps de régler l’installation pour la charge attendue etde temps à autre, linux tue mes processus mysql. C’est vrai que je suis plus famillier des applications Java que Php.

Le message qui s’affichait était un habituel “Erreur de connexion à la base de données”. Dans ce cas je fait un tour sur la VM à la recherche du status du service mysql. Et la c’est le drame ! Pas de service mysql enregistré. Un tour dans /var/log/message pour constater que le paquet mysql avait été désinstallé! Par qui ? par quoi ? un hacker ?

La trace indique que c’est cron-apt qui a lancé la suppression et en allant voir l’historique des commande dans /var/log/apt/history.log je vois:

Start-Date: 2018-11-20 04:54:11
Commandline: /usr/bin/apt-get -o quiet=1 dist-upgrade -q -y -o APT
:Get::Show-Upgraded=true -o Dir::Etc::sourcelist=/etc/apt/sources.
ist.d/security.sources.list -o Dir::Etc::sourceparts=nonexistent –
DPkg::Options::=–force-confdef -o DPkg::Options::=–force-confol
Upgrade: mariadb-common:amd64 (10.1.26-0+deb9u1, 10.1.37-0+deb9u1)
mariadb-server-core-10.1:amd64 (10.1.26-0+deb9u1, 10.1.37-0+deb9u
), mariadb-client-core-10.1:amd64 (10.1.26-0+deb9u1, 10.1.37-0+deb
u1)
Remove: mysql-server:amd64 (5.5.9999+default), mariadb-server-10.1
amd64 (10.1.26-0+deb9u1), default-mysql-server:amd64 (1.0.2), mari
db-client-10.1:amd64 (10.1.26-0+deb9u1)
End-Date: 2018-11-20 04:56:13

Je ne suis pas absolument sûr que c’est la mise à jour automatique de sécurité qui est la seule en cause ou bien si c’est une mauvaise configuration entre turnkey et les dépôt de debian mais en tout depuis cette mise à jour de la version 10.1.26 vers la 10.137 je n’ai plus de BDD.

Encore quelques heures à passer dans l’administration du système…

update1: une mise installation manuelle par un apt-get install mariadb-server remet tout en ordre

update2: un mail de la part de turnkey indique la marche officielle pour correction. //www.turnkeylinux.org/blog/debian-secupdate-breaks-lamp-server

Avec le libre les problèmes sont pris en compte rapidement.

Tubes nommés et redirections en parallèle

La ligne de commande est bien faite. Cette phrase est souvent entendue dans la bouche des informaticiens. J’en ai encore vérifié la véracité ses jours derniers.

Ma problèmatique était de constituer des statistiques sur des accès HTTP en consultant un fichier de log. La volumétrie des log étant de l’ordre de plusieurs gigaoctets et je ne disposais que de ma ligne de commande en bash.

Je me suis alors dirigé vers une serie de grep avec les bons motifs de recherche couplé à un bon vieux wc:

grep motif fichier.log | wc -l

Pour compliquer il y avait plusieurs motifs differents à compter et il fallait produire un fichier par jour avec le comptage de chaques motifs.

ACCES_COUNT=`grep -e motif_date -e motif_acces fichier.log | wc -l`

Autant de ligne de ce genre que de motif. L’inconvenient est que l’on parcourt la log autant de fois qu’il y a de motif d’acces pour une date donnée. Dans mon cas j’avais 15 motifs soit 1h30 pour obtenir les statistiques pour un jour donné.

Or, une fois que l’on est sur la bonne date dans le fichier de log c’est dommage de le reparcourir depuis le debut pour le motif d’accès suivant. D’où l’idée d’externaliser le parcours du fichier à la recherche de la bonne date puis de dispatcher la ligne aux grep qui compte les motifs d’accès.

tee

On a donc envie de faire un premier grep dont on va diriger la sortie sur d’autres grep en arborscence. La première pièce du puzzle est la commande tee. Voici l’idée :

grep -e motif_date fichier.log | tee -a entree_proc_grep1 entree_proc_grep2 … > /dev/null

Il manque la seconde piece qui est celle qui permet de definir un tube entre le premier grep et les autres qui doivent s’exécuter en parallèle. C’est là que les tube nommés interviennent.

named pipe

La commande mkfifo crée un tube nommé que l’on donne en entrée au grep de motif d’accès. Ces grep seront alors bloqués en attente de lire des donnés dans leurs tubes respectifs.

mkfifo entree_proc_grep1

grep -e motif_acces < entree_proc_grep1 | wc -l > fichier_temp1` &

PID_LIST+=” $!”

Autant de lignes de ce genre qu’il y a de motif d’accès à compter. Remarquons qu’à ce stade on à seulement créé des processus pour faire les grep de comptage et qu’ils sont tous bloqués en attentes sur leur tube. On alimente ensuite les tubes. Voici l’ordre

  1. créer les tube
  2. lancer en arrière plan les grep prenant les tubes en entrée
  3. lancer le grep sur la date pipé avec le tee vers les tubes

Subtilites

On ne peut plus récupérer la valeur des wc car c’est un sous shell qui l’exécute. On passe par un fichier temporaire.

On stocke la liste des pid des grep de comptage car le shell courant qui est leur parent doit attendre qu’ils soient tous finis avant d’aller lire les resultats dans les fichiers temporaires.

wait $PID_LIST

cat fichier_temp1

cat fichier_temp2

….

Dans mon cas particulier je suis passé de 1h30 de traitement pour avoir les statistiques d’un jour donné à seulement 3 minutes !

Finitions

Pour être propre il faut terminer en supprimant les fichiers temporaires (de comptage et les tubes).

Pour pouvoir lancer plusieurs instance du script sur des dates differentes en parallèle, ii faut ajouter le pid du script dans les noms des fichiers temporaires ( tubes nommés et comptage).

Dans mon cas particulier il me fallait les statistiques de plusieurs jours: chaque jour ayant sa propre stat. On peut lancer le script manuellement pour chaque jour ou bien intérer sur les jours, ce qui donne a peu près ceci:

for jour in 1 2 3 4

do

mkfifo entree_proc_grep1

grep -e motif_acces < entree_proc_grep1 | wc -l > fichier_temp1` &

PID_LIST+=” $!”

…..

grep -e motif_date fichier.log | tee -a entre_proc_grep1 entree_proc_grep2 … > /dev/null

wait $PID_LIST

cat fichier_temp1 >> fichier_stat_$jour

echo “” >> fichier_stat_$jour

…..

rm entree_proc_grep1

….

done

On remarque encore que pour chaque jour en parcourt l’ensemble de la log d’accès. Or dès le premier passage on a deja passé sur toutes les dates possibles. Une seule passe doit suffire ! L’idée est que le grep sur le motif de la date ne prenne plus le fichier de log en entrée mais un tube nommé…

for jour in 1 2 3 4

do

mkfifo entree_proc_grep1_$jour

grep -e motif_acces < entree_proc_grep1_$jour | wc -l > fichier_temp1_$jour` &

PID_LIST+=” $!”

…..

mkfifo entree_proc_$jour

PROC_JOUR_LIST+=” entree_proc_$jour”

grep -e motif_date entree_proc_$jour| tee -a entre_proc_grep1_$jour entree_proc_grep2_$jour … > /dev/null &

PID_LIST+=” $!”

done

cat fichier_log | tee -a $PROC_JOUR_LIST > /dev/null

wait $PID_LIST

for jour in 1 2 3 4

do

cat fichier_temp1_$jour >> fichier_stat_$jour

echo “” >> fichier_stat_$jour

…..

rm entree_proc_grep1_$jour

….

rm entree_proc_$jour

done

C’est un peu plus compliqué car pour distinguer tous ces tubes nommés on doit ajouter le numero de jour à leur nom.

Eviter ainsi de reparcourir la log depuis le début pour chaque jour permet d’aller plus vite. Dans mon cas particulier pour les statistiques de 3 jours je suis passé de 2mn50 à 0mn45s et pour les statistiques de 14 journées je suis passé de 22mn à 5mn !

Moralité de l’histoire, l’algorithmie alliée à la ligne de commande et la puissance du shell ça fait des étincelles.

Out of memory dans le kernel Linux

Sous ce titre se cache les soucis de disponibilité de mes sites web virtualisés. Depuis quelques mois ils tombent de temps en temps, surtout quand il y a un peu de charge c’est-à-dire quand j’y publie un article un peu racoleur  et que le nombre d’accès journalier dépasse l’extraordinaire nombre de quelques dizaines d’utlisateurs….

Quand cela arrive c’est souvent le SGBD qui a “crashé” et c’est signalé par un jolie “impossible d’obtenir une connexion à la base de donnée”. Le SGBD est effectivement arrêté et le redémarrer permet de remettre en fonctionnement le site. Le plus intéressant est de trouver la cause du crash.

Dans la log de démarrage on peut y voir des erreur /var/log/mysql/error.log:

181014  6:30:23 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
181014  6:30:23 [Note] Plugin 'FEDERATED' is disabled.
181014  6:30:27 InnoDB: The InnoDB memory heap is disabled
181014  6:30:27 InnoDB: Mutexes and rw_locks use GCC atomic builtins
181014  6:30:27 InnoDB: Compressed tables use zlib 1.2.8
181014  6:30:27 InnoDB: Using Linux native AIO
181014  6:30:29 InnoDB: Initializing buffer pool, size = 128.0M
181014  6:30:31 InnoDB: Completed initialization of buffer pool
181014  6:30:35 InnoDB: highest supported file format is Barracuda.
InnoDB: Log scan progressed past the checkpoint lsn 15552477668
181014  6:30:35  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...


En poussant l’investigation plus loin par un grep de “mysql” dans /var/log/syslog

Oct 14 01:14:54 wordpress kernel: [1971121.772280] INFO: task mysqld:13245 blocked for more than 120 seconds.
Oct 14 01:14:54 wordpress kernel: [1971121.772288] mysqld D ffff880019674468 0 13245 611 0x00000000
Oct 14 01:20:56 wordpress kernel: [1971481.772349] INFO: task mysqld:14574 blocked for more than 120 seconds.
Oct 14 01:20:56 wordpress kernel: [1971481.772358] mysqld D ffff880079cf8f38 0 14574 611 0x00000000
Oct 14 01:32:55 wordpress kernel: [1972201.772091] INFO: task mysqld:13240 blocked for more than 120 seconds.
Oct 14 01:32:55 wordpress kernel: [1972201.772094] mysqld D ffff8800197a4828 0 13240 611 0x00000000
Oct 14 01:34:53 wordpress kernel: [1972321.772343] INFO: task mysqld:13240 blocked for more than 120 seconds.
Oct 14 01:34:53 wordpress kernel: [1972321.772351] mysqld D ffff8800197a4828 0 13240 611 0x00000000
Oct 14 01:38:54 wordpress kernel: [1972561.772076] INFO: task mysqld:13240 blocked for more than 120 seconds.
Oct 14 01:38:54 wordpress kernel: [1972561.772078] mysqld D ffff8800197a4828 0 13240 611 0x00000000
Oct 14 01:55:40 wordpress kernel: [1973565.634464] [ 611] 0 611 1085 1 7 39 0 mysqld_safe
Oct 14 01:55:40 wordpress kernel: [1973565.634471] [ 1188] 104 1188 226779 4831 131 25556 0 mysqld
Oct 14 01:55:40 wordpress kernel: [1973565.634837] Out of memory: Kill process 1188 (mysqld) score 39 or sacrifice child
Oct 14 01:55:40 wordpress kernel: [1973565.634847] Killed process 1188 (mysqld) total-vm:907116kB, anon-rss:19324kB, file-rss:0kB
Oct 14 01:55:40 wordpress kernel: [1973568.287694] [ 611] 0 611 1085 1 7 39 0 mysqld_safe
Oct 14 01:55:40 wordpress kernel: [1973568.287706] [17643] 104 1188 226779 5726 131 24720 0 mysqld
Oct 14 01:55:40 wordpress kernel: [1973568.288313] Out of memory: Kill process 17643 (mysqld) score 39 or sacrifice child
Oct 14 01:55:40 wordpress kernel: [1973568.288317] Killed process 17643 (mysqld) total-vm:907116kB, anon-rss:22904kB, file-rss:0kB
Oct 14 03:54:02 wordpress kernel: [1980665.296368] [ 611] 0 611 1085 4 7 40 0 mysqld_safe
Oct 14 03:54:02 wordpress kernel: [1980665.296430] [17670] 104 17670 228505 5694 97 11154 0 mysqld
Oct 14 03:54:03 wordpress kernel: [1980665.296509] Out of memory: Kill process 17670 (mysqld) score 21 or sacrifice child
Oct 14 03:54:03 wordpress kernel: [1980665.296515] Killed process 17670 (mysqld) total-vm:914020kB, anon-rss:22776kB, file-rss:0kB
Oct 14 03:54:03 wordpress kernel: [1980668.526394] [ 611] 0 611 1085 3 7 40 0 mysqld_safe
Oct 14 03:54:03 wordpress kernel: [1980668.526456] [20409] 104 17670 228505 6736 97 10220 0 mysqld
Oct 14 03:54:03 wordpress kernel: [1980668.526536] Out of memory: Kill process 21984 (mysqld) score 21 or sacrifice child
Oct 14 03:54:03 wordpress kernel: [1980668.526537] Killed process 20409 (mysqld) total-vm:914020kB, anon-rss:26920kB, file-rss:24kB
Oct 14 03:55:21 wordpress kernel: [1980749.353383] [ 611] 0 611 1085 1 7 40 0 mysqld_safe
Oct 14 03:55:21 wordpress kernel: [1980749.357504] [ 611] 0 611 1085 1 7 40 0 mysqld_safe

Linux décide donc de tuer des processus quand il est à court de mémoire. Il lui arrive même de tuer des processus apache2. En faisant un grep de “apache2” dans /var/log/syslog

Oct 14 03:55:21 wordpress kernel: [1980749.357771] Out of memory: Kill process 13173 (apache2) score 13 or sacrifice child
Oct 14 03:55:21 wordpress kernel: [1980749.357772] Killed process 13173 (apache2) total-vm:457020kB, anon-rss:1708kB, file-rss:0kB

Il ne me reste plus qu’a allouer un peu plus de mémoire à mes VM que le petit gigaoctet par défaut. Trêve de radinerie.

 

 

 

 

The Pyra – un debian dans la poche

Pyra est un ordinateur de poches complet fonctionnant sous debian. Pas de fabrication de à la chaîne ici mais en petite quantité par des passionnés. Encore une fois ce sont les allemands qui s’illustrent à la manière de GoldenDelicious avec son GT04 successeur de l’openmoko un telephone linux. L’assembleur Dragonbox adresse une cible un peu différente puisque le pyra en successeur du Pandora est un ordinateur de poche qui peut faire telephone: voilà un digne héritier du N900.

Official Pyra and Pandora Site

Source : The Pyra

RSYNC depuis AIX vers Linux

Ce billet aurait pu s’intituler “mes aventures dans le monde AIX” ou bien “comment faire du nohup sur AIX” mais se serait être malhonnête car laisserait croire que tous mes problèmes venaient de cet OS propriétaire. Pour être exact le contexte était celui d’un transfert de fichiers depuis une machine AIX 5.3 vers un Linux Cent OS.

Je ne pensais pas que j’allais être confronté à tant de subtilités. Si certaines sont imputables à la limite de mes connaissances en scripting, d’autres ont pour cause les différences entre le monde merveilleux de Linux et celui de AIX.

En premier lieu voici la liste des contraintes imposées par des besoins fonctionnelles, des contraintes de sécurités et des raisons pratiques.

  • c’est AIX qui pilote le transfert: la sécurité impose ce sens de flux
  • les fichiers les plus récents  doivent être copiés en premier: besoin fonctionnel
  • seul les fichiers de moins d’un certain âges seront copiés: contrainte fonctionnelle.
  • la commande de transfert doit être en nohup: raison pratique car le transfert va être long.

Le chemin fut semé d’embûches avant d’arriver à mes fins dont la plupart vient des spécificités du système AIX.

La première difficulté est venue du tri pour obtenir les fichiers les plus récents en premier. Sous Linux on fait un find avec un printf suivi d’un sort

find . -type for -ctime -1460 -printf "T@ %p\n" | sort -r | awk '{print $(NF)}'

pas de printf dans la fin de AIX

la clé NF pour le awk non plus ou conséquence du point precendent

J’avais envie d’utiliser l’option exec du find en lui passant un stat comme ceci

find . -type for -ctime -1460 -exec stat -c '%Y %n' {} \; | sort -r | awk '{print $(2)}'

Pas de stat sous AIX

Malheureusement la commande stat n’existe pas sous AIX et la commande qui s’en rapproche n’a pas la même fonctionnalité. La solution est de passer par une commande perle dans le exec du find

find . -type for -ctime -1460 -exec perl -e '@tmp=stat ($ARGV [0]); print "$tmp [10]\t $ARGV [0]\n";' | sort -r | awk '{print $(2)}'

Mon dieu que c’est compliqué ! Et je n’étais pas au bout de mes peines.

Nohup et pipe

Le lecture ajoutera de lui même un pipe supplémentaire pour faire le rsync. Là n’est pas la question…. quoique on verra plus tard. Il s’agit surtout de mettre toutes ces commandes en nohup. Comme

nohup cmd1 | cmd2

ne porte le nohup que sur cmd1 l’idée est de passer par un seul sous she’ll qui sera vu comme une seule commande.

nohup $SHELL<<EOF &
find . -type for -ctime -1460 -exec perl -e '@tmp=stat ($ARGV [0]); print "$tmp [10]\t $ARGV [0]\n";' | sort -r | awk '{print $(2)}'
EOF

Ceci fonctionne bien sous Linux et il suffit de remplacer les commandes compliquées par un sleep mais sous AIX ?

Pas de sous shell avec le nohup AIX

La documentation IBM AIX disponible sur Internet est formelle. Si le nohup AIX prend en argument une et une seule commande. La seule moyen est de passer un script qui sera vu comme une commande pour le nohup.

nohup sh mon_script.sh

Rsync

Apres les difficultés liées à AIX j’avais également oublié de faire un échange de clé car en nohup on ne pourra pas saisir de mot de passe. Cela n’a rien à voir avec l’AIX, j’étais seulement absorbé sur les spécificités de l’AIX que j’en ai oublié cette subtilité.

Juste pour le plaisir… CC-BY-SA

Ransomware Linux

Il est loin le temps où avoir une machine  sous Linux protégeait des attaques des Virus. Quand j’ai commencé à héberger mon site web, au début des années 2000 j’avais utilisé un serveur Web dédié  (Savant Web serveur) sur Windows et j’avais été très étonné de constater le nombre de tentative  d’accès à des répertoires système de L’OS.  Ces tentatives échouaient car le serveur Web n’était pas IIS….

Depuis j’ai passé toutes mon informatique personnelle en GNU/Linux et je n’ai jamais été confronté à des attaques…. jusqu’à la semaine dernière.

Les pirates ciblent désormais également les machines Linux. Ainsi mes fichiers de disques de VM se sont mis à être renommés avec des suffixes .enc ! Ce que je pensais être un problème d’espace dans ma VM était bel et bien une attaque d’un virus de type ransomware. Tous mes fichiers personnels ainsi que la configurations apache et celle du serveur DNS étaient cryptées.

Heureusement que j’ai des sauvegardes… mais le désagrément causé est certain: rupture de service, éventuelle perte de données (de quand date la dernière sauvegarde?). On ne pense jamais assez aux sauvegardes ! La première chose à faire façe à une infection que l’on ne peut pas éradiquer (manque de littérature et désintérêt des éditeurs) est de limiter la casse. Arrêter le système car le virus à réussi à obtenir les droits root ou du groupe root puisqu’il chiffre des fichiers en écriture à root. Donc arrêter le système puis débrancher le câble d’alimentation ! Ensuite démarrer depuis une clé usb de type live-cd pour récupérer ce qui peut l’être. Enfin réinstaller le système complètement.

Après l’incident il faut également cherchez à s’en prémunir. Comment une telle infection à pu survenir ? Il y a 2 ou 3 semaines mon  serveur n’a pas redémarré sur échec de montage d’un Volume logique. Suite à cet étrange incident je n’avais trouvé comme solution que de démarrer sur un kernel précédent: coïncidence ou la première étape de l’attaque ? M’obliger à utiliser un kernel ancien contenant des failles ?

Ne jamais utiliser de kernel non à jour !

Leçon à retenir: Linux n’est plus sous les radars. Il faut donc s’équiper d’antivirus et d’antispam. Les solutions existent:clamav et spamassasin.

Juste pour le plaisir… CC-BY-SA

Sauvegarde à chaud de VM

Avoir du RAID redondé c’est bien pour éviter la coupure de service en cas de panne matériel mais cela ne protège pas des effacements par erreur. Il faut des sauvegardes.

Comme ce que je recherche c’est de pouvoir revenir à  un l’état de mes données dans le passé, je laissz dz côté la sauvegarde de la définition des VM.

Un script glané sur le site de Debian me sert de base //wiki.debian.org/fr/RsyncSnapshots. Il utilise rsync avec des liaison dur avec la précédente sauvegarde. Un peu inutile quand les VM sont allumée en permanence mais trouve son intérêt quand les fichiers ne changent pas d’une sauvegarde à l’autre.

Voici le script:

#!/bin/sh
##==========================================================================
## Auteur      : Thierry BRESSURE
## Licence     : GNU GPL v3 – //www.gnu.org/licenses/gpl.html
## Description : Script de sauvegarde disques des VM
##============================================================================
## Parametres d’entree : liste des profils a sauvegarder.
## Exemple d’appel     : rsync.sh blog kitejust4fun
## Code de retour      :
##  0 – La sauvegarde des disques s’est correctement terminee.
##============================================================================

ROOT_BACKUP=/media/backup
DEVICE_BACKUP=/dev/sdc1

#####################################
# GESTION DE L’APPEL DE LA COMMANDE #
#####################################

# Recuperation des profils passes en parametre.
if [ $# -ne 0 ]
then
    while [ $# -ne 0 ]
    do
        domains=”$domains $1 ”
        shift
    done
# Aucun domain n’est passe en parametre, on fait donc la sauvegarde pour tout
# le monde.
else
    # lister les vm
    domains=`virsh list | sed 1,2d | awk ‘{print $2}’`   
fi

###################################
# MONTAGE DU DISQUE DE SAUVEGARDE #
###################################

if [ ! -d $ROOT_BACKUP ]
then
   rm -rf $ROOT_BACKUP
   mkdir $ROOT_BACKUP
fi

montage=0

mount | grep “$ROOT_BACKUP” 2>/dev/null
if [ $? -ne 0 ]
then
mount -t ext4 $DEVICE_BACKUP $ROOT_BACKUP && montage=1

fi

####################################
# BOUCLE DE SAUVEGARDE DES PROFILS #
####################################

for un_domain in $domains
do

date_sauvegarde=$(date “+%Y%m%d_%H%M%S”)

echo
echo “${date_sauvegarde} – sauvegarde de la VM ${un_domain}”
        echo “—————————————–”
     

nombre_de_sauvegardes=2
# Creation d’un fichier temporaire pour y ecrire les fichiers et
# repertoires a ne pas sauvegarder (pour ne mettre que le fichier
# temporaire en parametre de la commande rsync)
ce_quil_ne_faut_pas_sauvegarder=$(tempfile)
:>$ce_quil_ne_faut_pas_sauvegarder
# Exclusions generales
echo “*~” >> $ce_quil_ne_faut_pas_sauvegarder

## DECOUVRIR LES DISQUES DE LA VM

        les_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`
               
       

## CREER UN SNAPSHOT
    virsh snapshot-create-as –domain ${un_domain} “${date_sauvegarde}” –atomic –disk-only

        ## garder en memoire les disques temporaires de la VM

        les_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`

## SAUVEGARDE

  # Si le repertoire de sauvegarde n’existe pas, je le cree.
    if [ ! -d $ROOT_BACKUP/vm_”${un_domain}” ]
    then
        echo “L’emplacement de la sauvegarde n’existait pas.”
        mkdir $ROOT_BACKUP/vm_”${un_domain}”
    fi

    ##############
    # SAUVEGARDE #
    ##############
   
    #il peut avoir plus d’un disque à sauvegarder
    for ce_quil_faut_sauvegarder in ${les_images_disques}
    do
    if [ -L $ROOT_BACKUP/vm_”${un_domain}”/current ] \
        && [ -d $ROOT_BACKUP/vm_”${un_domain}”/current ]
   then
        # Si une precedente sauvegarde existe, on la lie en dur.
        rsync  –delete-excluded –partial \
       –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
       –link-dest=$ROOT_BACKUP/vm_”${un_domain}”/current \
–exclude-from “${ce_quil_ne_faut_pas_sauvegarder}” \
“${ce_quil_faut_sauvegarder}” \
      $ROOT_BACKUP/vm_”${un_domain}”/”${date_sauvegarde}”/
else
        # Sinon, on en cree une toute neuve !
      rsync –delete-excluded –partial \
      –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
–exclude-from “${ce_quil_ne_faut_pas_sauvegarder}” \
       “${ce_quil_faut_sauvegarder}” \
       $ROOT_BACKUP/vm_”${un_domain}”/”${date_sauvegarde}”/
    fi

    retour_rsync=$?
if [ $retour_rsync -ne 0 ]
then
echo “le disque ${ce_quil_faut_sauvegarder} n’a pas pu etre sauvegarder, on annule le reste”
break
fi      
echo # Pour passer une ligne 🙂

    done

    # Suppression du fichier temporaire qui stocke les repertoires a exclure
    rm $ce_quil_ne_faut_pas_sauvegarder

    #######################
    # GESTION DES ERREURS #
    #######################

    # Pas d’erreur
    if [ $retour_rsync -eq 0 ]
    then
        # La sauvegarde a reussit, on cree un lien “current” pour retenir la
        # derniere.
        rm -f $ROOT_BACKUP/vm_”${un_domain}”/current 2>/dev/null
        ln -s $ROOT_BACKUP/vm_”${un_domain}”/”${date_sauvegarde}”/ \
            $ROOT_BACKUP/vm_”${un_domain}”/current

        # Si le nombre de snapshots depasse nombre_de_sauvegardes, je purge.
        nombre_snapshots=$((`ls $ROOT_BACKUP/vm_”${un_domain}” | wc -l` – 1))
        if [ ${nombre_snapshots} -gt $nombre_de_sauvegardes ]
        then
            # On supprime la plus vieille des sauvegardes
            plus_ancienne=”$(ls $ROOT_BACKUP/vm_”${un_domain}” | head -n 1)”
            rm -rf $ROOT_BACKUP/vm_”${un_domain}”/”${plus_ancienne}”
            echo “Purge de la plus ancienne sauvegarde : ${plus_ancienne}.”
        else
            echo “Aucune sauvegarde anterieure ne doit etre supprimee.”
        fi
    # Probleme lors de la sauvegarde rsync
    else
        # La sauvegarde a echouee, on affiche une erreur et on supprime la
        # tentative.
        echo “La commande rsync a echouee pour l’utilisateur ${un_domain}.”
        echo “Suppression de la sauvegarde en erreur : ${date_sauvegarde}.”
        rm -rf $ROOT_BACKUP/vm_”${un_domain}”/”${date_sauvegarde}”/
    fi
   

## REBASCULER LA VM VERS CHAQUE DISQUE ORIGINAL
    for un_disque in $les_disques
do
    virsh blockcommit ${un_domain} ${un_disque} –active –verbose –pivot
done
   
## SUPPRIMER LE SNAPSHOT DEVENU INUTILE
        virsh snapshot-delete –domain ${un_domain} –metadata ${date_sauvegarde}

## supprimer les disques temporaires qui ne sont hélas pas supprimés par la commande précédente
for image_temp in $les_images_disques_temp
do
echo “suppression du disque temporaire ${image_temp}…”
rm -rf “${image_temp}” && echo “$image_temp supprimé”
done
done

###########################
# démontage si nécessaire #
###########################

if [ $montage -eq 1 ]
then
    umount $ROOT_BACKUP
fi

exit 0

Juste pour le plaisir… CC-BY-SA

Installation Linux par clé USB

La clé USB étant devenue la disquette des temps modernes, il est naturel de s’en servir comme support pour accueillir les ISO des cd/dvd d’installation de Linux. Depuis l’OS propriétaire il existe plusieurs outils pour réaliser cette tâche préliminaire avant de pouvoir booter sur la clé.

Ainsi il y a très longtemps j’avais utilisé  Unetbootin mais ce n’est pas le bon outil si la distribution est un peu personnalisée avec des scripts d’installation spécifiques. Un autre outil USB Universal Installer ne fait pas mieux outrepassant une installation depuis des dépôts spécifiques pour aller chercher les paquets sur internet.

J’ai trouvé le salut avec Rufus qui ne change pas le menu d’installation de l’ISO et conserve bien les scripts d’installation. Un petit écueil que mérite bien un passage de mon poste de travail professionnel sous Linux.

Le libre dans le dessin vectoriel et l’animation

Je n’ai jamais utilisé autre chose que GIMP pour faire des dessins libres. Les fonctions de bases répondaient parfaitement à mes besoins: redimensionner, ajouter du texte etc. Par ailleurs je voyais souvent des gens utiliser des logiciels plus sophistiqués mais privateurs de libertés pour faire du dessin vectoriel ou de l’animation. Ces gens prétendaient que Linux (sic) ne proposait pas une alternative à leur besoin. Comme ces gens étaient ni plus ni moins que des utilisateurs occasionnels de ces  logiciels (i.e. n’utilisant que 10% des fonctions), je mettais en doute leur parole:

“Le libre propose une alternative dans la dessin vectoriel et l’animation”

Comme toujours je fais l’effort d’apprendre à utiliser un logiciel que si c’est nécessaire. Il se trouve que pour les besoins de mon hobby j’avais besoin de faire des schémas, des animations et des vidéos. Voilà une bonne raison de tester les logiciels libres destinés à cet usage.

Inkscape

Le logiciel de dessin vectoriel Inkscape est facile d’accès et permet de dessiner des objets vectoriels que l’on pourra cloner, changer de forme et de tailles perdre en qualité. Ce logiciel est très pratique pour réaliser des schémas ou faire des affiches. Le format de fichier consacré est SVG. Utilisez ce format au lieu des formats propriétaires ! Pour l’export utilisez le format PNG.

360 paire
Exemple de schéma réalisé avec Inkscape

Blender

Le logiciel Blender permet de faire de la modélisation et de l’animation en 3D. Il peut paraître compliqué (et il l’est !) mais pas plus que les solutions propriétaires. De plus sa puissance est stupéfiante:

Cinelerra

Pour le montage vidéo à proprement parler, la solution que je préfère est Cinelerra qui propose une interface similaire à Blender et des fonctions avancées (fusion d’image, nombre de pistes illimités, effet vidéos etc). Cinelerra travaille sans détruire les sources. Il crée un vrai description du montage dont un aperçu du rendu est affiché pendant l’édition. Un mode rendu en tâche de fond existe et permet de réaliser le véritable rendu en tâche de fond afin que l’aperçu soit une version réaliste du rendu final. Exemple de vidéo montée avec Cinelerra:

Les exemples de réalisation n’ont pas vocation à montrer l’état de l’art de ce que l’on peut obtenir avec ces logiciels mais montrent que sans expérience préalable, ni talent artistique particulier on peut réaliser des documents (dessin, animation, vidéos) de qualité acceptable en utilisant uniquement du Logiciel Libre.