Mettre à jour un serveur Linux automatiquement
L’une des composantes de base de la sécurité informatique, c’est d’avoir son parc à jour avec les dernières versions de logiciels afin de profiter des correctifs de sécurité. Si dans le monde de l’entreprise il existe un outillage intégré ou conçu pour maintenir un parc entier, dans le cas d’un hébergement loisir ou à titre personnel cette tâche peut s’avérer peu intéressante et répétitive.
Voici quelques scripts pour faciliter la vie. A noter que ce billet concerne principalement la famille Red Hat avec des distributions comme CentOS ou encore Rocky Linux. Certains outils proposés ne seront peut être pas disponibles sur de la Debian ou équivalent.
Automatiser la mise à jour des paquets
Pour cela rien de bien compliqué, il suffit de faire appel au gestionnaire de paquets de la distribution.
Dans la famille Red Hat, c’est dnf
qui se charge de maintenir le système à jour. Vous pouvez donc le placer dans un petit script shell qui se chargera d’appliquer automatiquement les nouvelles versions.
Exemple pour tout mettre à jour sans se poser de questions :
$ dnf update -y
Dans le cas où vous souhaitez éviter de mettre à jour certains paquets en automatique, vous pouvez utiliser les commandes d’exclusion, voire désactiver le dépôt du paquet si cela est possible.
$ dnf update -y --disablerepo <repo-a-ignorer>
$ dnf update -y --exclude <paquet-a-ignorer>
Redémarrer le système si nécessaire
Les administrateurs de système Linux le savent bien : une distribution Linux n’a pas besoin d’être redémarrée tous les 5 minutes au moindre service qui se met à jour. Cependant, quand on veut le faire de manière automatisé on se demande alors dans quel cas faut-il redémarrer ?
Généralement, Linux demande un redémarrage lorsque le Kernel a été mis à jour pour pouvoir démarrer sur le nouveau. On pourrait appliquer une consigne bête et méchante de reboot
juste après la commande dnf update -y
, mais un utilitaire disponible avec le gestionnaire de paquets dnf
rend la chose plus intelligente : needs-restarting
.
Si la commande needs-restarting
n’est pas disponible, installez-la avec le paquet dnf-utils
(ou yum-utils
).
La commande permet d’afficher pas mal d’informations, mais l’argument -r
nous suffira dans le cas présent :
## quand cela n'est pas requis
$ needs-restarting
No core libraries or services have been updated since boot-up.
Reboot should not be necessary.
## quand cela est requis
Core libraries or services have been updated since boot-up:
* kernel
Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943
Cerise sur le gâteau, la commande needs-restarting -r
renvoie un code retour 1 si le redémarrage est requis, et zéro si ce n’est pas le cas. Avec un petit script rapide, on peut donc le détecter à la suite de notre mise à jour système.
#!/usr/bin/env bash
## lance dnf update
/usr/bin/dnf update -y
## verifie si besoin de redémarrer
## si needs-restarting renvoie 0, pas besoin.
## Sinon, on redémarre.
/usr/bin/needs-restarting -r && echo "Nope" || systemctl reboot
Petit rappel si vous n’êtes pas familier de ce genre de syntaxe :
- L’opérateur
&&
(AND) signifie que la seconde commande sera lancée uniquement si la première est un succès - L’opérateur
||
(OR) signifie que la troisième commande sera lancée uniquement si la première a échoué
Cette syntaxe est équivalente à un IF...THEN...ELSE
.
Il ne reste plus qu’à planifier ça dans l’ordonnanceur du système. Dans /etc/cron.d
nous créons un fichier system-update
qui fera exécuter notre script. Ici, il est planifié pour se lancer tous les lundi matin à 2h, adaptez-le comme bon vous semble.
00 02 * * 1 root /usr/local/bin/system-update.sh
Réactiver des containers au démarrage du système
Ayant des containers lancés avec podman
, il m’est nécessaire de pouvoir les ravoir au démarrage.
Containers unitaires
La bonne nouvelle est que podman
est capable de générer des scripts de services systemd
pour un container. En lançant la commande suivante sur un container démarré :
podman generate systemd --new --name mycontainer
Retournera la définition d’un service prête à l’emploi. Pour l’utiliser, il suffit de l’écrire dans un fichier service :
podman generate systemd --new --name mycontainer >> /etc/systemd/system/mycontainer.service
A partir de là, il suffit d’activer le service au démarrage avec systemctl enable mycontainer.service
Containers gérés par podman-compose
La précédente commande ne fonctionne pas avec podman-compose
car par défaut, il supprime les containers à l’arrêt donc il risque de ne pas réussir à les relancer.
Le fichier service suivant permet de lancer un ensemble avec podman-compose
:
[Unit]
Description=MyContainer
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/podman-compose -f /path/to/docker-compose.yml up -d
ExecStop=/usr/bin/podman-compose -f /path/to/docker-compose.yml down
[Install]
WantedBy=multi-user.target
De la même façon, activez le service pour que systemd le lance au démarrage.
Lancer certains scripts au démarrage du système
Ayant quelques petits scripts de maintenance diverses, je n’ai pas non plus eu l’envie d’en faire des services pilotés par systemd. Ceux-ci sont des bêtes scripts shell fonctionnant en arrière-plan. Si vous avez un besoin similaire, il suffit de les planifier dans la crontab de l’utilisateur (ou dans /etc/cron.d
) de la manière suivante :
@reboot /path/to/script.sh
Et voilà !
J’espère que ces petites astuces pour seront utiles. N’hésitez-pas à en partager d’autres ou à faire vos remarques via la section contact !