Backup par mail

Le pipe (|), opérateur exclusivement Unix, et trop rarement utilisé (tout du moins par moi), m’a permis de réaliser en une seule ligne, une sauvegarde de base de données, compressée, et envoyé par mail.

Voyons la commande finale :

mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2 | mail -s "Backup BDD" storage_mail@gmail.com

Détaillons cette chaîne :

  1. on dump la ou les bases de données, pour se faire, je conseille fortement l’utilisation d’un utilisateur dédié qui n’aura qu’un accès limité à la lecture et éventuellement à l’utilisation des verrous pour assurer l’intégrité de la sauvegarde
  2. le flux de sortie, un script SQL, est envoyé à bzip pour être compressé
  3. le flux compressé est envoyé à uuencode. Cette opération va encoder avec des caractères ASCII afin d’être pouvoir transmis en pièce jointe et en lui donnant un nom
  4. enfin on expédie le mail avec un sujet et un destinataire

Et si on chiffrait la sauvegarde ?

Il y a plusieurs intérêt à chiffrer la sauvegarde :

  • la sauvegarde peut être placé dans un endroit non sécurisé ou faiblement
  • toute altération sur la sauvegarde sera impossible ou visible

Encore faut-il s’y prendre convenablement. En effet, on a immédiatement 2 façons naïves de chiffrer :

  • soit en utilisant un chiffrage symétrique
  • soit en utilisant un chiffrage asymétrique

Il se trouve que ces deux approches sont après coup débiles. En effet prenons d’abord le chiffrage symétrique ; que se passe-t-il si le serveur qu’on sauvegarde est compromis ? On peut estimer que le contenu des sauvegardes, y compris celles faites AVANT le piratage du serveur ne sont plus sûres, puisque le serveur compromis a non seulement un accès en écriture au site de sauvegarde, mais également la clé de déchiffrage des sauvegardes.

Examinons maintenant le chiffrage asymétrique, qui corrige bien le problème précédent mais présente deux problèmes :

  • le premier est un problème purement pratique : openssl, le couteau suisse du chiffrage pète en rsa lorsque le flux dépasse une certaine taille (très inférieure à 1Mo)
  • le second est d’ordre plus général : les chiffrages asymétriques coûtent très cher en temps processeur (autrement dit un chiffrage asymétrique prendre beaucoup plus de temps qu’un chiffrage symétrique sur le même flux), pour peu que la quantité de données soit « assez » conséquente, le chiffrage pourrait dégrader de façon significative et pendant un temps estimé trop long le serveur sur lequel les calculs s’effectuent.

La méthode que je qualifierais de bonne, (merci à Denis Altudov pour l’astuce), consiste à utiliser se qui se fait déjà dans les mails avec S/MIME : le contenu à protéger est chiffré avec un algorithme symétrique, dont la clé, générée à la demande et donc unique, est chiffrée par un algorithme asymétrique en utilisant la clé privée du destinataire ; ainsi seul le destinataire du mail est capable de lire le contenu protégé.

C’est exactement ce qu’on va faire, en utilisant openssl, et plus spécifiquement la sous-commande smime de openssl.
Il faudra au préalable un certificat (avec sa clé privée), au format PEM pour simplifier l’exemple. Reprenons l’exemple initial en ajoutant du chiffrage :

mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl | mail -s "Backup BDD" storage_mail@gmail.com

# version openssl smime autonome (ou presque)
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -from sender@kveer.com -to storage_mail@gmail.com -subject "Bacup BDD" yourPrivateKey.crt | sendmail storage_mail@gmail.com

Note : openssl smime est capable de générer un mail lui-même comme on peut le voir dans la seconde commande, mais cela aurait donné un mail avec une pièce jointe nommée smime.p7m, ce qui n’est pas terrible pour identifier ce qui était chiffré, en particulier le type de fichier, c’est pourquoi j’ai préféré rester à utiliser uuencode.

Et voilà, plus besoin d’un script dédié pour des plans de sauvegarde simple, il n’y a plus qu’à cronifier.

Déchiffrage

Par rapport à l’exemple donné, voici la commande miroir pour déchiffrer les pièces jointes :

openssl smime -decrypt -binary -aes128 -inform DER yourPrivateKey.crt -in your_encrypted_file.sql.bz2.ssl -out your_decrypted_file.sql.bz2

Les arguments -aes128  et -binary  sont peut-être superflus, je n’ai pas testé précisément ces points là.

Plusieurs pièces jointes dans un mail

Toujours avec le même exemple, voici comment on peut joindre plusieurs pièces jointes, et même un corps de message à son mail :

(
echo -e $YOUR_MESSAGE;
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl;
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B another_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_another_base_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl
)
| mail -s "Backup BDD" storage_mail@gmail.com

Où sauvegarder

Où vous le souhaitez. Pour ma part, j’ai choisi Google, car il propose 8Go par boîte mail gratuitement et accepte des pièces jointes allant jusqu’à 25Mo et parce que je suis pauvre. Pour une sauvegarde à pas chère, les mails via Google constituent une excellente opportunité.

Les paquets à installer

  • uuencode se trouve dans le paquet app-arch/sharutils
  • mail se trouve dans le paquet mail-client/mailx

Exemple de script

A peu de chose près, voici ce que j’utilise comme script de sauvegarde. Ce script se trouve dans @@/etc/cron.daily@@, ce qui lui permet d’être automatiquement exécuté avec les bons privilèges tous les jours.

#!/bin/bash
MYSQL_PASS=verySecretPassword
MYSQL_USER=backup_user
DATE=`date +%Y%m%d-%H%M%S`
HOSTNAME=`hostname`
RECIPIENT=backup@gmail.com
CERT=/root/backup.gmail.com.crt
WWW_WEB1='/var/www/web1/htdocs/ /var/www/web1/reset_acl.sh'
WWW_WEB2=/var/www/web2/htdocs
WWW_WEB3='/var/www/web3/forum /var/www/web3/www'

MYSQL_CMD="mysqldump --hex-blob --opt -u ${MYSQL_USER} -p${MYSQL_PASS} -B"
OPENSSL_CMD="openssl smime -encrypt -binary -aes128 -outform DER $CERT"

CONF='/etc/bash/bashrc
/etc/ahbot.conf
/etc/bind
/etc/clam*.conf
/etc/conf.d
/etc/courier*
/etc/cron*
/etc/dhcp
/etc/env.d
/etc/fail2ban
/etc/freshclam.conf
/etc/group
/etc/passwd
/etc/shadow
/etc/hosts
/etc/init.d
/etc/ipsec*
/etc/kernels
/etc/layman
/etc/locale.gen
/etc/make.conf
/etc/munin
/etc/mysql
/etc/nginx
/etc/ntp.conf
/etc/opendkim
/etc/openvpn
/etc/pam.d
/etc/php
/etc/postfix
/etc/pureftpd.*
/etc/realmd.conf
/etc/revdep-rebuild
/etc/screenrc
/etc/scriptdev2.conf
/etc/security
/etc/selinux
/etc/sysctl.conf
/etc/syslog-ng
/etc/teamspeak3-server
/etc/unrealircd'

T=$( cat <<EOF
Type your texte here\n
with \n if you want your mail to be readable.
EOF
)

( echo -e $T;
uuencode $CERT my_cert.crt;
$MYSQL_CMD base1 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base1_${DATE}.sql.bz2.ssl;
$MYSQL_CMD base2 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base2_${DATE}.sql.bz2.ssl;
$MYSQL_CMD base3 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base3_${DATE}.sql.bz2.ssl;
tar cj ${WWW_WEB1} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web1_${DATE}.tar.bz2.ssl;
tar cj ${WWW_WEB2} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web2_${DATE}.tar.bz2.ssl;
tar cj ${WWW_WEB3} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web3_${DATE}.tar.bz2.ssl;
tar cj ${CONF} | $OPENSSL_CMD | uuencode ${HOSTNAME}_etc_${DATE}.tar.bz2.ssl
) | mail -s "Backup $HOSTNAME bdd $DATE" $RECIPIENT

Voir aussi

SElinux et cron utilisateurs

Depuis que je suis passé à SELinux sur une Gentoo, beaucoup de problèmes sont apparus. Afin d’avoir un système un minimum utilisable, j’ai passé SELinux en mode permissive, malgré tout, cela ne résout pas tout, notamment des crons utilisateurs qui ne se lancent plus.

Précisons tout d’abord que mon système de cron est vixie-cron, qui semble être le daemon préféré sous Gentoo.

J’ai eu très peu d’informations au début lorsque j’ai voulu trouver pourquoi les crons ne se lançaient plus, que ce soit dans /var/log/kern.log où se trouve les logs de SELinux, ou dans /var/log/syslog. Je savais que ça provenait de SELinux puisque côté ACL, tout était nickel, et puis ça marchait très bien avant. La seule trace concrète du problème apparaît lorsqu’on redémarre le daemon vixie ; on peut lire ceci dans les logs :

root@stormrage:[~]
# zgrep ENTRYPOINT /var/log/syslog-20120318.gz
Mar 17 20:42:01 stormrage cron[2943]: (munin) ENTRYPOINT FAILED (crontabs/munin)
Mar 17 20:42:01 stormrage cron[2943]: (anakin) ENTRYPOINT FAILED (crontabs/anakin)

 

Voyons les permissions SELinux sur les user-crons :

root@stormrage:[~]
# ls -lZ /var/spool/cron/crontabs/
total 12
-rw-------. 1 anakin crontab anakin:object_r:user_cron_spool_t 274 6 nov. 13:54 anakin
-rw-------. 1 munin crontab munin:object_r:user_cron_spool_t 1180 9 janv. 17:31 munin
-rw-------. 1 root crontab root:object_r:user_cron_spool_t 657 17 mars 20:41 root

 

Je suis encore relativement novice à SELinux, mais il est clair que munin et anakin ne sont pas relié explicitement à un utilisateur SELinux, du moins il faut que ce soit une action volontaire. Ainsi, en obtenant la liste des contextes valides pour l’utilisateur Linux munin depuis le contexte dans lequel le daemon s’exécute (voir la commande ci-dessous), on a un seul résultat, qui ne correspond pas au contexte actuel sur les user crontabs.

root@stormrage:[~]
# ps -AfZ | grep cron
system_u:system_r:crond_t root 2521 1 0 Mar17 ? 00:00:00 /usr/sbin/cron
root@stormrage:[~]
# getseuser munin system_u:system_r:crond_t
seuser: user_u, level (null)
Context 0 user_u:user_r:cronjob_t

D’où un chcon -u user_u  sur tous les user crontabs et le tour est joué.

root@stormrage:[~]
# ls -lZ /var/spool/cron/crontabs/
total 12
-rw-------. 1 anakin crontab user_u:object_r:user_cron_spool_t 274 6 nov. 13:54 anakin
-rw-------. 1 munin crontab user_u:object_r:user_cron_spool_t 1180 9 janv. 17:31 munin
-rw-------. 1 root crontab root:object_r:user_cron_spool_t 657 17 mars 20:41 root

Je ne sais pas si user_u est le bon utilisateur SELinux à appliquer, en terme de sécurité, mais au moins les crons se lancent à nouveau.

On notera cependant que restaurer les contextes par défaut avec restorecon ou rlpkg ré-appliquent des contextes invalides. De même, éditer depuis root les crontabs d’autres utilisateur avec un crontab -e  applique un mauvais contexte, il semble préférable de passer par un su/sudo au préalable.
Il faudra donc penser à vérifier spécifiquement les contextes sur ces fichiers à chaque fois que le système de fichier est relabelisé.

Au final, je reste persuadé que SELinux est une bonne technologie mais elle n’est pas prêt à l’emploi (cela vaut également pour Red Hat), même en partant avec une stratégie de base comme celle fournie par Tresys. A moins de faire un serveur très bâteau, il sera certain qu’il faudra auditer et réajuster la stratégie SELinux avant de la valider pour une production.

Voir aussi

Construction d’une chaîne de compilation pour Android

Il existe plusieurs méthodes pour avoir une chaîne de compilation pour le système Android. Mais pourquoi une toolchain ? Android est un système d’exploitation basé sur le noyau Linux et dédié aux processeurs de type ARM (actuellement, c’est le cas). Il ne s’agit donc pas de processeurs « classiques » de type x86 ou ia64, et par conséquent, les chaînes de compilation fournies avec les distributions Linux ne sont pas adaptées, car elles ne peuvent générer que du code x86 ou ia64…

Avertissement : Pour l’instant, j’ai réussi à compiler un kernel qui boot, mais j’ai perdu la radio, j’ai seulement le wifi.
Cet article est donc présent surtout à des fins théoriques ou pour les plus persévérant à commencer les bidouilles de bas niveau :p.

Quelques chaînes de compilation pour architecture arm

  • Gentoo, avec son paquet crossdev. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation pré-compilé fourni par le SDK d’Android. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation fournie par crosstool-ng. La plus configurable, la plus chiante à mettre en place, mais la seule qui a marché.

Il est possible que les autres chaînes de compilation marchent parfaitement bien, j’ai juste du louper un truc sur les paramètres à passer… c’est dire que contrairement au monde x86, des architectures ARM, il y en a à la pelle et pas souvent compatibles entre elles (pas sans recompilation).

Cette article détaillera uniquement la dernière chaîne de compilation, qui a l’avantage d’avoir beaucoup de paramètres que l’on peut utiliser pour optimiser sa chaîne.

Les étapes décrites ci-dessous s’appliquent à Gentoo, mais peuvent s’appliquer à n’importe quel UNIX-like avec quelques modifications mineures.

# si ce n'est pas déjà fait, on installe git
emerge -v git

# récupération du kernel cyanogen
export KERNELDIR=/home/kernel-cyanogen
export CROSSTOOLDIR=/home/crosstool-ng
mkdir -p $KERNELDIR
cd $KERNELDIR
#git clone git://github.com/CyanogenMod/cm-kernel.git
# pour certains appareils htc dont le vision, un autre repo est utilisé
git clone git://github.com/CyanogenMod/htc-kernel-msm7x30.git
# aller boire un café, ça va prendre 10bonnes minutes...
#cd cm-kernel
cd htc-kernel-msm7x30
make headers_install ARCH=arm INSTALL_HDR_PATH=../kern_h/

# construction de la toolchain
echo 'sys-devel/ct-ng' >> /etc/portage/package.keywords
emerge -va ct-ng
eselect bashcomp enable ct-ng --global
mkdir -p $CROSSTOOLDIR
cd $CROSSTOOLDIR
# placez le fichier uClibc.config ici, depuis l'archive à télécharger
#mv XVilka-uClibc-msm7200a.config uClibc.config
ct-ng menuconfig

Ci-dessous les changements à effectuer pour le menuconfig de crosstool-ng

Paths and misc options --->
(1) Number of parallel jobs
Target options --->
Target Architecture (arm)
(armv7-a) Architecture level
(cortex-a8) Emit assembly for CPU
(vfpv3) Use specific FPU
(-O2) Target CFLAGS
Toolchain options --->
(android) Tuple's vendor string
Operating System --->
Target OS (linux)
Linux kernel version (2.6.37.6) // à adapter en fonction de la version du kernel du cyanogenmod
C compiler --->
[*] C++
[*] Java
C-library --->
C library (uClibc)
(uClibc.config) Configuration file
Threading implementation to use: (linuxthreads)

Et on retourne à la ligne de commande…

ct-ng build
# là on reprend une tasse de café

# récupération des sources du cyanogenmod
export CYANODIR=/home/cyanogen
cd $CYANODIR
repo sync
make adb
export PATH=/out/host/linux-x86/bin:$PATH

# compilation d'un nouveau kernel
export _XXCFLAGS=" -march=armv7-a -mtune=cortex-a8 -mfpu-abi=softfp -mfpu=vfpv3 -O2"
export PATH=~/x-tools/arm-android-linux-uclibcgnueabi/bin:$PATH
export CCOMPILER=~/x-tools/arm-android-linux-uclibcgnueabi/bin/arm-android-linux-uclibcgnueabi-
cd $KERNELDIR/htc-kernel-msm7x30
# branchez le téléphone au pc
adb pull /proc/config.gz .
zcat config.gz > .config
# menuconfig pour changer deux ou trois choses avant de compiler (à faire avec beaucoup de précautions)
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER menuconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER oldconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER -j`grep 'processor' /proc/cpuinfo | wc -l` all
cd $CYANODIR/device/htc/vision
mv kernel kernel.bak
mv modules/bcm4329.ko modules/bcm4329.ko.bak
ln -s $KERNELDIR/htc-kernel-msm7x30/arch/arm/boot/zImage kernel
ln -s $KERNELDIR/htc-kernel-msm7x30/drivers/net/wireless/bcm4329/bcm4329.ko modules/
cd $CYANODIR
. build/envsetup.sh && brunch cyanogen_vision-eng

Et voilà, plus qu’à flasher.

Tous les crédits vont à XVilka, pour avoir décrit sa méthode pour le milestone.

Voir aussi

Configuration robuste d’un serveur SSL

En visitant le site cacert.org, notamment pour voir où en était leur intégration dans les différents systèmes d’exploitation et navigateurs, je suis tombé sur Qualys SSL Server Test un site permettant de scanner la partie SSL d’un site web.

Je passe le test pour mon blog, on va voir ce que ça donne…
Pour note, mon blog est desservi par nginx, lui-même linké à openssl pour tous se qui se rapport au chiffrage.
C’est long… et surprise, je décroche un F ! Bravo, je ne peux pas faire pire !

Analysons le résultat :

  • tout d’abord, mon certificat est trusted, mais il semble qu’il y ait un problème sur la chaîne de certification. Une petite vérification m’a permis de confirmer qu’effectivement le serveur ne contient que le certificat du site et le certificat racine, en oubliant le certificat intermédiaire (chaîne de 3 certificats). Qu’à cela ne tienne, une petite concaténation m’a permis de corriger ce soucis. Le problème que ça aurait pu engendrer est qu’un navigateur qui n’a jamais visité un site certifié par Start SSL (qui est l’entité émettrice de mon certificat) aurait jugé que le certificat n’est pas valide, puisqu’il n’arrive pas à remonter de mon certificat à un des certificats racines du navigateur, vu qu’il lui manque le fameux certificat intermédiaire que je n’ai pas présenté.
  • second problème, j’ai des algorithmes de chiffrages qui sont considéré insecure. oups ? J’avais pourtant bien restreint les algorithmes à HIGH:-DES pourtant ! Il se trouve après avoir trouvé le dénominateur commun aux algorithmes non secure que le coupable est anonymous DH, ou bien ADH. Je change donc dans nginx la liste des algorithmes autorisés à HIGH:-DES:ADH  et je repasse le test… avec succès 🙂 Dans les sources, j’ai pu trouver un lien expliquant de façon succincte pourquoi cette famille d’algorithmes n’est pas sûre : du fait que le Diffie-Hellman est effectué en clair (anonymous), l’échange de clé reste secret (cela est assuré par le procédé Diffie-Hellman), mais n’empêche pas une attaque du milieu, à savoir un agent positionné entre deux participants et qui intercepterait les échanges des deux participant pour proposer ses propres paramètres Diffie-Hellman ; le procédé Diffie-Hellman a été bien réalisé… mais pas avec la bonne personne !
  • dernier problème, mineur celui-là, l’incapacité à renégocier une session chiffrée. Une petite ligne de configuration à rajouter, plus difficile à trouver cependant. Corrigé, je repasse le test, et cette fois, tout est vert, j’ai un A 🙂

Pour résumer, voici à quoi ressemble la configuration SSL dans le fichier de configuration de nginx :

ssl_ciphers HIGH:-DES:-ADH;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 SSLv3;
ssl_session_cache shared:SSL:1m;

Pour comparer, j’ai balancé le test sur un serveur sous Windows Server 2003, et un autre sous Windows Server 2008 R2, tous deux avec les configurations par défaut.
L’un est catastrophique, l’autre est parfait, plus parfait même que mon nginx tuné, notamment par le support du protocol TLS 1.2.
Il est dommage toutefois de constater le faible choix disponible dans la liste des algorithmes proposés sous Windows Server 2003.
Je vais essayer de désactiver SSLv2 sous Windows Server 2003 et voir ce que cela donne…

Bien que les notes fournies par Qualys puissent paraître sévères en rapport avec le monde réel (qui utilise encore ADH parmi les navigateurs modernes ?), reconfigurer proprement la partie ssl d’un serveur ne mange pas de pain (mis à part le cas IIS où la configuration est on ne peut plus restreinte), alors go on !

Voir aussi

Compiz et pas de barre de titre

Dans le cas où les barres de titre des applications ont disparues, désactivez le plus de choses dans Compiz, à part le déplacement et le redimensionnement des fenêtres. Ensuite changez le gestionnaire de thèmes via Compiz-fusion icon (ou via compiz directement si vous connaissez la commande) et activez le plug-in décorations des fenêtres. Ensuite rechargez compiz avec compiz-fusion icon.

ATI Radeon Mobility x1600

Au bout de 8 mois d’acharnement, enfin, j’ai réussi à faire fonctionner correctement le serveur X avec une carte graphique ATI Radeon Mobility X1600 et l’accélération graphique !! Tout ça parce que ATI est incapable de faire un tuto correct. Ceci est un compléments aux tutoriels que j’ai référencé dans la section Voir aussi.

L’installation des pilotes ATI requiert gcc 3.3. Chez moi ça ne compile pas, mais ce n’est pas grave, émergez au préalable le paquet libstdc++v3, cela va compiler les librairies de gcc 3.3, et cela sans plantage.
En ce qui concerne le noyau, il doit supporter le System V IPC et VM86.
Afin de bénéficier des dernières nouveautés ATI, ajoutez le paquets x11-drivers/ati-drivers ~x86 dans la liste des keywords, afin de démasquer les paquets encore marqués instables.
Normalement le reste devrait maintenant fonctionner.

Voir aussi

Pingouin malade demande docteur

Suite à un crash de mon portable (disque illisible), j’ai dû me farcir une grosse réinstallation. J’en profite donc pour refaire un Gentoo en environnement virtualisé en utilisant l’hyperviseur VMWare Workstation 6. Comme je travaille sur un PC portable aux ressources très limitées et que je suis assez gourmand en nombres d’applications ouvertes, j’alloue arbitrairement 256Mo de mémoire vive à ma bête polaire. Quelle erreur ! Lors de certaines compilations, j’obtient des crashs du compilateur g++ sans aucune raison particulière. C’est d’autant plus étrange sachant que ce n’est pas ma première installation de Gentoo, c’est la première fois que je vois ce phénomène. Je remarque également des freezes : les programmes ne font plus rien pendant un certains temps avant de reprendre leurs tâches. J’ai au début pensé à une erreur des options de compilation du noyau, mais en regardant les ressources systèmes avec la commande ‘htop’, je vis qu’il me restait 5Mo de mémoire vive, sachant que je n’ai pas de swap. En augmentant la mémoire vive allouée à la machine virtuelle, je redémarre, je compile et tout se passe bien.

Conclusion, ne soyez pas trop radin avec Linux sur la RAM, sous peine de comportement très aléatoire. On pourra d’ailleurs remarquer qu’en idle, mon nux ne me laisse pas beaucoup de mémoire vive, alors qu’il n’y a rien qui tourne à par le daemon ssh. Il faut que je jette un coup d’oeil dessus.