Racine en lecture seule

Dans l’article sur la mise en place d’un système sur deux clés USB interdépendantes, il était question de faire tourner le système sur une clé en lecture seule. Il faut notamment que la racine soit sur cette clé, mais potentiellement une grande partie du système pour que cela soit intéressant.

C’est aussi un intérêt pour la durée de vie de la clé supportant le système. La technologie des mémoires FLASH dans les clés USB ne supporte pas énormément de cycles d’écriture. Ainsi, empêcher l’écriture revient à réduire considérablement ce risque de panne.

Il y a plusieurs façons de réaliser l’opération :

  1. Partitionner le système de façon à avoir certaines parties en lecture seule (/, /boot, /bin, /usr, /lib, /sbin) et d’autres en lecture/écriture (/home, /var, /tmp, etc…). CF https://wiki.debian.org/ReadonlyRoot .
  2. Utiliser une surcouche au système de fichier pour que celui-ci soit comme si il était en lecture/écriture, mais en fait rien n’est jamais écrit sur le disque. Toute modification reste en mémoire vive et est ainsi perdu au redémarrage. Il faut cependant faire attention dans notre exemple à l’occupation de la mémoire qui va inévitablement grossir avec le temps d’utilisation. CF http://lwn.net/Articles/327738/ .
  3. Faire en sorte que les programmes qui écrivent sur le disque soit n’ai plus besoin de le faire, soit qu’ils soient arrêtés ou désinstallés. Cela veut dire que certains programmes seront inutilisables parce qu’ils nécessitent pour leur fonctionnement d’écrire (compulsivement).

Il peut y avoir un problème avec les mots de passes à gérer. Il est possible de gérer plusieurs partitions chiffrées sans avoir autant de mot de passe à taper qu’il y a de partitions. Une méthode, que je n’ai pas essayé, est de dire à cryptsetup que le mot de passe est commun à plusieurs partitions. Une autre méthode est d’utiliser des des mots de passes dans des fichiers (voir un seul) et finalement de ne plus avoir qu’un mot de passe à saisir, celui de la partition qui contient les fichiers de mots de passes. Et enfin, on peut utiliser LVM par dessus une seule partition chiffrée, et sous-partitionner grâce à LVM. Cette dernière solution marche bien et est réalisable dès l’installation du système (au moins sous Debian et Ubuntu alternate).

Mise en pratique

On va ici faire un mixe de la surcouche du système de fichier pour certains dossiers spécifiques et la désactivation des processus ou de leur méthode de journalisation.

/var/log

On va rendre le dossier /var/log modifiable, mais tout sera détourné vers /tmp/log. La base des fichiers qui se trouvent réellement dans /var/log sera bien en lecture seule.

Il faut ajouter au cours du processus de démarrage :

mkdir /tmp/log
mount -t aufs -o br:/tmp/log:/var/log=ro none /var/log

Le script au démarrage doit être placé avant qu’un démon ne soit lancé et n’utilise le dossier /var/log, et après le montage et nettoyage de /tmp.

Démon rsyslog

A-t-on besoin de garder les journaux ?
Si oui, alors ils vont arriver dans /tmp/log.
Si non, il suffit de désactiver rsyslog.

Serveur Xorg

Au lancement du serveur graphique X, celui-ci ouvre un fichier de journalisation /var/log/Xorg.0.log.

Gestionnaire de connexion GDM

GDM utilise un dossier pour différentes choses. Il est préférable de monter ce dossier en mémoire. On va garder le dossier utilisé par défaut mais le réutiliser à chaque démarrage sans le modifier. Puis on va mettre en place un script au démarrage pour initialiser ce dossier en mémoire et avec un contenu adéquat.

Commencer par arrêter GDM = revenir en console texte. Ce peut être fait avec :

service gdm3 stop

Ensuite, on renomme le dossier /var/lib/gdm3 en gdm3.init :

mv /var/lib/gdm3 /var/lib/gdm3.init

Créer le fichier de script /etc/init.d/mounttmpfs.sh :

#!/bin/sh
### BEGIN INIT INFO
# Provides:          mounttmpfs
# Required-Start:    mountall-bootclean
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Mount tmpfs filesystems.
# Description:
### END INIT INFO
[ ! -d /var/lib/gdm3 ] && mkdir -p /var/lib/gdm3
mount -n -t tmpfs -o size=1M none /var/lib/gdm3
cp -rp /var/lib/gdm3.init/* /var/lib/gdm3/
cp -rp /var/lib/gdm3.init/.[cdfp]* /var/lib/gdm3/
chmod Debian-gdm.Debian-gdm /var/lib/gdm3

Le rendre exécutable et l’activer :

chmod 755 /etc/init.d/mounttmpfs.sh
update-rc.d

Vérifier au redémarrage que dossier a bien été remplit. Le montage avec l’option -n fait que ce n’est pas écrit dans /etc/fstab… puisque l’on veut éviter les écritures inutiles pour rendre le tout en lecture seule. Mais on peut vérifier avec la commande mount que le montage a marché.

Et après ?

On peut continuer comme ça si on a d’autres programmes qui posent problème. On peut mixer différentes méthodes et utiliser le script de démarrage pour faire à la fois des montages en tmpfs et/ou aufs