Tag - linux

Entries feed

Monday, March 10 2014

Logrotate et OpenVPN

Logrotate est un outil fort pratique pour l'administrateur qui souhaite nettoyer automatiquement et périodiquement son dossier /var/log (on en parlait déjà ici et ici).

D'autre part, OpenVPN est un couple client/serveur performant pour la mise en place de réseaux privés virtuels. L'administrateur attentionné aimera que le serveur OpenVPN tienne à jour un flux de logs détaillés... mais avec de nombreux utilisateurs du VPN, les logs peuvent alors rapidement atteindre une taille très importante ! Logrorate est bien sûr la solution.

J'ai cependant eu quelques difficultés à trouver des options qui permettent à OpenVPN et Logrotate de fonctionner en bonne harmonie - je vous présente donc ci-dessous les paramétrages fonctionnels chez moi pour vous épargner (en tout cas je le souhaite) mes longs tâtonnements.

Dans la configuration d'OpenVPN, on a :

user openvpn
group openvpn
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log

Comme on peut le voir ci-dessus, je regroupe mes logs dans un même dossier et les logs sont écrits avec les droits d'exécution du serveur OpenVPN, à savoir l'utilisateur openvpn. log-append précise le fichier dans lequel les logs doivent être déposés.

Pour logrotate, dans /etc/logrotate/openvpn.conf, on a :

/var/log/openvpn/openvpn.log
{
    weekly
    rotate 52
    missingok
    notifempty
    delaycompress
    compress
    copytruncate
    postrotate
        /etc/init.d/openvpn restart
    endscript
}

J'espère que ces paramétrages permettront aussi chez vous l'harmonie entre OpenVPN et Logrotate !

Tuesday, February 25 2014

Optimiser les accès à un SSD sous Linux

Cet article est une copie à peu de chose près de l'article trouvé ici : http://p3ter.fr/article53/optimiser-son-ssd-sous-linux. Il est dupliqué ici pour mémoire !

Ajout de noatime dans /etc/fstab

L'option noatime permet de ne pas écrire sur le disque, la date du dernier accès en lecture lorsqu'il n'y a pas d'écriture. Éditez le fichier /etc/fstab avec des droits root, et ajoutez noatime sur les lignes correspondantes aux partitions ext4 de votre SSD.

UUID=xxxxxxxxxxxxxxx    /    ext4    noatime,errors=remount-ro 0       1

Placer /tmp dans la RAM

Plutôt que d'écrire sur le SSD les fichiers temporaires, on peut les placer dans la mémoire vive. Attention il faut prévoir au moins 1 Go de RAM qui sera dédié à /tmp. Éditez le fichier /etc/fstab avec des droits root et ajoutez la ligne ci-dessous :

tmpfs      /tmp            tmpfs        defaults,size=1g

Utiliser la swap en dernier recours

Toujours dans le but de réduire les écritures sur le SSD, on peut obliger le système à utiliser la partition swap uniquement quand la RAM est pleine. Pour ce faire, ajoutons cette ligne dans /etc/sysctl.conf :

vm.swappiness=20

La valeur doit être comprise entre 0 et 100 : à 0, le système ne placera du contenu en swap que lorsque la RAM sera totalement pleine ; à 100, le système swappera immédiatement. La valeur par défaut semble être de 60. Le bon niveau de swappiness peut être un long sujet à débats !

Activer le TRIM

Le TRIM est une technologie qui permet d'améliorer les performances de votre SSD. Elle est supportée sur la grande majorité des SSD. Pour vérifier si le vôtre est compatible :

hdparm -I /dev/sda | grep TRIM

Si le TRIM n'est pas activé par défaut sur votre système, éditez le fichier /etc/fstab et ajoutez discard dans les options.

UUID=xxxxxxxxxxxxxxx  /               ext4    noatime,discard,errors=remount-ro 0       1

Saturday, February 8 2014

Gedit crashe lors de la fermeture d'un onglet

Gedit m'a fait un coup pendable hier matin : il ferma à plusieurs reprises sans prévenir alors que j'avais plusieurs onglets ouverts. Une fois lancé depuis la console, je constatais ce message d'erreur :

TypeError: Couldn't find conversion for foreign struct 'cairo.Context'
Exception TypeError: "Couldn't find conversion for foreign struct
'cairo.Context'" in 'garbage collection' ignored Fatal Python error:
unexpected exception during garbage collection

Pour corriger ce gênant dysfonctionnement, j'installai le paquet python3-gi-cairo :

aptitude install python3-gi-cairo

En espérant que cela pourra dépanner certains et les sauver de ce crash gênant !

Saturday, February 1 2014

Echec à l'installation du gem rmagick

Souhaitant utiliser le gem 'rmagick', je lance la commande classique :

18:22 pab@risotto /home/pab % gem install rmagick

mais suis récompensé par :

Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
	ERROR: Failed to build gem native extension.

    /home/pab/.rvm/rubies/ruby-2.1.0/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 2.13.2. Can't find Magick-config

Après quelques recherches, je découvre qu'il faut préalablement installer libmagickwand-dev - ce que j'exécute sous Debian par la commande :

aptitude install libmagickwand-dev

Dé-zipper : erreur "need PK compat. v5.1 (can do v4.6)"

Il semble que l'utilitaire unzip en version 6.0 dans Debian (au moment de l'écriture de ce billet) ne parvienne plus à dé-compresser des archives sécurisées...

UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.
Archive:  dump.sql.zip
   skipping: dump.sql                need PK compat. v5.1 (can do v4.6)

Je ne suis pas parvenu à rendre cette fonctionnalité à unzip et me suis donc rabattu sur le 7zip, également disponible dans les dépôts Debian :

aptitude install p7zip-full
7z e mon-fichier.zip

7z, lui, fonctionne pour extraire (paramètre "e") le contenu d'une archive sécurisée.

Sunday, January 26 2014

SMTP Postfix en accord avec les RFC mais n'acceptant pas les utilisateurs s'authentifiant en clair

Quand on met à disposition un serveur SMTP à des utilisateurs, on aimerait s'assurer qu'ils ne communiquent pas leur mot de passe clair. Une solution consiste à interdire tout accès au SMTP sans SSL/TLS :

smtpd_tls_security_level = encrypt

mais cette option n'est pas compatible avec les RFC car alors tous les SMTPs doivent se connecter au vôtre avec SSL/TLS.

Il existe donc une autre possibilité plus élégante :

smtpd_tls_security_level = may
smtpd_tls_auth_only = yes

'' smtpd_tls_security_level = may'' autorise l'accès au serveur sans encryption (même si l'encryption est utilisée prioritairement si possible) tandis que "smtpd_tls_auth_only = yes" n'autorise les actions d'authentification (donc d'échange de mot de passe) que lorsque la connexion passe par un canal crypté.

Voilà qui répond au problème tout en respectant les RFC !

Thursday, January 23 2014

Updatengine : retrouver un mot de passe perdu !

Vous utilisez Updatengine couramment, et un matin, c'est le trou de mémoire, impossible de vous souvenir du mot de passe que vous utilisez pour vous connecter. Pas de panique, nous allons voir ci-dessous comment ré-initialiser le mot de passe administrateur d'Updatengine ! En revanche, on ne pourra rien faire pour votre amour propre !

Updatengine est basé sur Django et son système d'authentification. Il est donc possible de se tourner vers les fonctions classiques de Django pour réinitialiser le mot de passe :

python manage.py changepassword username

Si vous avez suivi les instructions d'installation classique d'Updatengine, alors cette commande devrait faire l'affaire :

/var/www/UE-environment/bin/python /var/www/UE-environment/updatengine-server/manage.py changepassword admin

en prenant bien sûr le soin de remplacer 'admin' par le nom d'utilisateur que vous avez paramétré lors de l'installation.

Sunday, November 10 2013

Installation et paramétrage d'un serveur avec conteneurs LXC chez Online.net/Dedibox

Nous allons décrire ici l'installation et la paramétrage d'un serveur dédié chez Online.net (offres Dedibox). La description de l'installation ne sera peut-être pas exhaustive et se concentrera sur les points clés, ceux qui par exemple ont été bloquants lors de notre déploiement.

Au niveau des technologies utilisées...

Nous allons déployer une version Debian stable (7.x à l'écriture de ces lignes) avec LVM2 (pour le découpage de l'espace disque) étant entendu que le RAID est géré matériellement et ne demande pas de paramétrage au niveau du système. La technologie LXC (LinuX Containers) sera utilisée pour séparer les servicse dans plusieurs conteneurs indépendants.

Pour le réseau, chaque conteneur disposera de sa propre IPv6 et sera donc accessible directement. En IPv4 en revanche, on déploiera un réseau local IPv4 avec un NAT pour répartir le trafic sur les différents conteneurs.

Paramétrage du réseau IPv6 chez Online.net

Chez Online.net, un bloc /48 est attribué avec chaque serveur dédié. Pour gérer l'IPv6 sur le serveur, il faudra installer le client Dibbler (un client DHCPv6) :

aptitude install dibbler-client

puis modifier la clé DUID dans le fichier /var/lib/dibbler/client-duid pour insérer celle attribuée par Online.net dans l'interface d'administration du système. Enfin, on modifiera le fichier de configuration /etc/dibbler/client.conf tel que suit :

log-level 7
iface br0 {
    pd
    option dns-server
    option domain
}

On modifie alors le fichier /etc/network/interfaces pour contenir les éléments suivants :

auto br0
iface br0 inet static
    address 88.123.123.123
    netmask 255.255.255.0
    gateway 88.123.123.1
    bridge_ports eth0

iface br0 inet6 static
    address 2001:abcd:abcd:abcd::
    gateway fe80::123:1234:1234:1234
    netmask 56

Vous aurez bien sûr pris le soin de remplacer 2001:abcd:abcd:abcd:: par l'adresse IPv6 correspondant au bloc /56 que vous avez décidé d'attribuer à votre serveur dédié et de spécifier la bonne passerelle (la passerelle par défaut est aussi l'adresse du routeur auquel est connecté votre Dedibox, vous pourrez trouver dans les logs de Dibbler l'adresse de ce routeur). Et remplacer 88.123.123.123 par l'adresse IPv4 qui vous a été attribuée (et spécifier la passerelle correspondante).

Ce paramétrage correspond à la mise en place d'un pont réseau (bridge) ce qui permettra à toutes les machines virtuelles de communiquer entre elles et de partager les communications réseau.

On redémarre alors le réseau :

/etc/init.d/networking restart

(si vous êtes connecté en SSH, il faudra peut-être se reconnecter en utiliser les nouvelles adresses spécifiées - pour forcer la connexion SSH en IPv6 il faudra utiliser ssh -6 et ssh -4 pour forcer l'IPv4)

puis on redémarre Dibbler par les commandes habituelles :

/etc/init.d/dibbler-client stop 
/etc/init.d/dibbler-client start

Une fois les conteneurs en place, nous reviendrons sur ce paramétrage pour y apporter quelques légères modifications.

Création de volumes virtuels avec LVM pour héberger les conteneurs

Chaque conteneur sera contenu dans un espace logique géré par LVM. Cela permettra notamment une manipulation aisée pour le redimensionnements, les sauvegardes...

Lors de l'installation initiale, nous avons donc pris le soin de garder une grosse partition /dev/sdaX non utilisée - c'est elle que nous allons déclarer comme volume physique pour LVM.

Il faut d'abord s'assurer que /dev/sdaX n'est pas mentionné dans /etc/fstab et le cas échéant commenter la ligne correspondante.

Puis on crée le volume physique :

pvcreate /dev/sdaX
vgcreate vg /dev/sdaX

et 2 volumes logiques de 50 Go :

lvcreate -n Nom1 -L 50g vg
lvcreate -n Nom2 -L 50g vg
mkfs.ext4 /dev/vf/Nom1
mkfs.ext4 /dev/vf/Nom2

Installation de LXC et déploiement du premier conteneur

aptitude install lxc lxc lxctl bridge-utils debootstrap unzip

installera les éléments nécessaires. Puis on modifiera /etc/fstab pour contenir :

cgroup        /sys/fs/cgroup        cgroup        defaults    0    0

La commande lxc-checkconfig permet de vérifier si tout est paré et donné des aides pour la résolution d'éventuels problèmes. Une fois que tous les paramètres de lxc-checkconfig sont au vert, on se lance pour de vrai !

A noter que le template Debian 7 inclus par défaut pour LXC dans Debian 7 est défectueux (cf. 'The Debian 7 template is broken' in [https://wiki.debian.org/LXC |https://wiki.debian.org/LXC] et la solution proposée ici par Rob van der Hoeven). Les lignes ci-dessous correspondent à la solution proposée par Rob.

On déploie un template fonctionnel :

cd /usr/share/lxc/templates/
wget http://freedomboxblog.nl/wp-content/uploads/lxc-debian-wheezy.gz
gzip -d lxc-debian-wheezy.gz
chmod u+x lxc-debian-wheezy

et on lance la création du premier conteneur :

lxc-create -n myfirstcontainer -t debian-wheezy

On déplace alors le conteneur dans le premier disque logique LVM que nous avions créé précédement :

cd /var/lib/lxc/
mv myfirstcontainer myfirstcontainer-tmp
mkdir myfirstcontainer
mount /dev/vg/Nom1 myfirstcontainer
cd myfirstcontainer-tmp
cp -R * ../myfirstcontainer/
cd ..
rm -Rf myfirstcontainer-tmp

et on paramètre le conteneur comme suit dans /var/lib/lxc/myfirstcontainer/config :

lxc.utsname = container1
lxc.network.type = veth
lxc.network.veth.pair = vethcontainer1
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.0.101/24  #on attribue une adresse IPv4 de réseau local
lxc.network.ipv4.gateway = 192.168.0.1  #la passerelle, nous allons attribuer cette adresse ensuite à l'hôte physique
lxc.network.hwaddr = 00:11:D0:14:84:BE  #attention, à modifer par une valeur aléatoire si vous installez plusieurs machines pour qu'il n'y ait pas collision !
lxc.network.ipv6 = 2001:abcd:abcd:abcd::101/56  #une adresse appartenant au bloc /56 attribué au serveur dédié

et on modifie les paramétrages réseau au sein du conteneur dans /var/lib/lxc/myfirstcontainer/rootfs/etc/network/interfaces :

auto eth0
iface eth0 inet static
    address 192.168.0.101

iface eth0 inet6 static
    address 2001:abcd:abcd:abcd::101
    netmask 56
    post-up ip -6 route add default via 2001:abcd:abcd:abcd::

Sur la machine hôte, on modifie alors les paramètres tel que suit :

  • on indique à Dibbler de ne pas chercher à paramétrer l'interface virtuelle vethcontainer1 en ajoutant dans la configuration de Dibbler :
iface vethcontainer1 no-config
  • on met en place le réseau IPv4 par :
ip addr add 192.168.0.1 dev br0
ip route add 192.168.0.0/16 dev br0
iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
  • on met en place le réseau IPv6 par :
ip -6 route add 2001:abcd:abcd:abcd::101 dev br0
  • on modifie les paramétrages réseau du système en modifiant /etc/sysctl.conf :
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.accept_ra = 2

et sysctl -p pour prendre en compte ces paramétrages.

Si la connectivité IPv6 disparaît, alors il faudra se reconnecter en IPv4 et lancer les commandes suivantes :

ip -6 route add aa:bb:cc:dd:ee::/64 dev br0
ip -6 route add default via aa:bb:cc:dd:ee::1 dev br0
/etc/init.d/dibbler-client stop
/etc/init.d/dibbler-client start

en remplaçant aa:bb:cc:dd:ee::1 par l'adresse de la passerelle IPv6 (cette adresse est normalement communiquée par les Router Advertisements).

Tout semble alors prêt pour le démarrage du conteneur !

Lancement du conteneur

lxc-start -d -n myfirstcontainer

et on peut alors s'y connecter en console via :

lxc-console -n myfirstcontainer

Par défaut, le mot de passe root est root (c'est le paramétrage par défaut du template que nous avons utilisé - il va de soi que nous allons rapidement modifier ce paramétrage).

Pour quitter la console LXC, il faudra faire Ctrl+a puis d.

Dans le conteneur, on pourra vérifier que :

  • ping 192.168.0.1 fonctionne (ping de la machine hôte physique)
  • ping 8.8.8.8 fonctionne (ping vers l'extérieur, le web)
  • ping -6 2001:abcd:abcd:abcd:: fonctionne (ping de la machine hôte physique en IPv6)
  • ping -6 2001:4860:4860::8888 fonctionne (ping vers le web en IPv6)

Si tout fonctionne comme attendu, on peut alors poursuivre l'installation du système. On pourra par exemple :

  • créer des conteneurs additionnels (en adaptant quelque peu le paramétrage réseau afférent)
  • paramétrer iptables et ip6tables sur l'hôte physique et les conteneurs pour protéger les systèmes et rediriger le trafic IPv4 sur les conteneurs
  • installer Pound comme reverse proxy pour diriger le trafic HTTP/HTTPS IPv4 vers les différents conteneurs sous-jacents

Exemple de configuration iptables sur l'hôte physique

#!/bin/bash
IPTABLES='/sbin/iptables';

CT1_HOST="192.168.0.101";
CT2_HOST="192.168.0.102";
MONITORING_ONLINE="88.190.254.18";
LAN="192.168.0.0/24";
WAN_IFACE="br0";
WAN_IP="88.123.123.123";
# Flushing tables
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F
# Define default policy
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT

$IPTABLES -A INPUT -j ACCEPT -d $LAN;
$IPTABLES -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED

# Temporary - SSH access open to all IPs on port 22 but Fail2ban is working.$
$IPTABLES -A INPUT -j ACCEPT -p tcp --dport 22
# Opens to ping from online monitoring
$IPTABLES -A INPUT -j ACCEPT -p icmp -s $MONITORING_ONLINE

# Accepts connection to ports 80 and 443
$IPTABLES -A INPUT -j ACCEPT -p tcp --dport 80
$IPTABLES -A INPUT -j ACCEPT -p tcp --dport 443

# Rediriger le port 123 vers le container 1
$IPTABLES -t nat -A PREROUTING -p tcp --dport 123 -d $WAN_IP -j DNAT --to-destination $CT2_HOST:123

# Rediriger un port 456 vers le container 2
$IPTABLES -t nat -A PREROUTING -p tcp --dport 456 -d $WAN_IP -j DNAT --to-destination $PAB2_HOST:456

# Activating masquerade FROM local network
$IPTABLES -t nat -A POSTROUTING -o $WAN_IFACE -s $LAN -j MASQUERADE

Exemple de configuration de pound sur l'hôte physique

User		"www-data"
Group		"www-data"
RootJail	"/chroot/pound"

## Logging: (goes to syslog by default)
##	0	no logging
##	1	normal
##	2	extended
##	3	Apache-style (common log format)
LogFacility local0
LogLevel 1

## check backend every X secs:
Alive		180

## use hardware-accelleration card supported by openssl(1):
#SSLEngine	"<hw>"

# poundctl control socket
Control "/var/run/pound/poundctl.socket"

ListenHTTP
	Address 88.123.123.123
	Port	80

	## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
	xHTTP		2

        #Les services à envoyer sur le premier conteneur
	Service
		HeadRequire "Host: .*(domaine1.fr|domaine2.fr|domaine3.fr).*"
		BackEnd
			Address	192.168.0.101
			Port	8080
		End
	End

        #Les services à envoyer sur le second conteneur
        Service
                HeadRequire "Host: .*(domaine4.fr|domaine5.fr).*"
                BackEnd
                        Address 192.168.0.102
                        Port    8080
                End
        End

End

ListenHTTPS
        Address 88.123.123.123
        Port    443
	Cert    "/path/to/certificate/pound.pem"

	HeadRemove "X-Forwarded-Proto"
        AddHeader "X-Forwarded-Proto: https"

        ## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
        xHTTP           2

        #Les services à envoyer sur le premier conteneur
	Service
		HeadRequire "Host: .*(domaine1.fr|domaine2.fr|domaine3.fr).*"
		BackEnd
			Address	192.168.0.101
			Port	8080
		End
	End

        #Les services à envoyer sur le second conteneur
        Service
                HeadRequire "Host: .*(domaine4.fr|domaine5.fr).*"
                BackEnd
                        Address 192.168.0.102
                        Port    8080
                End
        End

End

Friday, November 1 2013

Sécuriser (un peu mieux) MariaDB/MySQL en une ligne de commande

Cette petite astuce ne suffira pas à sécuriser parfaitement votre serveur MariaDB/MySQL mais cela y contribuera fortement ! Et ça ne coûte que quelques secondes donc il serait bête de s'en priver.

La commande :

mysql_secure_installation

va automatiquement durcir votre installation et la rendre plus à même d'être déployée en production en :

  • vérifiant que le(s) compte(s) 'root' dispose(nt) d'un mot de passe
  • supprimer les comptes de test et la base de données de test accessible par défaut à tout utilisateur
  • supprimer les comptes root (si vous le souhaitez) accessibles depuis un hôte autre que 'localhost'
  • supprimer les comptes anonymes

Voilà qui permet d'être plus serein !

Thursday, October 31 2013

Sauvegarder régulièrement ses bases de données MariaDB/MySQL (MàJ)

La commande mysqldump est fort pratique pour effectuer une sauvegarde des bases de données sur un serveur MariaDB/MySQL. On peut bien sûr l'utiliser pour mettre en place des solutions de sauvegarde maison (cf. 2e section de la dépêche). On peut aussi utiliser le petit outil "automysqlbackup" que m'a conseillé Jdrien.

Une solution toute prête : automysqlbackup

Automysqlbackup est un petit script qui fera sans doute tout ce que vous cherchez (et peut-être plus !) : conservation de versions journalières, hebdomadaires des bases, utilisation de l'utilisateur par défaut Debian pour éviter d'avoir à saisir un mot de passe dans un script cron... Je vous laisse le découvrir dans cet article : http://jdrien.net/chronicus/index.php?article66/automysqlbackup-ou-l-art-de-ne-pas-reinventer-la-roue

Merci à Jdrien pour m'avoir présenté cette solution !

Une solution "maison" si automysqlbackup ne vous convainc pas :

Voilà un petit script pour automatiser intelligemment le processus. Prévu pour être lancé une fois par jour, le script effectue les actions suivantes :

  • il liste les bases contenues sur le serveur
  • il exporte chaque base dans un fichier nom_de_la_base.sql.X avec X le numéro du jour (1 pour Lundi, 2 pour Mardi...)
#!/bin/bash
nbday=$(date +"%u")
cd /chemin/backup/mysql
for i in *.sql.$nbday; do rm -f "$i"; done
mysql --user=debian-sys-maint --password="abcdef123456" -e 'show databases' | while read dbname; do mysqldump --user=debian-sys-maint --password="abcdef123456" "$dbname" > "$dbname".sql.$nbday; done

Détaillons le travail ligne à ligne.

On récupère le numéro du jour :

nbday=$(date +"%u")

On se place dans le dossier de sauvegarde des bases SQL :

cd /chemin/backup/mysql

On supprime les sauvegardes de la semaine passée :

for i in *.sql.$nbday; do rm -f "$i"; done

On parcourt la base de données et on exporte avec mysqdump le contenu de chaque base dans un fichier .sql.X (avec X le numéro du jour) :

mysql --user=debian-sys-maint --password="abcdef123456" -e 'show databases' | while read dbname; do mysqldump --user=debian-sys-maint --password="abcdef123456" "$dbname" > "$dbname".sql.$nbday; done

Vous noterez que l'accès à la base est effectuée avec l'utilisateur 'debian-sys-maint'. Cela n'est bien sûr valable que sur les sytèmes Debian. 'debian-sys-maint' est équivalent à un compte 'root' et le mot de passe paramétré par défaut pour ce compte se trouve dans /etc/mysql/debian.cnf. Utilisé par le système pour certaines fonctions de maintenance, il vous permettra dans ce cas de ne pas laisser votre mot de passe 'root' "à vous" en clair dans un fichier !

Bonnes sauvegardes !

Wednesday, October 30 2013

Crypter une partition et l'ouvrir sans crainte d'un keylogger

Nous allons utiliser dm-crypt+LUKS qui se basent sur les outils de cryptographie présents normalement dans le noyau linux. On pourra faire le reproche à cette solution de ne pas permettre mettre en place un déni plausible (i.e. ouvrir une partition avec des données à l'apparence normale sous la contrainte, TrueCrypt le permet).

Création de la partition

La partition à crypter se nomme : /dev/sdaX Choisissons le chiffrement aes-xts-plain avec un taille de clé de 512 bits :

cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/sdaX

Le système demande une 'passphrase' que l'on choisira bien sûr longue, avec de nombreux caractères accentués, des chiffres, des majuscules, des signes de ponctuation... Attention à ne pas perdre la 'passphrase' car sans elle, point de salut !

Puis accédons au périphérique :

cryptsetup luksOpen /dev/sdaX zonecryptee

et formatons l'espace comme souhaité puis montons le :

mkfs.ext3 /dev/mapper/zonecryptee
mount -t ext3 /dev/mapper/zonecryptee /mnt/dossiercrypte/

Pour fermer la partition cryptée :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Pour obtenir des informations sur la partition crypée, on fera :

cryptsetup luksDump /dev/sdaX

Ajouter une clé pour accéder à la partition

Grâce à LUKS, on peut saisir plusieurs clés (jusqu'à 8) pour accéder à un même espace crypé. Commençons par générer une longe clé aléatoire :

dd if=/dev/urandom of=keyfile bs=1024 count=4

et ajoutons cette clé à l'espace crypté :

cryptsetup luksAddKey /dev/sdaX keyfile

On pourra désormais ouvrir l'espace, sans saisir la 'passphrase' secrète et sans crainte d'un keylogger ou d'une caméra qui filmerait nos mains sur le clavier, grâce à la commande :

cryptsetup --key-file=keyfile luksOpen /dev/sdaX zonecryptee

Après ouverture, la clé peut être retirée du système (elle n'est nécessaire qu'à l'ouverture) afin de limiter son exposition aux regards. Bien sûr, il ne faut pas perdre le fichier 'keyfile' et le conserver en sûreté ! S'il était compromis, on pourrait révoquer la clé avec la commande :

cryptsetup luksRemoveKey /dev/sdaX

Refermer la partition

Là rien ne change :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Protégez-vous bien !

Saturday, October 26 2013

Entretenir et sécuriser Roundcube avec logrotate et fail2ban

Roundcube entrepose certaines informations dans le dossier logs/ à la racine de l'installation. Le fichier 'errors' contiendra par exemple la trace des tentatives d'accès avec mot de passe erroné.

Pour éviter que ce fichier ne grossisse trop sans surveillance, nous allons : - mettre en place une rotation des logs avec logrotate - surveiller le log avec fail2ban pour bannir toute IP qui tenterait de forcer le passage en multipliant les essais de nom d'utilisateur et de mot de passe.

La rotation des logs

Dans /etc/logrotate.d/roundcube, on placera le paramétrage (assez explicite) suivant :

/var/www/roundcube/logs/errors {
        weekly
        missingok
        rotate 8
        compress
        notifempty
        create 640 www-data www-data
}

et le tour est joué.

On pourra appliquer la même rotation au fichier /var/www/roundcube/logs/sendmail si la volumétrie de votre webmail le nécessite !

Surveillance avec fail2ban

Nous allons créer un nouveau filtre dans /etc/fail2ban/filter.d/roundcube.conf :

[Definition]
failregex = Login failed for .*. from <HOST>

ou, si l'on est placé derrière un Proxy qui transmet la "vraie" adresse d'origine dans le champ X-Forwarded-For :

[Definition]
failregex = Login failed for .*. from .*.(X-Forwarded-For: <HOST>)

et une nouvelle règle :

[roundcube]
enabled  = true
port     = http,https
filter   = roundcube
action   = iptables46-multiport[name=apache, port="http,https", protocol=tcp]
logpath  = /var/www/roundcube/logs/errors
maxretry = 6

(attention, la règle d'action iptables46 correspond à une astuce temporaire pour ajouter le support de l'IPv6 à Fail2ban comme décrit ici)

et désormais, toute tentative d'accès répétée conduira à l'exclusion de l'IP douteuse !

Sunday, October 20 2013

fail2ban et IPv6

Fail2ban est un outil indispensable pour surveiller les tentatives d'accès frauduleuses à des serveurs. Quand un nombre déterminé d'actions offensantes ont été vues (dans les logs de vos serveurs SSH, FTP, HTTP...), alors fail2ban bannit l'IP mal intentionnée (grâce à iptables).

Malheureusment, la version 0.8.6 de fail2ban ne supporte que l'IPv4. Des travaux sont en cours à ce sujet et la version 0.9 (qui sera libérée bientôt) devrait contenir tout le nécessaire. En attendant, il existe un petit script que l'on peut déployer en suivant les instructions détaillées ici : http://www.crazyws.fr/dev/systeme/fail2ban-et-ipv6-sur-votre-serveur-debian-squeeze-MG970.html

Pour archive, je recopie aussi les grandes étapes à effectuer :

cd /root
wget http://thanatos.trollprod.org/sousites/fail2banv6/fail2ban-ipv6.tar.bz2
mkdir fail2ban-ipv6
tar xvjf fail2ban-ipv6.tar.bz2 -C fail2ban-ipv6

puis on sauvegarde les fichiers qui ont être patchés :

cd /usr/share/fail2ban/server
cp filter.py filter.py.withoutipv6
cp failregex.py failregex.py.withoutipv6

on teste le déploiement du patch :

cd /usr/share/fail2ban/server/
patch -p0 --dry-run < /root/fail2ban-ipv6/patchfilter.patch
patch -p0 --dry-run < /root/fail2ban-ipv6/regex.patch

puis on l'applique pour de vrai :

patch -p0 < /root/fail2ban-ipv6/patchfilter.patch
patch -p0 < /root/fail2ban-ipv6/regex.patch

et on rajoute les fichiers de configuration nécessaires :

cp /root/fail2ban-ipv6/ip64tables.sh /usr/bin/
chmod 755 /usr/bin/ip64tables.sh
cp /root/fail2ban-ipv6/iptables46-multiport.conf /etc/fail2ban/action.d/
chmod 644 /etc/fail2ban/action.d/iptables46-multiport.conf

On peut alors re-paramétrer les services à surveiller...

Pour SSH par exemple :

[ssh]
enabled = true
filter = sshd
action = iptables46-multiport[name=ssh, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
maxretry = 6

ou pour Apache (en utilisant la spécificité du multi-port) :

[apache]
enabled = true
filter = http,https
action = iptables46-multiport[name=ssh, port="http,https", protocol=tcp]
logpath = /var/log/apache*/*error.log
maxretry = 6

Friday, October 18 2013

Forcer la bascule vers HTTPS derrière un 'reverse proxy'

Pound (déjà évoqué à de nombreuses reprises dans ces lignes) est un 'reverse proxy' (et aussi un 'load balancer' si on souhaite utiliser ces fonctionnalités) très efficace... Il peut notamment gérer toutes les connexions en HTTPS vers vos serveurs web, les décrypter et ensuite les distribuer (bien sûr ce n'est à faire que sur un réseau local hermétique aux oreilles indiscrètes !) en HTTP à vos différents serveurs.

Selon les configurations, on acceptera les connexions en HTTP ou HTTPS ou seulement l'une ou l'autre. Parfois, on souhaite récupérer les utilisateurs qui se connectent en HTTP et les renvoyer automatiquement vers HTTPS.

Il faut alors demander au serveur web sous-jacent de réécrire les adresses, ce qui, sous Apache, se fait de la façon suivante :

        RewriteEngine on
        RewriteCond %{HTTP:X-Forwarded-Proto} !https
        RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

On notera que la réécriture ne s'applique que dans les cas où le drapeau 'X-Forwarded-Proto' n'est pas déjà HTTPS.

On peut bien sûr restreindre ce paramétrage à certains dossiers seulement (même si généraliser le HTTPS aujourd'hui serait une bonne pratique).

Pour restreindre cette ré-écrire (et donc ne forcer la connexion en HTTPS) que sur certains dossiers, on pourra inclure ces instructions dans un champ Directory :

        <Directory /var/www/appli/admin>
                RewriteEngine on
                RewriteCond %{HTTP:X-Forwarded-Proto} !https
                RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
        </Directory>

Ne laissez plus vos mots de passe transités en clair sur le net ! Forcez HTTPS a minima sur les zones sensibles !

Wednesday, October 16 2013

Apache derrière un 'reverse proxy' : la magie du X-Forwarded-For

Si votre serveur Web se trouve "caché" derrière un "reverse proxy" ou toute forme de "load balancer", alors vous serez peut-être embêté en constatant que les logs d'accès d'Apache ne mentionnent par défaut que l'adresse du proxy comme adresse d'origine... Ennuyeux !

Heureusement, les esprits ingénieux qui ont conçu les "reverse proxies" ont pensé à ajouter aux paquets transmis le drapeau "X-Forwarded-For". Il suffit alors de demander à votre serveur web de prendre en compte l'IP spécifiée dans ce champ comme origine de la communication !

Dans le cas d'Apache2, la configuration intiale qui était :

LogFormat "%v:%p %h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%h%l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

devient (on remplace %h par %{X-Forwarded-For}i) :

LogFormat "%v:%p %{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Pour les logs d'erreur (importants par exemple pour permettre à fail2ban, ou un autre démon du genre, d'agir), la version 2.2 d'Apache ne permet malheureusement pas de prendre en compte un format spécifique pour les logs. Il semble que cela soit corrigé dans la version 2.4 d'Apache (cf. ici). Si vous utilisez la version 2.2, alors il faudra installer le module rpaf :

aptitude install libapache2-mod-rpaf
a2enmod rpaf

puis dans /etc/apache2/conf.d/mod_rpaf :

RPAFenable On
RPAFsethostname On
RPAFproxy_ips a.b.c.d e.f.g.h
RPAFheader X-Forwarded-For

en remplaçant a.b.c.d et e.f.g.h par les adresses du reverse proxy. RPAF va veiller, dans les logs d'erreur, à remplacer l'adresse du 'reverse proxy' par l'adresse du client telle que signalée dans "X-Forwarded-For".

Et le tour est joué !

Enregistrer les logs de Pound avec rsyslog et logrorate

Pound est un reverse proxy fort pratique. Par défaut, aucun log des connexions n'est enregistré mais cela se paramètre...

Voici une configuration fonctionnelle sur Debian.

Dans /etc/pound/pound.cfg :

LogFacility     local0
LogLevel        1

Dans /etc/rsyslog.d/pound.conf :

local0.* -/var/log/pound.log

et dans /etc/rsyslog.conf :

*.*;auth,authpriv.none              -/var/log/syslog

devient :

*.*;auth,authpriv.none,local0.none              -/var/log/syslog

Dans /var/log, on crée le fichier de log (et on en modifie les droits si nécessaire) :

touch /var/log/pound.log
chown rood:adm /var/log/pound.log

On redémarre alors les 2 services rsyslog et pound :

service rsyslog restart
service pound restart

Envie de rotation ?

Les logs de Pound peuvent rapidement atteindre des tailles phénoménales s'il gère des traffics importants. A surveiller donc sur les premières journées d'utilisation ! Le cas échéant, on peut utiliser une rotation de log pour garder les données des quelques derniers jours et éviter la disparaition de l'espace libre sur un serveur !

Dans /etc/logrotate.d/pound :

/var/log/pound.log {
        daily
        missingok
        rotate 7
        compress
        copytruncate
        notifempty
        create 640 root root
}

Monday, October 14 2013

Suivre l'état de son serveur avec Munin

Munin est un logiciel libre performant pour surveiller et suivre ("monitorer" si on s'autorise les anglicismes) des ordinateurs ou des serveurs. Il se compose de deux composants :

  • munin-node, l'utilitaire chargé de récupérer les données sur les "noeuds" du réseau
  • munin, le superviseur qui compile les données de tous les "noeuds" surveillés, fabrique des graphiques et des pages HTML pour permettre la visualisation aisée des données au travers d'un serveur web

Nous allons décrire ici le déploiement de munin-node sur un serveur et de munin sur un poste superviseur distinct.

Installer et paramétrer munin-node sur le poste à surveiller

Munin-node s'installera avec votre gestionnaire de paquet favori ; par exemple sous Debian :

aptitude install munin-node

Lors de l'installation, munin-node choisit et paramètre automatiquement un certain nombre de plugins (chaque plugin est un petit programme autonome capable d'aller collecter des données précises : par exemple le plugin cpu collecte des informations sur la charge du processeur, postfix_mailstats extrait des logs le nombre de courriels transmis par postfix, ...). Le paramétrage de munin-node s'effectue dans /etc/munin/munin-node.conf.

On pourra notamment prêter attention à ces paramètres :

#Spécifier le nom de l'hôte surveillé
host_name serveur_surveille1.domain.tld
#Adresse IPv4 du superviseur qui aura le droit de se connecter au noeud pour récupérer les informations
allow ^192\.168\.1\.200$
#Port sur lequel le service est disponible
port 4949

Une fois le paramétrage terminé, on redémarre le client par la commande

service munin-node restart

Installer le superviseur

Le superviseur Munin s'installe avec :

aptitude install munin

Il faut ensuite indiquer au superviseur quels sont les noeuds à interroger et éventuellement donner des indications spécifiques pour les graphes à construire. Cela s'effectue dans /etc/munin/munin.conf :

[serveur_surveille1.domain.tld]
    address 192.168.1.45
    use_node_name yes

Le travail de génération des graphes et des pages HTML est effectué régulièrement grâce à une tâche cron (dont la fréquence pourra être modifiée dans le fichier /etc/cron.d/munin). Il est également possible de paramétrer le système pour générer les graphes lors des consultations à l'aide d'un recours à des scripts cgi - cela n'est pas détaillé ici. Les travaux de munin ne sont pas silencieux, les logs (bien pratiques pour comprendre une éventuelle panne) sont situés dans /var/log/munin/.

On redémarrer munin par

service munin restart

et après quelques minutes d'attente, les premiers graphes doivent être générés et accessibles dans /var/cache/munin/www/.

On pourra alors rendre accessible ce dossier au travers d'un serveur web bien paramétré !

Load munin

Pour aller plus loin avec les plugins sur le noeud

Tous les plugins disponibles sont regroupés dans /usr/share/munin/plugins/ et on pourra les rendre actifs par la commande :

ln -s /usr/share/munin/plugins/pluginchoisi /etc/munin/plugins/pluginchoisi

Pour tester un plugin et visualiser les données qu'il retourne, on pourra utiliser la commande :

munin-run postfix_mailstats

La configuration des plugins s'effectue dans le fichier /etc/munin/plugin-conf.d/munin-node suivant les instructions que l'on trouvera dans les en-têtes des fichiers de plugins.

Bonne surveillance de vos serveurs !

Sunday, October 13 2013

Onduleur et Raspberry Pi, détecter et agir en cas de panne de courant

Dans cet article, nous allons voir comment faire communiquer un onduleur Eaton Ellipse 650 (mais le mode opératoire peut s'adapter à d'autres modèles d'onduleurs compatibles avec Linux) et un Raspberry Pi sous Raspbian. Le Raspberry Pi pourra alors accomplir une série d'actions : par exemple, dans le cas exposé ici, envoyer une notification de coupure électrique par courriel.

On commence par installer l'utilitaire NUT sous Linux :

aptitude install nut nut-usb

Puis on choisit le mode STANDALONE dans /etc/nut/nut.conf. Ensuite on ajoute un paragraphe correspondant à l'onduleur connecté en USB au Raspberry Pi dans /etc/nut/ups.conf :

[eaton]
driver = usbhid-ups
port = auto
desc = "MGE UPS Systems"

On peut alors vérifier que la connexion à l'onduleur fonctionne par la commande :

/lib/nut/usbhid-ups -DDD -a eaton

SI l'utilitaire nous retourne une erreur similaire à "failed to claim USB device" alors cela peut signifier que les droits ne sont pas suffisants pour accéder à la ressource. On peut alors essayer la connexion avec la commande :

/lib/nut/usbhid-ups -DDD -u root -a eaton

Si cela fonctionne, on pourra alors régler (attention, c'est une méthode un peu brutale !) le problème en modifiant la section "usbfs-like devices" du fichier /lib/udev/rules.d/91-permissions.rules :


 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", \
-                               MODE="0664"
+                               MODE="0666"

(attention au risque potentiel de sécurité de cette modification, à n'effectuer qu'en connaissance de cause !)

Une fois l'onduleur correctement reconnu, on ajoutera un utilisateur à la liste des utilisateurs autorisés à se connecter au service de l'onduleur. Ce paramétrage s'effectue en modifiant le fichier /etc/nut/upsd.users - on ajoutera par exemple


[utilisateur]
        password = monmotdepasse
        upsmon master

Enfin, on modifiera le fichier /etc/nut/usbmon.conf pour modifier les options de suivi :

MONITOR eaton@localhost 1 utilisateur monmotdepasse master

On pourra spécifier un script spécifique à exécuter lors des événements électriques :

NOTIFYCMD /path/to/notification/script

Et on pourra modifier le contenu des messages à envoyer pour chaque événement électrique reconnu :

NOTIFYMSG ONLINE        "Electrical power is back ON - UPS %s on line power"
NOTIFYMSG ONBATT        "Loss of electrical power - UPS %s on battery"
NOTIFYMSG LOWBATT       "Loss of electrical power continues - UPS %s"

Pour chaque état de l'onduleur, on pourra spécifier les actions à effectuer : - EXEC = exécuter le script de notification paramétré plus haut - SYSLOG = mentionner l'événement dans le syslog du système - WALL = faire apparaître le message dans la console de tous les utilisateurs connectés

NOTIFYFLAG ONLINE       EXEC+SYSLOG+WALL
NOTIFYFLAG ONBATT       EXEC+SYSLOG+WALL
NOTIFYFLAG LOWBATT      EXEC+SYSLOG+WALL

On pourra par exemple utiliser un scrit de notification de la sorte :

#! /bin/bash
#Send email with detailed UPS report
o=$(upsc eaton)
d=$(date)
echo -e "$d" "\n\nEvent: " "$*" "\n\n======Details on UPS=====\n" "$o" |mail -s "Evénement électrique" courriel@domain.tld
#Add any other actions: send SMS, launch shutdowns of critical systems...

Bonne surveillance de votre onduleur !

Friday, October 11 2013

Reverse IPv6 avec DNSMasq, chez Online.net

Comme raconté ici, le postmaster de Google a adopté une position très stricte de rejet de tout courriel provenant d'un serveur SMTP se connectant en IPv6 mais ne disposant pas de champ 'reverse' concordant.

On peut déplorer cette très grande rigidité et s'en étonner, surtout dans une période d'adoption progressive de l'IPv6. Pour ceux dont le fournisseur d'accès (plus précisément le fournisseur de votre bloc d'adresses IPv6) ne donne aucun moyen d'avoir un 'reverse', une solution temporaire est proposée ici : connexion en IPv4 à Google.

Dans le cas d'Online.net, la possibilité d'une délégation DNS est apparue récemment en production. Elle permet d'indiquer à quel serveur DNS se raccrocher pour effectuer la translation de nom inverse (i.e. d'adresse IP vers nom de domaine) pour les adresses du bloc.

Etape 1 : disposer d'un serveur DNS capable de répondre aux requêtes "reverse"

La grande référence du DNS est bind, mais on peut également monter ce petit service en moins de 10 lignes de configuration avec DNSMasq (dont je parlais déjà ici).

On installe dnsmasq par

aptitude install dnsmasq

et voici un exemple de configuration complète :

log-facility=/var/log/dnsmasq.log
log-queries
no-resolv
no-hosts
ptr-record=0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse1.domain.tld
ptr-record=1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse2.domain.tld

Les paramètres log-facility et log-queries indiquent que l'on souhaite garder une trace de toutes les requêtes DNS dans /var/log/dnsmasq.log

no-resolv et no-host ainsi que l'absence de paramètre server indiquent que l'on ne souhaite répondre positivement qu'aux requêtes correspondant à l'un des enregistrements mentionnés dans le fichier de configuration.

Et enfin, sont indiqués les 2 enregistrements PTR qui correspondent à 2 adresse IPv6 pour lesquelles on souhaite avoir un reverse IPv6.

La première adresse est 2001:abcd:efgh:100:: et la seconde est 2001:abcd:efgh:100::101. On voit que l'adresse est mentionnée dans l'enregistrement PTR en l'écrivant "à l'envers" et en séparant chaque caractère (y compris les 0 que la convention nous permet de ne pas faire apparaître dans les adresses IPv6) par un point.

Etape 2 :

On rend ce serveur DNS très simple (et capable de ne répondre qu'à ces 2 requêtes reverse IPv6) accessible à l'adresse dns.domain.tld. Si on est placé derrière un firewall, on n'oubliera pas d'ouvrir le port 53 en TCP et en UDP.

Etape 3 : paramétrer la délégation DNS chez le fournisseur du bloc IPv6

Cette étape diffère selon le fournisseur du bloc IPv6. Chez Online, il faut se rendre dans la console, onglet "Serveur" puis "Paramétrage du réseau". On choisit le bloc IPv6 de son choix et on clique sur l'option "Paramétrer la délégation DNS". On saisit alors l'adresse du serveur DNS capable de répondre aux éventuelles requêtes reverse IPv6.

Délégation DNS chez Online

Etape 4 : on peut à nouveau écrire aux destinataires de GMail

Si on expédie un message à un destinataire @gmail.com, quelques secondes plus tard, on voit apparaître dans les logs la requête DNS suivante :

Oct 6 14:04:59 dnsmasq[21288]: query[PTR] 
1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa **from 74.125.18.211**

74.125.18.211 est une adresse (IPv4 !) de Google qui vient s'enquérir du reverse IPv6. Et le courriel est expédié sans encombre !

Bons paramétrages de reverse IPv6 à tous !

Thursday, October 10 2013

Ajouter un disque additionnel à un RAID 1 en 5 lignes de commande

Un RAID 1 (mirroring) constitue ne bonne garantie contre une panne de disque dur sur une machine (serveur, poste de bureau, NAS) contenant des données critiques. Avec une bonne maintenance, on peut espérer conserver des données avec un faible taux de risque de perte sur de longues durées : une bonne méthode consistant par exemple à ajouter des disques plus récents à la grappe RAID.

Nous allons détailler ici les opérations nécessaires pour ajouter un disque dur de X Go à une grappe (RAID 1) de 2 disques durs de même capacité, gérée par les fonctionnalités de RAID logiciel sous Linux.

La première étape consiste à copier la table des partitions des disques durs actifs dans le RAID (appelons les /dev/sda et /dev/sdb) sur le nouveau disque (/dev/sdc). En effet, le nouveau disque doit être structuré (en termes de partitions) rigoureusement comme les anciens.

Attention, il existe aujourd'hui couramment deux types de table de partition : l'ancien système à base de MBR (Master Boot Record) et le nouveau système nommé GPT (Globally Unique Identifier Partition Table). En MBR, vous pouvez utiliser l'utilitaire fdisk/sfdisk (non détaillé ici). Si vos disques sont formatés avec des tables GPT (le nouveau standard), voici comment faire.

On enregistre d'abord la table de partition du disque sda dans un fichier 'table' :

sgdisk --backup=table /dev/sda

puis on applique cette table au disque /dev/sdc (attention à ne pas se tromper de disque, cela pourrait être destructeur !) :

sgdisk --load-backup=table /dev/sdc

Et comme dans le système GPT chaque partition est identifiée par un unique GUID et que celui-ci est inclus dans la table GPT, alors il faut modifier les GUID pour des valeurs aléatoires dans le disque fraîchement ajouté :

sgdisk -G /dev/sdc

Le nouveau disque dur est maintenant prêt à intégrer le RAID.

mdadm --detail /dev/md0

va nous permettre de regarder les partitions inclues dans cette première partition en RAID. Par exemple, on verra que ce sont les partitions /dev/sda2 et /dev/sdb2 qui sont concernées. On saura donc qu'il faut ajouter /dev/sdc2 :

mdadm --manage /dev/md0 --add /dev/sdc2

Puis

mdadm --detail /dev/md0

doit montrer que le nouveau disque a été ajouté.

Il est toutefois fort probable que le disque ait été monté en 'spare device' i.e. en périphérique activé uniquement en cas de perte d'un autre disque. Si vous souhaitez que les données soient répliquées dès maintenant sur ce disque, il faudra agrandir le RAID :

mdadm --grow /dev/md0 --raid-devices=3

Et le tour est joué, la reconstruction du RAID (i.e. la copie des données vers le nouveau disque) doit s'effectuer de manière transparente. /dev/md0 est désormais répliqué sur 3 disques durs.

Bien sûr, une procédure similaire pourra être déployée en cas de disque défectueux pour ajouter un nouveau disque dans la grappe !

- page 5 of 8 -