23 avr. 2018

CentOS 7 : installation vraiment minimale - errata

Dans un billet précédent, j'avais réalisé une installation vraiment minimale de CentOS 7. Si globalement le cahier des charges était respecté, je me suis heurté à quelques petites déconvenues, je me suis donc dit qu'un billet sous forme d'errata ne serait pas de trop.

SELinux

Bon, d'accord, SELinux est probablement l'un des composants de CentOS, Fedora et RHEL le plus détesté (ou est-ce systemd ?), car nombreux sont encore les tutoriaux qui commencent par demander de désactiver celui-ci (à tort). Bref, si comme moi vous vous attendez à ce que votre système minimaliste soit paramétré en "Enforcing" (après tout c'est marqué dans le kickstart), pas de chance. Tapez 20 fois la commande setenforce Enforcing si vous voulez, la réponse sera la même : non.

Pourquoi ? Parce que votre serviteur, en allant tailler dans les paquets à la tronçonneuse, s'est débarrassé des politiques SELinux. Sans politique, cela fonctionne moins bien. Comment on les obtient ? En installant deux paquets : selinux-policy et selinux-policy-targeted. N'envisagez pas un seul instant de n'installer que le premier : le système se bloquera au démarrage.

scp

Quand on est sur une machine serveur, il n'est a priori pas nécessaire d'installer un quelconque client, sauf cas exceptionnel et identifié. En voici un : sans installer le paquet openssh-clients sur mon serveur minimaliste, je ne peux pas faire de scp vers celui-ci. Je suppose que le binaire scp doit être appelé à un moment quelconque côté serveur, mais toujours est-il que sans, bein ça ne fonctionne pas.

Perl et la locale

Celui-ci est assez tordu et concerne les paramétrages de langue. Il se trouve qu'après avoir installé Perl sur ce serveur minimaliste, j'ai voulu lancer un script utilisant ce langage. J'ai eu droit, durant les scripts, à un message de ce genre :

perl: warning: Falling back to the standard locale ("C").

Alors le pourquoi exact, je ne suis toujours pas certain, je suspecte qu'il manque un paquet et que celui-ci (toujours pas identifié) fait un paramétrage particulier, toujours est-il que je me voyais mal modifier ma configuration OpenSSH pour aller jouer avec les variables d'environnement exportées par ce dernier. J'ai préféré finalement ajouter deux petites lignes à /etc/environment :

LANG=en_US.utf-8
LC_ALL=en_US.utf-8

Cela force le système en anglais américain, en UTF-8.

Les logs

Bon alors celle-là, elle est fantastique : rsyslog n'est du coup plus installé par défaut et certains logiciels n'envoient plus de log, comme OpenSSH : j'ai voulu diagnostiquer des erreurs de connexion SSH et je n'avais pas de fichier /var/log/secure ! En effet, par défaut OpenSSH sous CentOS utilise le protocole syslog pour fournir ses logs. A noter aussi que logrotate manquait, ce qui aurait pu s'avérer plus dramatique au bout de quelques mois sur une machine de production.

C'est tout ?

Ce n'est probablement que le début. Je me rends compte à l'usage qu'il me manque pas mal de choses de mon petit confort (vim, less, tmux...). Un autre paquet que je n'ai pas encore réinstallé est NetworkManager, à voir si cela devient vraiment pratique.

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

Crédit photo : Adam Sherez - Same but different.

22 déc. 2017

NetBSD : haute disponibilité avec CARP

Turner Twins, acrobats, 1937 / by Sam HoodNetBSD dispose depuis la version 4.0 d'une implémentation du protocole CARP. Il s'agit d'un protocole, à l'origine prévu pour les routeurs, permettant à un groupe de machines de disposer d'une adresse IP flottante. Si la machine principale venait à être indisponible, une machine secondaire peut alors prendre le relai. CARP permet donc de mettre en place de la haute disponibilité.

Je me suis amusé à mettre en place une configuration CARP sur les deux serveurs DNS de mon LAN. Pourquoi ? J'ai remarqué que bien souvent, selon les OS, quand on spécifie deux serveurs DNS dans les paramètres réseau, même si la redondance est là, on peut sentir un ralentissement :

  • le client va faire du round-robin et donc régulièrement des requêtes vont échouer ;
  • le client va d'abord s'adresser au premier serveur DNS de sa liste, et si celui-ci est indisponible, il attendra un timeout avant de passer au suivant.

Il y a probablement d'autres moyens d'adresser ces problèmes, mais cela m'a fourni une excuse de jouer avec CARP, c'est le plus important :)

CARP se présente en fait sous forme d'une carte réseau fictive dont le pilote est disponible dans le noyau. Quand je dis disponible, c'est qu'en théorie l'option est compilée dans le noyau GENERIC, mais cela n'est pas forcément le cas sur toutes les plateformes. Ainsi, j'ai dû recompiler un noyau contenant pseudo-device carp.

Une fois que CARP est bien disponible, il suffit tout simplement de créer une nouvelle interface réseau sur chaque machine. La machine principale aura un poids plus fort que la machine secondaire, et portera l'adresse IP flottante en temps normal.

Sur la machine principale :

# ifconfig carp0 create
# ifconfig carp0 vhid 101 pass motdepassehalakon 10.13.37.42 netmask 255.255.255.0

Sur la machine secondaire :

# ifconfig carp0 create
# ifconfig carp0 vhid 100 pass motdepassehalakon 10.13.37.42 netmask 255.255.255.0

On peut alors vérifier que l'adresse IP flottante est joignable. A noter la présence d'un mot de passe permettant de limiter les cas de "vol d'IP flottante", ici positionné à "motdepassehalakon"

Pour que cela tienne au redémarrage, il faut bien entendu que la configuration soit enregistrée quelque part. En fait, en terme de configuration, il s'agit tout simplement de la configuration de la carte réseau carp0, ici sur la machine principale :

$ cat /etc/ifconfig.carp0
create
up
vhid 101 pass motdepassehalakon 10.13.37.42 255.255.255.0

Ensuite sur la machine secondaire :

$ cat /etc/ifconfig.carp0
create
up
vhid 100 pass motdepassehalakon 10.13.37.42 255.255.255.0

Maintenant, il ne reste plus qu'à tester... en débranchant la prise !

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

Crédit photo : State Library of New South Wales - Turner Twins, acrobats, 1937 / by Sam Hood.

21 déc. 2017

rsnpashot, le robot de sauvegarde

Suite au commentaire de Xate dans un récent billet, aujourd'hui un billet sur rsnapshot, un logiciel de sauvegarde incrémentale basé sur rsync. Si j'en fais un billet, c'est tout simplement car c'est ce que j'ai mis en place pour sauvegarder mon infrastructure.

J'avoue ne pas trop savoir quoi raconter sur ce logiciel, car de nombreuses documentations existent déjà, quasiment pour chaque distribution :

Je vais donc parler de quelques points de ma configuration en particulier. La première particularité de celle-ci est que j'ai choisi d'installer rsnapshot sur une machine (en fait une jail FreeBSD sur mon NAS FreeNAS) et de l'utiliser en mode "robot de sauvegarde", c'est-à-dire qu'il va se connecter sur toutes les machines à sauvegarder via SSH pour effectuer les sauvegardes. J'y vois l'avantage que je n'ai qu'une seule configuration à modifier, et un utilisateur à configurer sur mes serveurs (accompagné, bien entendu, de sa configuration sudo et de la clé SSH).

Par exemple, pour la sauvegarde du Raspberry Pi qui fait des bulk builds :

backup rsnapshot@netpi2:/etc/                                          netpi2/         +rsync_long_args=--rsync-path='/usr/pkg/bin/sudo /usr/pkg/bin/rsync'
backup rsnapshot@netpi2:/usr/pkg/etc/                                  netpi2/         +rsync_long_args=--rsync-path='/usr/pkg/bin/sudo /usr/pkg/bin/rsync'
backup rsnapshot@netpi2:/var/log/                                      netpi2/         +rsync_long_args=--rsync-path='/usr/pkg/bin/sudo /usr/pkg/bin/rsync'
backup rsnapshot@netpi2:/srv/sandbox/pkgsrc-current/usr/pbulk/etc/     netpi2/         +rsync_long_args=--rsync-path='/usr/pkg/bin/sudo /usr/pkg/bin/rsync'

On peut aussi noter que j'ai choisi d'ajouter des options à rsync selon mes machines, car celles-ci peuvent être de différents OS, ce qui fait que rsync et sudo ne se trouvent pas toujours au même endroit.

Du côté de la rétention et des intervalles de sauvegarde, j'ai fait très simple :

  • une sauvegarde par jour (daily);
  • 370 jours de rétention.

370 jours peut sembler un peu abusé, mais la force de rsnapshot est dans son utilisation des liens (hardlinks) combinée à celle de rsync, qui rend les sauvegardes rapides, mais aussi moins consommatrices en espace disque car dédupliquées. Par exemple pour le serveur web de ce blog :

# du -csh daily.0/vhost2/ daily.1/vhost2/                                                                                                                                                                       
 17G    daily.0/vhost2/
2.3G    daily.1/vhost2/
 19G    total

La restauration se fait très simplement aussi, puisqu'il s'agit de fichiers tout ce qu'il y a de plus classiques, ou de liens.

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

Crédit photo : Ritva Pirinen - Spare Parts.

19 déc. 2017

sslh : faire cohabiter SSH et HTTPS

Sur un système Unix libre, il n'est pas possible de faire écouter deux services réseau sur un même port. sslh est un logiciel qui permet d'écouter sur un port et redirige le trafic vers un service, selon les premiers octets écoutés. Il devient ainsi possible, par exemple, de partager son port 443 entre un serveur SSH et un serveur HTTPS.

La configuration est très simple, voici ce que j'ai mis en place sur un Raspberry Pi fonctionnant sous NetBSD :

verbose: false;
foreground: false;
inetd: false;
numeric: false;
transparent: false;
timeout: 2;
user: "nobody";
pidfile: "/var/run/sslh.pid";

listen:
(
    { host: "netpi3"; port: "443"; }
);

protocols:
(
     { name: "ssh"; service: "ssh"; host: "netpi3"; port: "22"; probe: "builtin"; },
     { name: "ssl"; host: "netpi3"; port: "8443"; probe: "builtin"; }
);

Avec cette configuration, sslh redirige le trafic SSH vers netpi3 sur le port 443 vers netpi3 sur le port 22 (j'aurais pû mettre localhost), et redirige aussi le trafic HTTPS vers netpi3 sur le port 443 vers netpi3 sur le port 8443 (j'aurais aussi pû mettre localhost). Un inconvénient à ce système, c'est que le trafic vu par le serveur SSH ou par le serveur HTTPS est vu comme provenant de l'IP hébergeant sslh. Cela peut s'avérer gênant dans la configuration d'un pare-feu ou d'autres outils comme Fail2ban. Il existe toutefois une configuration pour ce dernier, et dans le cas de Linux et de FreeBSD, sslh gère une fonctionnalité de proxy transparent (voir la documentation).

A noter que HTTPS et SSH ne sont pas les seuls protocoles pris en charge. Il est possible de faire pareil avec XMPP et OpenVPN, par exemple.

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

Crédit photo : David Verbrugge - 20160214_183534.

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.

Propulsé par Dotclear