Installation minimaliste d'une CentOS 6

Suite à un billet précédent sur l'installation d'un domU Enterprise Linux sur un dom0 NetBSD, et à la sortie de CentOS 6.0, j'ai fait quelques essais d'installations de cette distribution.

Il n'y a pas d'énormes différences entre le billet cité et CentOS 6.0, juste quelques surprises. La première est au niveau de l'installation en mode texte, qui perd en possibilités, il n'est par exemple plus possible de personnaliser son partitionnement ou la liste des packages. Il faudra préférer une installation via VNC, qui permet d'afficher l'interface graphique. Les limitations en mémoire de RHEL 6 sont d'ailleurs valable pour CentOS 6, attention donc à attribuer assez de mémoire vive, au moins lors de l'installation, pour obtenir l'interface graphique.

J'ai donc décidé de passer par Kickstart pour quelques installations, et là aussi, il y a quelques changements, comme par exemple certains champs optionnels devenus obligatoires. Voici donc un exemple de kickstart commenté pour une installation minimaliste (mais pas minimale) personnalisée :

# Langue et zone horaire
lang fr_FR
keyboard fr 
timezone --utc Europe/Paris
# J'utilise Xen, donc je shutdown pour modifier le noyau d'installation en pygrub
shutdown
text
# on peut chiffrer le mdp root
rootpw changemonmdprootsvp
# j'autorise quelques services du firewall, la configuration au premier boot mais pas de SELinux par contre 
firewall --service=ssh --service=smtp
firstboot --enable
selinux --disabled
# Configuration du réseau
network --device eth0 --bootproto dhcp
# Paramétrage du disque dur : bootloader et partitionnement. Attention, on efface tout !
bootloader --location=mbr --driveorder=xvda
authconfig --enableshadow --passalgo=sha512
clearpart --all --initlabel --drives=xvda
part /boot --fstype ext3 --size 500 
part swap --size 512 
part / --fstype ext3 --size 5000
part /home --fstype ext3 --size 1200
part /var --fstype ext3 --size 400 --grow
# On fait une installation par le réseau, pensez à modifier ces urls par celles qui vous correspondent
# De plus, les dépôts updates et extras sont ajoutés pour que le système soit à jour dès l'installation
url --url http://monmiroirlocal/pub/CentOS/6/os/x86_64/
repo --name=updates --baseurl=http://monmiroirlocal/pub/CentOS/6/updates/x86_64/
repo --name=extras --baseurl=http://monmiroirlocal/pub/CentOS/6/extras/x86_64/
# C'est là qu'on s'amuse avec la liste des paquets.
# --nobase permet une installation très légère, mais il faut au moins le groupe @Core
# A noter que je refuse l'installation de nombreux firmwares matériels car je suis en VM.
%packages --nobase
@Core
ntp
openssh-clients
wget
vim-enhanced
-b43-openfwwf
-kernel-firmware
-aic94xx-firmware
-atmel-firmware
-bfa-firmware
-ipw2100-firmware
-ipw2200-firmware
-ivtv-firmware
-iwl1000-firmware
-iwl3945-firmware
-iwl4965-firmware
-iwl5000-firmware
-iwl5150-firmware
-iwl6000-firmware
-iwl6050-firmware
-libertas-usb8388
-ql2100-firmware
-ql2200-firmware
-ql23xx-firmware
-ql2400-firmware
-ql2500-firmware
-rt61pci-firmware
-rt73usb-firmware
-xorg-x11-drv-ati-firmware
-zd1211-firmware

# La post-installation me permet de récupérer et d'appliquer des configurations spécifiques
# Très pratique pour déboguer, l'option --log :)
%post --log=/root/postinstall.log
wget http://monmiroirlocal/pub/cfg/c6postinstall/prompt.sh -O /etc/profile.d/prompt.sh
wget http://monmiroirlocal/pub/cfg/c6postinstall/CentOS-Base.repo -O /etc/yum.repos.d/CentOS-Base.repo
wget http://monmiroirlocal/pub/cfg/c6postinstall/ntp.conf -O /etc/ntp.conf
wget http://monmiroirlocal/pub/cfg/c6postinstall/main.cf -O /etc/postfix/main.cf
chkconfig ntpd on
chkconfig postfix on

Avec ce genre d'installation, on tombe à moins de 200 paquets installés :)

Utilisation de nombreux domU en backend fichiers sur un dom0 NetBSD

Oui, j'utilise des machines virtuelles Xen dans des fichiers. Pas de partition, pas de LVM, non. Un bon vieux fichier qu'on peut effacer sans regrets une fois son domU "jetable" inutile. Pour utiliser ces fichiers, et pour monter des fichiers en tant que disque de manière générale, NetBSD utilise le pilote vnd (4). Et par défaut, il y a 4 fichiers spéciaux vnd. Et lorsqu'on désire lancer 42 machines virtuelles en même temps, chacune ayant besoin d'un fichier vnd pour monter son disque dur, on obient une erreur du genre :

Error: Device 51712 (vbd) could not be connected. Hotplug scripts not working.

Alors on s'affole, on copie-colle le message dans un moteur de recherche bien connu, et on tombe sur ce genre de chose :

How much /dev/vnd*d device do you have ? Maube you need to create more ? e.g.: cd /dev ./MAKEDEV vnd4 vnd5 vnd6 vnd7 vnd8

Donc on applique :

root@arreat:/usr/pkg/etc/xen# cd /dev
root@arreat:/dev# ./MAKEDEV vnd4 vnd5 vnd6 vnd7 vnd8 vnd9 vnd10 vnd11 vnd12 vnd14 vnd15
root@arreat:/dev# cd /usr/pkg/etc/xen
root@arreat:/usr/pkg/etc/xen# xm create vmjetable1 && xm create vmkikoo2 \
&& xm create vmpipeau3 && xm create vmdelire4 && xm create encoreunevmjetable

Maintenant, c'est la RAM qui va commencer à manquer... mais c'est un autre problème ;-)

Installation d'un domU Xen Enterprise Linux sur un dom0 NetBSD

Ces derniers temps je m'amuse à faire des installations par le réseau d'un peu tout et n'importe quoi. J'utilise principalement l'outil de virtualisation Oracle VirtualBox, mais il m'arrive aussi de faire joujou avec Xen. Avec un hôte (dom0) CentOS 5 (et sans doute toutes les distribution de type "Enterprise Linux" telles que Red Hat Enterprise Linux ou Scientific Linux), il est très facile de créer d'autres machines virtuelles (domU) Xen de même type grâce à la commande "virt-install". Avec un dom0 NetBSD cependant, point de commande de ce type. Voyons donc comment faire.

Sur un système Enterprise Linux 5, il est possible de trouver une image de noyau d'installation (et l'initrd approprié) spécifique à Xen, comme par exemple sur ce miroir pour CentOS 5 64 bits.

Ce qui me paraît étrange, c'est avec Enterprise Linux 6, tout du moins avec Scientific Linux. Le noyau 2.6.32 dispose à priori des pv-ops, mais SL6 dispose d'un noyau et d'un initrd Xen. Peut-être est-ce par soucis de compatibilité de chemins, car les fichiers font la même taille que dans le répertoire pxeboot. D'ailleurs, lors de ma synchronisation rsync avec le miroir officiel Scientific Linux, le répertoire xen n'apparaît pas. Et je n'en ai pas eu besoin :)

Une fois nos images de noyau et d'initrd en main, il nous reste à créer notre fichier de configuration de domU, mon exemple prend comme exemple de disque dur un fichier et une connexion réseau par bridge :

name = "centosexample"
uuid = ""
maxmem = 512
memory = 512
kernel  = "/srv/www/pub/CentOS/5/os/x86_64/images/xen/vmlinuz"
ramdisk = "/srv/www/pub/CentOS/5/os/x86_64/images/xen/initrd.img"
extra = "vnc"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [  ]
disk = [ "file:/srv/xen/images/disk/centosexample.img,xvda,w" ]
vif = [ "mac=00:16:3a:e2:12:34,bridge=bridge0" ]

Il est possible de faire l'installation en mode texte en supprimant la ligne "extra", et d'ajouter l'url d'un fichier kickstart dans la directive extra, qui devient donc :

extra = "text ks=http://monserveur/pub/cfg/centos5_x86_64.cfg"

La commande "xm create -c centosexample" vous permet de lancer votre domU et de débuter l'installation. Une fois celle-ci faite et votre domU de nouveau éteint, il suffit de commenter les lignes "kernel" et "ramdisk" et de décommenter la ligne "bootloader". Vous pouvez alors démarrer votre domU sans que le noyau de celui-ci soit sur le disque dur du dom0 :)

Lors de mes tests, je me suis limité au partitionnement par défaut (qui utilise LVM), à un détail près : avec Scientific Linux 6, j'ai imposé ext3 à l'installeur. Une fois l'installation terminée, éteindre son domU (proprement de préférence) et modifier la configuration qui devient :

name = "centosexample"
uuid = ""
maxmem = 512
memory = 512
bootloader = "/usr/pkg/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [  ]
disk = [ "file:/srv/xen/images/disk/centosexample.img,xvda,w" ]
vif = [ "mac=00:16:3a:e2:12:34,bridge=bridge0" ]

J'ai donc remplacé le noyau et l'initrd d'installation par pygrub, qui me permet de démarrer mon domU sur le noyau et l'initrd installés. De plus, les mises à jour ne nécessitent pas de copier de nouveau le noyau et l'initrd sur le dom0.

Pour finir, si vous souhaitez installer un dom0 NetBSD, je ne peux que vous recommander l'excellent billet de Bsdsx !

Configuration d'une redondance DNS

Je suis dans la situation suivante : j'ai une machine exécutant entre autres un serveur DHCP et un serveur DNS, et je souhaite réinstaller cette machine. Problème, si je la réinstalle, le DHCP et le DNS seront indisponibles. Il me faut donc redonder ces deux services pour ne pas perturber les autres machines. Après la redondance DHCP, ce billet aborde la redondance DNS. Ce billet, comme le précédent, n'aborde pas la configuration complète d'un serveur DNS mais détaille les options de configurations liées à la redondance

Une redondance basique dans un LAN est très facile à mettre en œuvre car il n'y a pas besoin de modifier quoi que ce soit chez un registrar. Il faudra cependant ajouter l'adresse IP du second serveur DNS dans la configuration de toutes les machines ayant une adresse IP statique, car celles-ci ne récupèrent pas la liste des serveurs DNS via DHCP. Une redondance DNS se compose généralement d'au moins deux serveurs : un serveur maître et un ou plusieurs serveurs esclaves. Toutes nos futures modifications dans le DNS s'effectueront sur le serveur maître et seront répliquées automatiquement vers le serveur esclave. Dans notre cas, le serveur maître utilise NetBSD 4.0 et le serveur esclave utilise NetBSD 5.1; dans les deux cas, ISC Bind est utilisé dans sa version embarquée avec l'OS, et configuré dans un chroot.

Sur notre serveur maître, configurons nos zones dans le fichier /var/chroot/named/etc/named.conf :

zone "anotherhomepage.loc" IN {
        type master;
        file "anotherhomepage.loc";
        allow-update { none; };
        allow-query { any; };
        allow-transfer { 10.13.37.11; };
};

zone "37.13.10.in-addr.arpa" IN {
        type master;
        file "anotherhomepage.loc.reverse";
        allow-update { none; };
        allow-query { any; };
        allow-transfer { 10.13.37.11; };
};

Remarquons que nous autorisons le transfert vers 10.13.37.11 qui est le serveur esclave. Continuons dans le fichier de zone anotherhomepage.loc dont voici quelques extraits :

$TTL 86400
@       IN      SOA     ns0.anotherhomepage.loc. nils.anotherhomepage.loc. (
               2011042601 ; Serial
               8H   ; Refresh
               2H   ; Retry
               4W  ; Expire
               1D  ; Minimum TTL
)

; Name servers
anotherhomepage.loc.    IN      NS     ns0
anotherhomepage.loc.    IN      NS     ns1
; Mail servers
anotherhomepage.loc.    IN      MX      10      mail
; "A" entries
ns0                  IN      A       10.13.37.10
ns1                  IN      A       10.13.37.11
mail                 IN      A       10.13.37.12

Notre serveur esclave est donc renseigné pour le DNS, voyons voir dans le DNS inverse, fichier de zone anotherhomepage.loc.reverse :

$TTL 86400
@       IN      SOA     ns0.anotherhomepage.loc. nils.anotherhomepage.loc. (
               2011042601  ; Serial
               8H   ; Refresh
               2H   ; Retry
               4W  ; Expire
               1D  ; Minimum TTL
)
        IN      NS      ns0.anotherhomepage.loc.
        IN      NS      ns1.anotherhomepage.loc.
        IN      MX      10      mail.anotherhomepage.loc.
10      IN      PTR     ns0.anotherhomepage.loc.
11      IN      PTR     ns1.anotherhomepage.loc.
12      IN      PTR     mail.anotherhomepage.loc.

Occupons-nous à présent de notre serveur esclave. De ce côté, un seul fichier à modifier, /var/chroot/named/etc/named.conf, car les autres seront transférés par les mises à jour de zone :

zone "anotherhomepage.loc" IN {
        type slave;
        masters { 10.13.37.5; };
        file "anotherhomepage.loc";
        allow-update { 10.13.37.5; };
        allow-query { any; };
        allow-notify { 10.13.37.5; };
};

zone "37.13.10.in-addr.arpa" IN {
        type slave;
        masters { 10.13.37.10; };
        file "anotherhomepage.loc.reverse";
        allow-update { 10.13.37.10; };
        allow-query { any; };
        allow-notify { 10.13.37.10; };
};

Il ne reste maintenant qu'à vérifier notre configuration. Par défaut, les logs vont dans /var/log/messages. Vous pouvez définir un autre emplacement pour les logs, comme par exemple :

logging {
        channel simple_log {
                file "/var/log/named/bind.log" ;
                severity info;
                print-time yes;
                print-severity yes;
                print-category yes;
        };
        category default{
                simple_log;
        };
        category queries{
                simple_log;
        };
};

Cet exemple est à insérer dans votre named.conf. Incrémentons les numéros de série, effectuons une relance de bind sur le serveur esclave puis le serveur maître :

root@ns0:/var/chroot/named/var# /etc/rc.d/named reload
Reloading named config files.

Regardons le résultat sur le serveur esclave pour la relance du serveur maître :

root@ns1:/var/chroot/named/etc# tail -f /var/chroot/named/var/log/named/bind.log
26-Apr-2011 19:14:10.864 notify: info: client 10.13.37.5#64893: received notify for zone '37.13.10.in-addr.arpa'
26-Apr-2011 19:14:10.923 general: info: zone 37.13.10.in-addr.arpa/IN: Transfer started.
26-Apr-2011 19:14:10.924 xfer-in: info: transfer of '37.13.10.in-addr.arpa/IN' from 10.13.37.5#53: connected using 10.13.37.60#65525
26-Apr-2011 19:14:11.335 general: info: zone 37.13.10.in-addr.arpa/IN: transferred serial 2011042601
26-Apr-2011 19:14:11.336 xfer-in: info: transfer of '37.13.10.in-addr.arpa/IN' from 10.13.37.5#53: Transfer completed: 1 messages, 258 records, 8672 bytes, 0.411 secs (21099 bytes/sec)
27-Apr-2011 19:14:11.337 notify: info: zone 37.13.10.in-addr.arpa/IN: sending notifies (serial 2011042601)
26-Apr-2011 19:14:11.383 notify: info: client 10.13.37.5#64893: received notify for zone 'anotherhomepage.loc'
26-Apr-2011 19:14:11.388 general: info: zone anotherhomepage.loc/IN: Transfer started.
26-Apr-2011 19:14:11.390 xfer-in: info: transfer of 'anotherhomepage.loc/IN' from 10.13.37.5#53: connected using 10.13.37.60#65524
26-Apr-2011 19:14:11.654 general: info: zone anotherhomepage.loc/IN: transferred serial 2011042601
26-Apr-2011 19:14:11.654 xfer-in: info: transfer of 'anotherhomepage.loc/IN' from 10.13.37.5#53: Transfer completed: 1 messages, 268 records, 8464 bytes, 0.263 secs (32182 bytes/sec)
26-Apr-2011 19:14:11.657 notify: info: zone anotherhomepage.loc/IN: sending notifies (serial 2011042601)

Houra ! Les transferts ont eu lieu ! Maintenant, il reste à modifier dans notre serveur DHCP les adresses IP des serveurs DNS. Dans le cas d'ISC DHCP :

option domain-name-servers 10.13.37.10, 10.13.37.11;

Notez que ce billet permet une redondance assez basique, et loin d'être totalement sécurisée : quelqu'un d'assez malin peut, en utilisant une attaque de type Man-in-the-middle peut appliquer des modifications au serveur esclave. Pour les personnes qui aimeraient corriger ce défaut, il faut se tourner vers DNSSEC.

Configuration d'une redondance DHCP

Ce billet est basé sur l'excellent billet de Paul Heinlein et publié avec son aimable autorisation. Le billet original se trouve ici.

Je suis dans la situation suivante : j'ai une machine exécutant entre autres un serveur DHCP et un serveur DNS, et je souhaite réinstaller cette machine. Problème, si je la réinstalle, le DHCP et le DNS seront indisponibles. Il me faut donc redonder ces deux services pour ne pas perturber les autres machines. Ce billet ne porte cependant que sur DHCP.

Commençons par jeter un oeil à la configuration actuelle du serveur DHCP, elle ressemble un peu à ceci :

ddns-domainname "anotherhomepage.loc";
ddns-update-style none;
ddns-updates off;
ignore client-updates;
authoritative;
allow unknown-clients;
max-lease-time 3600;
default-lease-time 1800;
subnet 10.13.37.0 netmask 255.255.255.0 {
        pool {
        deny dynamic bootp clients;
        range 10.13.37.200 10.13.37.249;
        option domain-name-servers 10.13.37.5;
        option domain-name "anotherhomepage.loc";
        option routers 10.13.37.254;
        option broadcast-address 10.13.37.255;
group {
use-host-decl-names true ;

# Virtual Machine de tests PXE
host pxemachine {
        hardware ethernet 08:00:27:d3:8f:2d;
        fixed-address 10.13.37.199;
        option host-name "pxemachine";
}
}
}
}

On y trouve un pool, un groupe et une machine dans ce groupe avec une adresse IP fixée grâce à son adresse MAC : n'importe quelle machine se verra attribuer une adresse entre 10.13.37.200 et 10.13.37.249, mais la machine dont l'adresse MAC est 08:00:27:d3:8f:2d se verra attribuer l'IP 10.13.37.199.

Que se passe-t-il si je stoppe le serveur DHCP ? Les clients n'ont plus d'IP, donc plus d'accès au réseau, ce qui peut s'avérer gênant. Recopions la configuration sur l'autre serveur puis modifions celle-ci, qui va maintenant ressembler à ça :

ddns-domainname "anotherhomepage.loc";
ddns-update-style none;
ddns-updates off;
ignore client-updates;
authoritative;
allow unknown-clients;
max-lease-time 3600;
default-lease-time 1800;
failover peer "dhcp-failover" {
        primary; # declare this to be the primary server
        address 10.13.37.5;
        port 647;
        peer address 10.13.37.60;
        peer port 647;
        max-response-delay 30; 
        max-unacked-updates 10; 
        load balance max seconds 3;
        mclt 1800;
        split 128;
}
subnet 10.13.37.0 netmask 255.255.255.0 {
        pool {
        failover peer "dhcp-failover";
        deny dynamic bootp clients;
        range 10.13.37.200 10.13.37.249;
        option domain-name-servers 10.13.37.5;
        option domain-name "anotherhomepage.loc";
        option routers 10.13.37.254;
        option broadcast-address 10.13.37.255;
group {
use-host-decl-names true ;

# Virtual Machine de tests PXE
host pxemachine {
        hardware ethernet 08:00:27:d3:8f:2d;
        fixed-address 10.13.37.199;
        option host-name "pxemachine";
}
}
}
}

Maintenant notre machine est serveur primaire DHCP et communique avec le serveur désigné après peer address. Allons d'ailleurs voir la nouvelle configuration du serveur secondaire :

ddns-domainname "anotherhomepage.loc";
ddns-update-style none;
ddns-updates off;
ignore client-updates;
authoritative;
allow unknown-clients;
max-lease-time 3600;
default-lease-time 1800;
failover peer "dhcp-failover" {
        secondary; # declare this to be the secondary server
        address 10.13.37.60;
        port 647;
        peer address 10.13.37.5;
        peer port 647;
        max-response-delay 30; 
        max-unacked-updates 10; 
        load balance max seconds 3;
        mclt 1800;
        split 128;
}
subnet 10.13.37.0 netmask 255.255.255.0 {
        pool {
        failover peer "dhcp-failover";
        deny dynamic bootp clients;
        range 10.13.37.200 10.13.37.249;
        option domain-name-servers 10.13.37.5;
        option domain-name "anotherhomepage.loc";
        option routers 10.13.37.254;
        option broadcast-address 10.13.37.255;
group {
use-host-decl-names true ;

# Virtual Machine de tests PXE
host pxemachine {
        hardware ethernet 08:00:27:d3:8f:2d;
        fixed-address 10.13.37.199;
        option host-name "pxemachine";
}
}
}
}

A noter que si vous utilisez un pare-feu sur vos machines, il faudra autoriser les ports 647/tcp et 647/udp qui permettent la communication entre les deux serveurs.

Que se passe-t-il au démarrage et arrêt des serveurs ?

Exemple dans les logs du serveur primaire, après ajout de la configuration, le serveur dhcp primaire est nommé master-dhcp et le secondaire slave-dhcp :

Apr 20 22:28:30 master-dhcp dhcpd: Wrote 0 deleted host decls to leases file.
Apr 20 22:28:30 master-dhcp dhcpd: Wrote 0 new dynamic host decls to leases file.
Apr 20 22:28:30 master-dhcp dhcpd: Wrote 53 leases to leases file.
Apr 20 22:28:31 master-dhcp dhcpd: failover peer dhcp-failover: I move from communications-interrupted to startup
Apr 20 22:28:45 master-dhcp dhcpd: failover peer dhcp-failover: I move from startup to communications-interrupted

Démarrons maintenant DHCPD sur le serveur secondaire, et voyons le résultat sur le serveur primaire :

Apr 20 22:30:29 master-dhcp dhcpd: failover peer dhcp-failover: peer moves from normal to normal
Apr 20 22:30:29 master-dhcp dhcpd: failover peer dhcp-failover: I move from communications-interrupted to normal
Apr 20 22:30:29 master-dhcp dhcpd: pool 80c3200 192.168.6/24 total 50  free 26  backup 24  lts -1

Et regardons les logs du serveur secondaire :

Apr 20 22:30:28 slave-dhcp dhcpd: Wrote 0 deleted host decls to leases file.
Apr 20 22:30:29 slave-dhcp dhcpd: Wrote 0 new dynamic host decls to leases file.
Apr 20 22:30:29 slave-dhcp dhcpd: Wrote 50 leases to leases file.
Apr 20 22:30:29 slave-dhcp dhcpd: failover peer dhcp-failover: I move from normal to startup
Apr 20 22:30:29 slave-dhcp dhcpd: failover peer dhcp-failover: peer moves from normal to communications-interrupted
Apr 20 22:30:29 slave-dhcp dhcpd: failover peer dhcp-failover: I move from startup to normal
Apr 20 22:30:29 slave-dhcp dhcpd: failover peer dhcp-failover: peer moves from communications-interrupted to normal
Apr 20 22:30:29 slave-dhcp dhcpd: pool 7f7ffd8a5150 192.168.6/24 total 50  free 26  backup 24  lts 1

Si je stoppe le serveur primaire, on le voit dans les logs du serveur secondaire :

Apr 20 22:32:08 slave-dhcp dhcpd: peer dhcp-failover: disconnected
Apr 20 22:32:08 slave-dhcp dhcpd: failover peer dhcp-failover: I move from normal to communications-interrupted

Et le redémarrage est aussi visible :

Apr 20 22:32:40 slave-dhcp dhcpd: failover peer dhcp-failover: peer moves from normal to normal
Apr 20 22:32:40 slave-dhcp dhcpd: failover peer dhcp-failover: I move from communications-interrupted to normal
Apr 20 22:32:40 slave-dhcp dhcpd: pool 7f7ffd8a5150 192.168.6/24 total 50  free 26  backup 24  lts 1

Pour finir, cette configuration n'est possible que si les deux serveurs DHCP ont la même version d'ISC DHCP. Heureusement (?), de NetBSD 4.0 jusqu'à NetBSD 5.1 inclus, ISC DHCP est toujours en version 3.0.3 ;-)

Propulsé par Dotclear