18 déc. 2017

CentOS 7 : installation vraiment minimale

Il y a deux ans, j'ai écrit un article sur une installation minimaliste de CentOS 7. Celle-ci avait le mérite d'avoir été réalisée rapidement, et d'être assez satisfaisante. Bref, un bon exemple de la loi de Pareto. Toutefois, je n'en étais pas pleinement satisfait, par exemple à cause de paquets de type firmware, qui peuvent être ajoutés avec le temps lors de nouvelles versions de CentOS, mais aussi parce que j'enlevais pas mal de paquets par rapport au groupe nommé Base. J'ai donc décidé de toucher au groupe Core.

Avertissement : ce genre d'exercice ou d'expérience n'est pas à utiliser "en production" tel quel. Le système réellement basique qui en résulte ne contient pas vraiment grand-chose, et il manque ainsi de nombreux outils de diagnostic ou d'administration qui peuvent s'avérer utile en environnement professionnel. Dans le cas d'une reproduction de ces manipulations avec un système RHEL, il faudra très probablement ajouter de nombreux paquets pour gérer l'enregistrement auprès du RHN (ou d'un Satellite), ainsi que des paquets requis par le support de Red Hat.

Je vois donc cet exercice comme une base, me permettant ensuite d'installer les logiciels que j'estime nécessaires pour le besoin de chaque serveur.

Pourquoi ?

Quel est l'intérêt de faire une installation vraiment minimale ? En fait j'en vois plusieurs :

  • tout d'abord, moins de paquets c'est moins de place occupée, même si la place sur nos disques durs augmente avec le temps, il apparaît pertinent dans le cas de machines virtuelles d'occuper le moins de place possible ;
  • ensuite, car cela peut rendre l'installation plus rapide : moins de paquets à installer, moins de temps à les installer ;
  • enfin, car c'est une recommandation ANSSI, de n'installer que le strict nécessaire, afin de limiter la surface d'attaque ; j'en viens d'ailleurs à passer pour un extrémiste auprès de certains lorsque j'annonce que les pages de manuel n'ont rien à faire sur un système de production...

Un autre point à aborder avant de mettre les mains dans le cambouis : jusqu'où aller ? A quel point peut-on dire que cela est réellement une installation minimale, et à quel point le système qui en résulte est utilisable ? Voici mes critères pour cette installation :

  • le système doit pouvoir démarrer, au moins en machine virtuelle, idéalement en machine physique ;
  • le système doit avoir un accès au réseau filaire fonctionnel avec une adresse IPv4 fixe (le DHCP n'est pas nécessaire) ;
  • le système doit pouvoir installer et mettre à jour des paquets ;
  • le partitionnement est réduit au minimum (/boot, / et swap) et utilise le système de fichiers utilisé par défaut (XFS) ;
  • les fonctions suivantes sont disponibles : serveur SSH, client NTP, pare-feu (firewalld) ;
  • le système peut rester en anglais.

Tout le reste peut être retiré. Tout ? Presque, pour éviter de me casser la tête avec un clavier QWERTY, j'ai décidé d'installer le paquet kbd. Mais cela reste une préférence toute personnelle.

Comment ?

Partir d'une installation "manuelle" et retirer des éléments est contre-productif. Pour arriver à l'objectif, il va falloir automatiser l'installation, grâce à kickstart.

Voici donc le fichier que j'utilise pour cela :

# Kickstart file automatically generated by anaconda.

#version=DEVEL
install
text
reboot
firstboot --disabled
lang en_US.UTF-8
keyboard fr-latin9
firewall --enabled
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
services --enabled sshd,chronyd
timezone --utc Europe/Paris

network --onboot yes --device eth0 --mtu=1500 --bootproto static --ip A.B.C.D --netmask 255.255.255.0 --gateway A.B.C.E --nameserver A.B.C.F --activate --hostname pxemachine.anotherhomepage.loc

rootpw centos
user --name=nils --homedir=/home/nils --uid=1001 --gid=1001 --password=centos --groups=wheel

url --url ftp://X.Y.Z.T/pub/centos/7/os/x86_64/
repo --name=updates --baseurl=ftp://X.Y.Z.T/pub/centos/7/updates/x86_64/

bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
clearpart --all --initlabel
part /boot --asprimary --size=500
part swap --asprimary --size=1024
part / --asprimary --size=1024 --grow

%packages --excludedocs --instLangs=en --nocore
bash
yum
centos-release
passwd
iputils
iproute
systemd
rootfiles
kbd
openssh-server
-bind-license
-dhclient
-kexec-tools
-e2fsprogs-libs
-e2fsprogs
%end

Comme évoqué plus haut, j'ai utilisé quelques arguments de la directive %packages qui me permet de n'installer que le minimum : ainsi, pas de documentation, on reste en anglais, et le groupe Core saute ! Il m'a donc fallu spécifier volontairement les paquets indispensables, comme le noyau, bash ou encore yum. Pour aller encore plus vite, j'ai choisi d'effectuer l'installation en mode texte (je pourrais être plus brutal et remplacer text par cmdline), mais effectuer celle-ci en mode graphique n'a pas d'incidence sur le nombre de paquets installés.

Malgré tout, il m'a fallu retirer volontairement quelques paquets qui me semblent peu utiles pour le moment : pas besoin de gérer des partitions ext2, 3 ou 4, pas besoin de kexec, ni de dhcp.

Le pare-feu reste activé, ainsi que SELinux : ils s'agit de paramètres par défaut assez sains, je ne vais donc pas recommander de les retirer. A noter malgré tout que le système est utilisable sans ces deux éléments.

Résultat

J'ai pu abaisser l'installation à 193 paquets installés. En poussant plus loin (pas de pare-feu, pas de ssh, pas de NTP, pas de kbd), je peux descendre à environ 170. Ma partition principale est alors utilisée à 466Mo, dont 393Mo dans /usr, et 11Mo dans /etc. Jamais je n'ai installé ou démarré un système CentOS aussi vite. Jamais je n'ai eu un système CentOS aussi austère : pas de vim, pas de less, pas de htop, et c'est limite si je dois me considérer heureux de disposer de grep !

D'un autre côté, pas de fioritures : pas de firmware de matériel non utilisé, pas de system-config-*, ni de NetworkManager. Bon, par contre faut pas rêver, systemd est obligatoire ;)

Et la suite ?

A partir de maintenant il est possible de personnaliser plus en avant son installation, et de n'utiliser des outils non pas parce qu'ils sont présents, mais parce qu'on en a besoin. Je ne sais pas encore quelle suite je pourrais donner à ce billet, qui vaille la peine d'être racontée : il n'est probablement pas intéressant de faire des billets en mode "yum install" pour vim, audit, ou quelque autre logiciel. Une possibilité pourrait être de coller aux recommandations ANSSI, mais il existe déjà plein de guides de sécurité pour Linux, non ?

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux !

Crédit photo : badr yousef - Feather.

16 déc. 2017

CentOS 7 : démarrer Anaconda en PXE

Je voulais, à la base, écrire un billet sur une installation particulière de CentOS 7. J'ai donc voulu utiliser mon "infrastructure de boot PXE" à la maison et commencer à gribouiller un kickstart, mais quand j'ai démarré ma machine virtuelle sur le réseau, le drame :

dracut-initqueue[584]: Warning: Could not boot.
dracut-initqueue[584]: Warning: /dev/root does not exist

Ma configuration pxelinux à ce moment est la suivante :

LABEL centos7amd64
        MENU LABEL Install CentOS 7 x86_64 (interactive)
        KERNEL pub/centos/7/os/x86_64/isolinux/vmlinuz
        APPEND initrd=pub/centos/7/os/x86_64/isolinux/initrd.img ip=dhcp inst.repo=ftp://X.Y.Z.T/pub/centos/7/os/x86_64/ inst.ks=ftp://X.Y.Z.T/pub/ks/c7_x86_64.cfg

Et bien entendu, le même type de configuration fonctionne en CentOS 6.

Ce message d'erreur arrive à des moments et des types d'installation parfois différents, de ce que j'ai lu. Et la résolution n'est pas toujours la même. Dans mon cas, il a fallu que j'ajoute le chemin vers un fichier squashfs, qui doit contenir l'OS minimal pour démarrer Anaconda je crois. Cela donne donc la configuration suivante :

LABEL centos7amd64
        MENU LABEL Install CentOS 7 x86_64 (interactive)
        KERNEL pub/centos/7/os/x86_64/isolinux/vmlinuz
        APPEND initrd=pub/centos/7/os/x86_64/isolinux/initrd.img root=live:ftp://X.Y.Z.T/pub/centos/7/os/x86_64/LiveOS/squashfs.img ip=dhcp inst.repo=ftp://X.Y.Z.T/pub/centos/7/os/x86_64/ inst.ks=ftp://X.Y.Z.T/pub/ks/c7_x86_64.cfg

J'espère que cela rendra service à d'autres !

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux ! Si en plus vous avez des remarques, ou des propositions d'améliorations, n'hésitez pas : les commentaires sont là pour ça !

Crédit photo : Mattias - Car Glass 03.

27 juin 2017

CentOS 7 : désactiver firewalld et réactiver iptables

toolsEn plus de systemd, RHEL 7 et CentOS 7 disposent d'une nouvelle interface de pare-feu : firewalld. Bien qu'il fasse plutôt bien le boulot, je me suis trouvé dans des cas où j'avais du mal à lui faire faire ce que je voulais. En fait dès l'instant où j'ai commencé à jouer avec des interfaces tun, des zones et de la retransmission de paquets, j'ai commencé à avoir des difficultés. En attendant de les résoudre, j'ai noté que je pouvais revenir au fonctionnement précédent, et piloter iptables directement.

Désactivation de firewalld

Commençons par arrêter firewalld, et s'assurer qu'il est bien coupé :

[root@test ~]# systemctl stop firewalld.service
[root@test ~]# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

Jun 27 10:27:00 test.anotherhomepage.org systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 27 10:27:00 test.anotherhomepage.org systemd[1]: Started firewalld - dynamic firewall daemon.
Jun 27 10:27:25 test.anotherhomepage.org systemd[1]: Stopping firewalld - dynamic firewall daemon...
Jun 27 10:27:25 test.anotherhomepage.org systemd[1]: Stopped firewalld - dynamic firewall daemon.

Bien sûr, cela veut dire qu'à partir de maintenant, la machine n'est plus protégée par le pare-feu.

Ensuite, on désactive son démarrage automatique :

[root@test ~]# systemctl disable firewalld.service

Si vraiment on ne souhaite plus pouvoir démarrer firewalld par accident, on peut le masquer :

[root@test ~]# systemctl mask firewalld.service
Created symlink from /etc/systemd/system/firewalld.service to /dev/null.

Maintenant c'est pas tout, mais faut remettre un pare-feu.

Activation d'iptables

Pour activer iptables, c'est très simple, commençons par installer le paquet "iptables-services" :

[root@test ~]# yum -y install iptables-services
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.imt-systems.com
 * extras: mirror.netcologne.de
 * updates: mirror.ratiokontakt.de
Resolving Dependencies
--> Running transaction check
---> Package iptables-services.x86_64 0:1.4.21-17.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================
 Package                                                         Arch                                                 Version                                                       Repository                                          Size
=============================================================================================================================================================================================================================================
Installing:
 iptables-services                                               x86_64                                               1.4.21-17.el7                                                 base                                                50 k

Transaction Summary
=============================================================================================================================================================================================================================================
Install  1 Package

Total download size: 50 k
Installed size: 24 k
Downloading packages:
iptables-services-1.4.21-17.el7.x86_64.rpm                                                                                                                                                                            |  50 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : iptables-services-1.4.21-17.el7.x86_64                                                                                                                                                                                    1/1
  Verifying  : iptables-services-1.4.21-17.el7.x86_64                                                                                                                                                                                    1/1

Installed:
  iptables-services.x86_64 0:1.4.21-17.el7

Complete!

Ensuite, on l'active dans systemd :

[root@test ~]# systemctl enable iptables
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.

On peut alors le lancer :

[root@test ~]# systemctl start iptables

Comme pour RHEL 6 et CentOS 6, la configuration se trouve dans le fichier /etc/sysconfig/iptables, et dispose d'un jeu de règles n'ouvrant la voie qu'au ping et à SSH. La machine est, à partir de cet instant, de nouveau protégée par un pare-feu.

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux ! Si en plus vous avez des remarques, ou des propositions d'améliorations, n'hésitez pas : les commentaires sont là pour ça !

Crédit photo : velacreations - tools.

20 juin 2011

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 !

17 janv. 2011

Vérifications de permissions - suite

Introduction : les astuces de ce billet sont extraites du document Guide to the Secure Configuration of Red Hat Enterprise Linux 5 édité par la NSA. Vous pouvez télécharger le document au format PDF dans son intégralité sur leur site. Cette introduction me permet d'être en conformité avec leur notice de Copyright.

Après les droits des répertoires et le sticky bit, amusons-nous un peu avec SUID et SGID : un fichier possédant l'attribut SUID ou SGID permet d'être lancé avec les droits de l'utilisateur ou du groupe qui a été placé, généralement root. Ainsi, le programme at, permettant de lancer une tâche à un moment donné, est accessible aux utilisateurs classiques alors que son fonctionnement nécessite des droits plus élevés. Ceci peut s'avérer risqué car si un programme SUID root possède une faille, celle-ci peut être exploitée avec les droits de root, même si l'attaquant n'a pas les droits.

Comme pour le sticky bit, commençons par vérifier notre environnement :

root@orgrimmar:~# whoami
root
root@orgrimmar:~# cat /etc/redhat-release 
CentOS release 5.5 (Final)

Recherchons maintenant tous les fichiers possédant un SUID ou un SGID :

root@orgrimmar:~# find / \( -perm -4000 -o -perm -2000 \) -type f -print
/bin/ping6
/bin/umount
/bin/ping
/bin/mount
/bin/su
/lib64/dbus-1/dbus-daemon-launch-helper
/usr/bin/wall
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/sudoedit
/usr/bin/chsh
/usr/bin/write
/usr/bin/at
/usr/bin/chage
/usr/bin/crontab
/usr/bin/ssh-agent
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/gpasswd
/usr/bin/locate
/usr/bin/screen
/usr/libexec/openssh/ssh-keysign
/usr/libexec/libvirt_proxy
/usr/libexec/utempter/utempter
/usr/kerberos/bin/ksu
/usr/sbin/userhelper
/usr/sbin/postqueue
/usr/sbin/postdrop
/usr/sbin/usernetctl
/usr/sbin/ccreds_validate
/sbin/netreport
/sbin/mount.nfs4
/sbin/umount.nfs4
/sbin/umount.nfs
/sbin/mount.nfs
/sbin/unix_chkpwd
/sbin/pam_timestamp_check
find: /proc/9859/task/9859/fd/4: Aucun fichier ou répertoire de ce type
find: /proc/9859/task/9859/fd/4: Aucun fichier ou répertoire de ce type
find: /proc/9859/fd/4: Aucun fichier ou répertoire de ce type
find: /proc/9859/fd/4: Aucun fichier ou répertoire de ce type
root@orgrimmar:~# 

Sur le coup, voir autant de lignes peut paraître effrayant, mais si on y regarde de plus près, on peut comprendre que 99% des fichiers indiqués aient besoin du SUID. Le seul qui m'inquiète, c'est screen. Je vais donc regarder sur une autre machine, bien différente cette fois-ci :

nils@tomb:~$ uname -sr
NetBSD 5.0.2
nils@tomb:~$ ls -hl /usr/pkg/bin/scree*
lrwxr-xr-x  1 root  wheel   12B Jul 11 11:23 /usr/pkg/bin/screen@ -> screen-4.0.3
-r-s--x--x  1 root  wheel  279K Jul 11 11:23 /usr/pkg/bin/screen-4.0.3*

On voit que screen sur ma machine NetBSD a aussi un bit SUID. C'est bon, je peux aller me coucher l'esprit tranquille :) Mais avant, revenons à notre serveur CentOS, et comme pour l'affaire du sticky bit, simulons un programme dont le SUID a été ajouté inutilement :

root@orgrimmar:~# cat > testbin
#!/bin/bash
echo -n "Je suis un programme SUID de test"
exit 0
root@orgrimmar:~# chmod -v +x testbin 
Le mode d'accès de `testbin' a été modifié à 0755 (rwxr-xr-x).
root@orgrimmar:~# ls -hl testbin 
-rwxr-xr-x 1 root root 63 déc 31 00:44 testbin*
root@orgrimmar:~# chmod -v +s testbin 
Le mode d'accès de `testbin' a été modifié à 6755 (rwsr-sr-x).
root@orgrimmar:~# ls -hl testbin 
-rwsr-sr-x 1 root root 63 déc 31 00:44 testbin*

Relançons notre recherche :

root@orgrimmar:~# find /root \( -perm -4000 -o -perm -2000 \) -type f -print
/root/testbin

Supprimons maintenant le SUID et relançons la recherche :

root@orgrimmar:~# chmod -v -s testbin 
Le mode d'accès de `testbin' a été modifié à 0755 (rwxr-xr-x).
root@orgrimmar:~# find /root \( -perm -4000 -o -perm -2000 \) -type f -print
root@orgrimmar:~# 

Et voilà, nous sommes tranquille :)

Que faire si j'ai un doute sur un programme ? Plusieurs possibilités : s'il s'agit d'un programme qui est fourni par les paquets de votre distribution, on peut toujours aller vérifier sur d'autres machines, dont l'OS ou la distribution peut différer (comme je l'ai fait avec screen); un même programme nécessitant le SUID sur 2 OS différents peut légèrement rassurer. Si le logiciel est libre (exemple : GNU screen :D), on peut aussi aller chercher dans les fichiers de création du paquet binaire, pour les RPM il suffit de chercher le SRPM du logiciel et de l'installer sur une machine de test. Ensuite, on regarde le contenu du fichier .spec qui sert à la création de ce paquet : en effet, ces fichiers contiennent la liste et les droits des fichiers et répertoires du paquet que l'on veut compiler :) Si un .spec n'indique pas que le programme est SUID, alors il est temps de s'inquiéter !

Propulsé par Dotclear