FreshRSS

🔒
❌ À propos de FreshRSS
Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Comment installer les VMware Tools sur Debian 10 ?

28 mai 2021 à 10:45

I. Présentation

Lorsque l'on déploie une machine virtuelle sur un environnement VMware, il convient d'installer les VMware Tools au sein de la machine virtuelle, qu'elle tourne sous Windows ou Linux. Dans ce tutoriel, je vais prendre une machine virtuelle sous Debian 10, sur un ESX de VMware, et vous expliquer comment installer les VMware Tools en ligne de commande. La procédure est similaire sur d'autres distributions Linux.

L'installation des VMware Tools est importante pour bénéficier de certaines fonctionnalités, mais aussi pour optimiser les interactions entre la machine virtuelle et l'hyperviseur VMware. Que ce soit un serveur VMware ESX ou simplement VMware Workstation / Player.

  • Synchronisation de l'heure entre l'hyperviseur et la VM
  • Éteindre proprement la VM directement à partir de l'hyperviseur
  • Glisser-déposer et Copier-coller entre la VM et l'hôte physique (dans le cas d'une installation en mode graphique de Debian)
  • Etc.

Nous verrons dans ce tutoriel qu'il y a deux façons d'installer les outils VMware dans une VM Linux : VMware Tools ou Open-VM Tools.

II. Installer les VMware Tools sous Debian

A. Monter les sources VMware Tools dans la VM

Dans le système d'exploitation invité, nous devons monter le "CD" qui contient les sources d'installation des VMware Tools. Pour cela, effectuez un clic droit sur la VM, puis : SE invité > Installer VMware Tools.

La suite de l'installation s'effectue en ligne de commande sur le serveur : soit en console directement, soit au travers d'une connexion SSH.

B. Réaliser l'installation des VMware Tools

On va devoir monter notre CD d'installation sur la machine, ce qui nécessite de créer un point de montage. Pour les commandes à venir, je pars du principe que je suis connecté avec un compte "root" sur la machine, mais sinon ajoutez "sudo" devant les commandes.

mkdir /mnt/cdrom

Maintenant que le point de montage "cdrom" est créé,  on va lui associer le périphérique "cdrom", comme ceci :

mount /dev/cdrom /mnt/cdrom

Vous devriez obtenir le retour suivant dans la console :

mount: /mnt/cdrom: Attention: périphérique protégé en écriture, monté en lecture seule.

À partir de ce moment-là, le contenu des VMware Tools est accessible dans le dossier "/mnt/cdrom". Maintenant, on va se positionner dans le dossier "/tmp" pour extraire à cet emplacement le contenu de l'archive TAR.GZ correspondante aux VMware Tools.

cd /tmp

Ensuite, avec la commande "tar" on va décompresser le contenu du fichier "VMwareTools-10.3.22-15902021.tar.gz". Attention, le nom du fichier peut varier en fonction de la version de votre hyperviseur VMware.

tar xzpf /mnt/cdrom/VMwareTools-10.3.22-15902021.tar.gz

Sinon, on peut utiliser la commande suivante qui fonctionnera peu importe la version grâce au wildcard :

tar xzpf /mnt/cdrom/VMwareTools-*.tar.gz

Les sources d'installation sont désormais copiées en local sur notre machine virtuelle : on peut démonter le point de montage "/mnt/cdrom" car nous n'avons plus besoin du CD.

umount /mnt/cdrom

Il ne reste plus qu'à exécuter le script Perl d'installation. Il se situe dans le dossier "vmware-tools-distrib", ce dernier étant lui-même dans "/tmp" (dossier dans lequel nous sommes actuellement).

cd vmware-tools-distrib

Une fois dans le dossier, exécutez le script d'installation :

./vmware-install.pl

Validez l'installation en indiquant "yes" et appuyez sur "Entrée". Nous reviendrons en fin d'article sur le message qui s'affiche au sujet du paquet "open-vm-tools".

VMware Tools Debian 10

Ensuite, il y a une série de questions : dans la majorité des cas, appuyez simplement sur "Entrée" pour valider, sauf si vous souhaitez répondre autre chose que la valeur par défaut. Il n'est pas nécessaire d'activer toutes les fonctionnalités proposées par les VMware Tools.

L'installation doit s'effectuer sans encombre sur votre machine ?

C. Supprimer les sources

Pour finir le travail, nous allons supprimer le dossier avec les sources des VMware Tools :

rm vmware-tools-distrib/ -Rf

Terminez par un redémarrage de votre machine pour finaliser l'installation.

IV. L'installation avec Open-VM Tools

Open-VM Tools (OVT), c'est l'équivalent des VMware Tools, mais sous licence open source, supportée par VMware. Il s'agit d'une alternative stable qui offrira les mêmes fonctionnalités, mais son fonctionnement est différent, notamment pour les mises à jour.

Pour mettre à jour les VMware Tools, il faut passer par l'hyperviseur directement comme nous avons pu le voir, et on peut gérer les mises à jour avec vSphere Update Manager. En comparaison, pour mettre à jour Open-VM Tools, il faut mettre à jour le paquet dans la VM directement : comme n'importe quel autre paquet.

L'installation est très simple puisque ce paquet est disponible dans les dépôts officiels de Debian (et d'autres distributions). Il suffit d'exécuter la commande suivante :

apt-get install open-vm-tools

Dans le cas où vous utilisez un système avec une interface graphique, utilisez plutôt cette commande pour installer un paquet supplémentaire :

apt-get install open-vm-tools open-vm-tools-desktop

Ensuite, on peut vérifier la version installée sur la machine avec la commande suivante :

/usr/bin/vmware-toolbox-cmd -v

Par exemple :

10.3.22.561 (build-15902021)

N'oubliez pas de redémarrer à la fin de l'installation, comme avec les VMware Tools officielles.

The post Comment installer les VMware Tools sur Debian 10 ? first appeared on IT-Connect.

Comment ajouter un nouvel utilisateur « sudo » sous Linux ?

21 mai 2021 à 13:00

I. Présentation

Sur votre machine Linux, si vous avez besoin qu'un utilisateur standard dispose des droits d'administration de cette même machine par l'intermédiaire de la commande "sudo", vous allez avoir besoin de créer l'utilisateur et de l'ajouter au groupe "sudo".

Dans ce tutoriel, nous allons voir comment créer un utilisateur et l'ajouter au groupe "sudo", ce qui permettra de lui donner des droits d'administration sur la machine.

Pour découvrir plus en détail la commande "sudo" et la configuration du fichier sudoers (recommandé pour déléguer les droits), voici le tutoriel et la vidéo disponible sur IT-Connect :

⭐Linux - Commande sudo et configuration du fichier sudoers

II. Créer un utilisateur sudo

Pour les commandes qui vont suivre, si vous êtes connecté avec un autre utilisateur que "root" mais qui a des droits d'administration, pensez à ajouter "sudo" devant les commandes.

A. Créer l'utilisateur sur la machine

Pour créer un nouvel utilisateur nommé "flo" et qui doit être notre futur utilisateur "sudo", on utilise simplement la commande suivante :

adduser flo

Cela va permet de créer un nouvel utilisateur "flo", un groupe "flo" et un répertoire personnel "/home/flo". Il faudra saisir un mot de passe pour cet utilisateur : je vous recommande d'utiliser un mot de passe sécurisé/complexe, d'autant plus que cet utilisateur aura des droits d'administration sur la machine.

créer utilisateur sudo debian

B. Ajouter un utilisateur au groupe sudo

Maintenant, nous allons ajouter l'utilisateur "flo" au groupe "sudo". Pour cela, on utilise la commande habituelle : usermod. Ce qui donne :

usermod -aG sudo flo

Petite précision : l'option -aG permet d'ajouter l'utilisateur "flo" au groupe "sudo", mais l'aurez deviné ! On peut vérifier que le résultat de notre commande est correct en regardant de quels groupes est membre l'utilisateur "flo" :

groups flo

C. Utiliser le nouveau compte sudo

Techniquement notre compte est prêt ! Il ne reste plus qu'à en profiter et à l'utiliser avec précautions ! À partir de la session courante, pour basculer sur l'utilisateur "flo", on va utiliser la commande suivante :

su - flo

Voilà, vous êtes dans votre terminal connecté avec ce nouveau compte, vous allez pouvoir utiliser la commande sudo. Je vous recommande vivement de prendre connaissance des possibilités offertes par le fichier de configuration sudoers, avant de partir sur un compte "sudo" avec tous les droits.

The post Comment ajouter un nouvel utilisateur « sudo » sous Linux ? first appeared on IT-Connect.

Linux – Afficher la branche Git dans le prompt

17 mai 2021 à 13:00

I. Présentation

Lorsqu’on utilise Git au quotidien pour versionner son code / ses scripts, on est souvent amené à créer des branches pour tester un bout de code, corriger un bug, le tout sans impacter le script actuel qui tourne en production.

Et pour éviter un carnage en production, nous devons redoubler de vigilance, et nous assurer de bien être sur la branche de test, et non celle de production.

Il existe des commandes Git pour vérifier cela, et pour naviguer d’une branche à l’autre. Mais on peut vite s’y perdre.

Et si je vous disais qu’il est possible de manipuler le prompt de votre terminal Linux pour afficher le nom de la branche de votre repository Git sur laquelle vous travaillez ?

Note : Si vous ne voyez pas encore l’intérêt en tant que sysadmin d’utiliser Git pour gérer vos scripts et la configuration de vos serveurs, laissez-moi vous convaincre du contraire : Git c’est l’avenir du sysadmin. Ça devient même un nouveau standard dont vous ne pouvez plus passer à côté.

II. Prérequis

Afin de suivre ce tutoriel, vous devez respecter les prérequis suivants :

  • Avoir une distribution Linux fonctionnelle, que ce soit une machine virtuelle, ou une distribution sous WSL
  • Git installé
  • Avoir créé votre premier repository Git

III. Comment modifier le prompt bash

Au lancement de votre terminal Linux, vous devriez avoir par défaut un prompt affichant :

  • Votre nom d’utilisateur
  • Le hostname de votre machine
  • Le répertoire dans lequel vous vous trouvez
  • Un $, indiquant que votre compte n’est pas un compte root

Le contenu de ce prompt est stocké dans une variable nommée PS1, pour Prompt String 1.

Vous pouvez d’ailleurs afficher le contenu de cette variable via la commande :

echo $PS1

Bon, on est d’accord, vu comme ça, c’est un peu moins parlant 😉

Note : Si l’anglais n’est pas un problème pour vous, je vous invite à consulter cet article pour tout savoir en détail sur la variable PS1.

Pour afficher le nom de la branche Git sur laquelle on travaille dans notre prompt, il nous faut donc modifier le contenu de cette variable PS1.

Et pour éviter de refaire la manipulation à chaque fois que l’on démarre un nouveau terminal, on va donc ajouter un bout de code à notre profile bash, en modifiant le fichier .bashrc :

vim ~/.bashrc

Note : le caractère ~ est un raccourci pour indiquer votre répertoire d’utilisateur. Dans mon cas, cela correspond à /home/thibault.

Déplacez-vous à la fin du fichier, et ajoutez le code suivant, puis sauvegardez :

# Configuration Git Branch – Modification prompt Linux
parse_git_branch() {
     git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[email protected]\h \[\033[32m\]\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] $ "

 

Avant de tester le bon fonctionnement du code, quelques explications s’imposent :

La fonction parse_git_branch va extraire le nom de la branche Git sur laquelle vous vous trouvez actuellement dans votre repository Git.

Le contenu de la variable PS1 est alors modifié pour inclure le nom de la branche Git.

Si on analyse en détail le contenu de la variable PS1, on a alors les propriétés suivantes :

  • \[email protected]\h \[\033[32m\] à Affiche le nom de l’utilisateur et le hostname de la machine, avec la couleur appropriée
  • \w\[\033[33m\] à Affiche le nom du répertoire de travail actuel. Lorsque vous changez de répertoire avec la commande cd, ce contenu change également de manière dynamique.
  • \$(parse_git_branch)\[\033[00m\] à Si le répertoire de travail est un repository Git (et seulement dans ce cas-là), alors on affiche le nom de la branche Git dans laquelle nous nous trouvons actuellement.

IV. Tester le bon fonctionnement

Maintenant pour tester ça, comment faire ? Et bien, il suffit de redémarrer votre terminal pour que la fonction que l'on vient de rajouter soit prise en compte.

Jusque là, vous ne devriez voir aucun changement. Normal après tout, puisque vous vous trouvez actuellement dans un répertoire qui n'est pas tracké par Git.

Pour vérifier le fonctionnement, je me déplace dans mon dossier repository Git "scripts", qui contient deux branches :

  • master
  • test/branch

On peut voir que lorsque j'utilise la commande git checkout pour changer de branche et me déplacer entre "master" et "test/branch", mon prompt change aussi en fonction.

 

V. Conclusion

Ainsi, on sait d’un coup d’œil si le répertoire de travail est suivi par Git ou non, et si c’est le cas, on connaît également la branche (production, développement, etc) sur laquelle on travaille.

Plus aucun risque de se tromper maintenant ! 😉

The post Linux – Afficher la branche Git dans le prompt first appeared on IT-Connect.

Détails des durcissements des sysctl sous Linux : sysctl réseau

12 mai 2021 à 13:00

I. Présentation

Faisant suite à mon autre article "Détails des durcissements des sysctl sous Linux : sysctl système".

Nous allons dans cet article nous intéresser aux durcissements recommandés par l'ANSSI sur les sysctl réseau dans son guide Recommandation de configuration d'un système GNU/Linux. Je vais dans cet article suivre la même approche que dans l'article précédent, dans lequel vous trouverez également quelques exemples d'utilisation de la commande sysctl pour lire et écrire des paramètres.

Pour les paramètres sysctl au niveau réseau, celles-ci peuvent être appliquées à plusieurs niveaux, ce qui détermine le nom précis du paramètre à modifier. On peut par exemple différencier les paramètres s'appliquant sur les interfaces IPv4 (net.ipv4.X.X) ou IPv6 (net.ipv6.X.X), mais également spécifier une interface précise (net.ipv4.eth0), les mots-clés all et default sont utilisés respectivement pour appliquer un paramètre sur toutes les interfaces ou pour les interfaces nouvellement créées (configuration par défaut si rien n'est spécifié).

Ça, c'était la théorie, la réalité est un chouilla plus obscure (voir ce mail https://marc.info/?l=linux-kernel&m=123606366021995&w=2) et je vous déconseille, pour résumer, de paramétrer des valeurs différentes pour le all et le default d'une même sysctl sous peine de vous retrouver avec des comportements difficiles à déboguer ou à comprendre.

II. Durcissement des sysctl réseau Linux

A. IP Forwarding

Le premier durcissement généralement recommandé en ce qui concerne les sysctl réseau est la désactivation de l'IP forwarding. Ce sysctl, lorsqu'il est à 1, permet au serveur de faire transiter des paquets d'une interface vers une autre, à l'image d'un routeur. Lorsque cette fonctionnalité n'est pas utile au fonctionnement du serveur, il est recommandé de désactiver l'IP forwarding :

net.ipv4.ip_forward = 0

Ainsi, le serveur ne sera pas autorisé à faire du routing, c'est-à-dire faire suivre des paquets d'une interface vers une autre, et ne pourra être utilisé comme un routeur entre deux réseaux. Dans le cas où votre serveur dispose de deux interfaces, dont une vers un réseau non maitrisé (Internet par exemple), les paquets provenant d'internet ne pourront atteindre directement les autres serveurs du réseau non exposé (deuxième interface de votre serveur), car le serveur ne fera pas suivre ces paquets, même s'il connait la route par lesquels ils sont censés passer.

Dans le cas où ce sysctl est à 1 (IP forwarding activé), alors les paquets reçus par le serveur sans lui être destinés, mais pour lesquels il connait une route seront automatiquement envoyés sur cette route, le serveur pourrait alors servir de pont entre deux réseaux sans que cela ne soit voulu.

À noter que ce paramétrage ne protège pas de tout, si votre serveur est compromis ou si l'application web qu'il héberge est ciblée par une attaque SSRF (Server Side Request Forgery), alors les IP du réseau "interne" pourront tout de même être atteintes.

B. Filtrage par chemin inverse

Le filtrage par chemin inverse ou Reverse Path Filtering est un mécanisme du noyau Linux consistant à vérifier si l'adresse source indiquée dans les paquets reçus par une interface est routable par cette interface. En d'autres termes, lorsque notre serveur va recevoir un paquet sur une interface, il va l'ouvrir, regarder quelle est son adresse IP source, puis utiliser sa table de routage pour voir s’il contient une route capable de joindre cette IP source pour l'interface par laquelle il a reçu ce paquet (qui deviendra une IP destination en cas de réponse :)). On pourrait décrire ce mécanisme comme un contrôle de cohérence du serveur qui reçoit un paquet, le serveur cherche à vérifier s'il est normal ou cohérent de recevoir un paquet avec telle IP source sur cette interface.

Dans le cas où ce "contrôle de cohérence" échoue, le paquet est supprimé ("droppé" pourrait-on dire en bon français). L'ANSSI recommande d'activer cette fonctionnalité en mettant une valeur 1 aux sysctl suivants :

 net.ipv4.conf.all.rp_filter = 1
 net.ipv4.conf.default.rp_filter = 1

À noter que les systèmes Red Hat possèdent une option supplémentaire (2) permettant d'accepter un paquet si son IP source est routable par n'importe quelle interface du serveur, et non pas uniquement par l'interface ayant réceptionné le paquet analysé.

Le reverse path filtering est en réalité un mécanisme créé pour limiter les attaques par Déni de Service (Denial of Service ou DoS). L'une des techniques de déni de service profite du Three way Handshake TCP combiné à de l'IP spoofing. Plus clairement, l'attaquant va envoyer des milliers de paquets TCP SYN au serveur avec des adresses IP usurpées ou n'existant pas. Le serveur va alors renvoyer à ces adresses IP un paquet SYN/ACK et n'obtiendra jamais de réponse. Ainsi, les connexions resteront ouvertes pendant un long moment, ce qui les rendra indisponibles pour de nouvelles connexions légitimes. Un peu comme si l'on réservait toutes les tables d'un restaurant sur une semaine sans venir y manger :).

Ce mécanisme est décrit précisément dans la RFC3704 : https://tools.ietf.org/html/rfc3704

Lorsqu'une telle attaque intervient avec un rp_filter activé, la plupart des paquets seront droppés dès leur réception, car le système remarquera qu'ils ne sont pas légitimes pour arriver sur une interface réseau donnée.

C. Redirections ICMP

L'ICMP (Internet Control Message Protocol) est un protocole qui ne se réduit pas au ping, les paquets echo request (paquet ICMP de type 8) et echo reply (paquet ICMP de type 0) observés lorsqu'on fait un ping ne sont qu'une petite partie des capacités de ce protocole. Parmi les fonctions méconnues de ce dernier, les paquets ICMP de type 5, nommés Redirect Messages sont utilisés afin d'avertir un hôte nous ayant envoyé un message qu'une autre route est possible (et plus rapide) pour joindre l'hôte qu'il cherche à contacter.

Ce mécanisme se nomme l'ICMP redirect est n'est utilisé qu'à de rares occasions (voire jamais) sur un système d'information moderne correctement configuré, et comme tout en sécurité, si c'est inutile, c'est à désactiver.

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

En soit, ce mécanisme de l'ICMP redirect permet donc à un hôte recevant un paquet de faire passer son correspondant par un autre chemin réseau, en lui indiquant une nouvelle route qu'il intégrera durablement dans sa table de routage, un attaquant utilisant ce mécanisme envers un système peut donc modifier le chemin qu'emprunterons les futurs paquets, et pourquoi pas provoquer une attaque de type Man in the Middle ou une simple interruption de service. C'est pourquoi l'ANSSI recommande de désactiver l'acceptation et l'envoi de paquets ICMP redirect.

Le sysctl secure_redirects correspond à une option permettant à l'hôte d'accepter un paquet ICMP redirect uniquement si celui provient de l'adresse IP d'une des passerelles enregistrées au niveau de la configuration réseau. On cherche ici a maintenir l'utilisation de l'ICMP redirect, mais à réduire les hôtes pouvant nous envoyés de tels paquets à une liste de confiance.

D. Source routing

Pour l'expéditeur d'un paquet IP, le mécanisme du source routing consiste en la possibilité de définir la route prise par ce paquet sur le réseau. Alors que dans la plupart des cas, un paquet IP est envoyé par son expéditeur sur la passerelle réseau, qui définit ensuite en fonction de sa table de routage quel sera le prochain saut ou la prochaine passerelle à atteindre. Dans le cas d'un source routing, l'expéditeur peut inclure dans le paquet IP une liste d'adresses IP par lequel le paquet devra passer et ainsi modifier la décision nominale des différentes passerelles du réseau qui seront traversées. En d'autres termes, l'expéditeur peut manipuler une partie de la décision des passerelles concernant le routage des paquets. Également, le chemin par lequel le paquet est passé peut être transmis à son destinataire, qui prendra potentiellement ce chemin pour ses réponses. Les guides de bonnes pratiques recommandent de désactiver cette fonctionnalité :

net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

Dans les faits, le source routing au niveau d'un paquet IP n'est presque jamais utilisé, il peut être utile pour du débogage (notamment pour du traceroute). En plus d'aider à dresser une cartographie du réseau, le source routing reste intéressant pour un attaquant, car il peut permettre de joindre une machine sur un réseau qui n'est, selon les tables de routages habituelles, pas accessibles au travers un serveur ayant deux interfaces réseau par exemple. 

E. Journalisation des martians packet

L'IANA définit un paquet "martien" comme un paquet qui arrive sur une interface n'utilisant pas le réseau source ou destination du paquet reçu. Pour Linux, il s’agit de tout paquet qui arrive sur une interface qui n’est en aucun cas configurée pour ce sous-réseau.

net.ipv4.conf.all.log_martians = 1

L'objectif de la journalisation des IP "anormales" est justement de pouvoir investiguer, voire alerter et réagir sur un comportement réseau qui n'est pas usuel. Il est en effet courant qu'un attaquant produise ce genre de comportements anormaux lors d'une phase de cartographie, d'une analyse comportementale d'un hôte ou d'un service pour en déterminer la nature (version, technologie précise), voir de causer un bug ou d'exploiter une vulnérabilité.

Dans les faits, la journalisation d'un tel paquet aura aussi de grandes chances de provenir d'une erreur de configuration au niveau des routes et des routeurs du réseau, le but pourrait donc également être d'avertir les administrateurs d'un potentiel problème de routage.

F. RFC 1337

La RFC 1337 est une RFC de type Informationnal (non obligatoire en somme) qui décrit un bug théoriquement possible sur des connexions TCP, ce bug est nommé "TIME-WAIT Assassination hazards". En somme, il s'agit d'une "lacune" dans la conception de TCP/IP qui rend possible la fermeture d'une connexion en TIME-WAIT par un paquet provenant d'une ancienne session TCP (arrivé en retard ou en dupliqué à cause d'une latence quelconque). Ce cas de figure théorique peut donc perturber des communications établies entre un client et un serveur :

net.ipv4.tcp_rfc1337 = 1

Cette protection vise donc à se protéger d'une anomalie potentielle dans les communications TCP, qui n'est pas le fruit d'une attaque ciblée visant à avoir un résultat précis.

G. Ignorer les réponses non conformes à la RFC 1122

Certains routeurs sur Internet ignorent les normes établies dans la RFC 1122 et envoient de fausses réponses aux trames de diffusion. Normalement, ces violations sont journalisées via les fonctions de journalisation du noyau, mais si vous ne voulez pas voir ces messages d'erreur dans vos journaux, vous pouvez activer cette variable, ce qui conduira à ignorer totalement tous ces messages d'erreur.

La RFC 1122  normalise ce que toute machine terminale (host, par opposition à routeur) connectée à l'Internet devrait savoir. Je vous invite à consulter la description de Stéphane Borztmeyer sur son blog pour plus de détails : RFC 1122: Requirements for Internet Hosts - Communication Layers

net.ipv4.icmp_ignore_bogus_error_responses = 1

L'objectif est donc simplement d'économiser un tout petit peu d'espace disque et d'éviter la présence de certains évènements inutiles dans les journaux. Peu d'impact en termes de sécurité donc.

H. Augmenter la plage pour les ports éphémères

Les ports éphémères sont les ports utilisés comme port source lorsqu'un système initie une connexion vers un serveur (alors nommés "port client"). Ces ports peuvent également être utilisés par certains protocoles dans une seconde phase d'échange avec le client après un premier échange sur un port "officiel". C'est notamment le cas pour les protocoles TFTP ou RPC. Sur les serveurs à haut trafic (reverse proxy ou load balancer), il est recommandé d'élargir la plage de port par rapport à celle par défaut :

net.ipv4.ip_local_port_range = 32768 65535

À noter que 65535 est la valeur la plus haute pouvant être acceptée. La valeur la plus basse (ici 32768) peut aller jusqu'à 0, gardez cependant à l'esprit que de nombreux ports sont réservés à des usages spécifiques (22 pour SSH, 80 pour HTTP, etc.). Il est donc plus sage de ne pas empiéter sur ces ports-là.

Le gain n'est pas très significatif, mais ce faisant, nous permettons au serveur d'établir plus de connexions et limitons ainsi les risques de saturation de ces ports pouvant être provoqués intentionnellement (attaque par déni de service) ou non (trafic réseau exceptionnellement élevé).

I. Utiliser les SYN cookies

Les SYN cookies sont des valeurs particulières des numéros de séquences initiales générés par un serveur (ISN: Initial Sequence Number) lors d'une demande de connexion TCP. Les bonnes pratiques de sécurité recommandent leur activation au niveau des échanges réseau :

 net.ipv4.tcp_syncookies = 1

L'activation des SYN cookies au niveau du système permet de se protéger des attaques par inondation de requêtes SYN (SYN flooding) qui consiste à ouvrir un très grand nombre de connexions sur un serveur à l'aide de requêtes SYN, sans jamais donner suite au Three Way Handshake TCP (SYN, SYN/ACK, ACK). Le serveur maintient donc un ensemble de connexions en attente (attente de réception d'un ACK après envoi d'un SYN/ACK), ce qui finit par saturer les connexions disponibles pour les clients légitimes.

Ce mécanisme permet au serveur de garder la "tête froide" lorsqu'il est ciblé par une telle attaque, mais il n'est pas conçu pour améliorer les capacités du serveur dans un contexte normal de fonctionnement (autre qu'une attaque par SYN flood).

Attention toutefois : les SYN cookies ne sont en théorie pas conforme au protocole TCP et empêchent l'utilisation d'extension TCP, ils peuvent entraîner une dégradation sérieuse de certains services (par exemple le relais SMTP). Si vous voulez tester les effets des SYN cookies sur vos connexions réseau, vous pouvez paramétrer ce sysctl sur 2 pour activer sans condition la génération de SYN cookies.

J. Gestion de l'IPv6

Dans le cas où l'IPv6 n'est pas activement utilisé au sein de vos réseaux locaux (c'est très très souvent le cas), il est tout simplement recommandé de désactiver la prise en compte de l'IPv6 au niveau du noyau Linux.

net.ipv6.conf.all.disable_ipv6 = 1 
net.ipv6.conf.default.disable_ipv6 = 1

La désactivation pure et simple de l'IPv6 permet de réduire la surface d'attaque du serveur, ce qui est l'un des principaux fondements de la sécurité. Dans bien des cas, l'IPv6 peut être utilisé pour détourner du trafic réseau, réaliser des attaques par déni de service ou contourner des politiques de filtrage lorsqu'il n'est pas activement utilisé et pris en compte dans la configuration et le durcissement global d'un système d'information.

K. Gestion de l'auto-configuration IPv6

Dans le cas, très rare selon moi, où vous utilisez de manière active l'IPv6 dans vos infrastructures internes, différents paramètres peuvent être utilisés afin de durcir la configuration de vos systèmes.

En IPv6, les router advertisements sont des paquets régulièrement envoyés par les routeurs d'un réseau pour s'annoncer aux éventuels nouveaux venus. Les informations contenues dans les router advertisements permettent à un nouvel hôte connecté de récupérer les caractéristiques essentielles du réseau, passerelles par défaut, routes et le préfixe servant à se forger une adresse IPv6 en auto configuration.

Dans le cas où les adresses IPv6 sont établies de manière statique sur vos réseaux, il est recommandé de désactiver la prise en charge des router advertisements afin de ne pas laisser la possibilité à un attaquant d'utiliser leur prise en charge sur les systèmes du réseau pour lui-même déterminer la configuration IPv6 de ces systèmes . En effet, quoi de plus simple que de se faire passer pour un routeur ou une passerelle pour réaliser une attaque par l'homme du milieu ?

# Ne pas accepter les router preferences par router advertisements
net.ipv6.conf.all.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0

# Pas de configuration automatique des prefix par router advertisements
net.ipv6.conf.all.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_pinfo = 0

# Pas d’apprentissage de la passerelle par router advertisements
net.ipv6.conf.all.accept_ra_defrtr = 0
net.ipv6.conf.default.accept_ra_defrtr = 0

# Pas de configuration auto des adresses à partir des router advertisements
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0

L. Désactiver le support des "router solicitations" IPv6

En IPv6, le router sollicitation est un type de message qui permet à un hôte de demander à tous les routeurs présents sur le réseau local de lui envoyer un Router Advertisement, afin qu'il l'enregistre dans sa liste de voisins et qu'il puisse récupérer les éléments essentiels du réseau IPv6. Dans le cas où les adresses IPv6 sont paramétrées en statique, il est recommandé de désactiver ce mécanisme :

 net.ipv6.conf.all.router_solicitations = 0
 net.ipv6.conf.default.router_solicitations = 0

Pour être plus précis, ce sysctl configure le nombre de router sollicitation à envoyer sur le réseau avant de considérer qu'il n'y a pas de routeur sur le réseau. Désactiver ce comportement lorsque les adresses IPv6 sont statiques permet donc d'éviter du trafic inutile, mais également qu'un attaquant puisse répondre à ces sollicitations en vue de se faire passer pour un routeur IPv6 auprès de votre serveur, lui facilitant ainsi le travail pour la réalisation d'une attaque de type man in the middle.

M. Nombre maximal d’adresses autoconfigurées par interface

L'adressage IPv6 permet d'utiliser plusieurs adresses par interface. À moins que vous n'ayez un besoin particulier nécessitant plusieurs adresses IPv6 unicast global par interface, il est recommandé de paramétrer ce sysctl à 1, ce qui limite à 1 le nombre d'adresses unicast global par interface (16 possibles dans la configuration par défaut).

 net.ipv6.conf.all.max_addresses = 1
 net.ipv6.conf.default.max_addresses = 1

Attention, positionner ces sysctl à 0 rend illimité le nombre d'adresses possibles, ce qui finira par avoir un impact sur les performances de votre serveur.

J'ai toutefois du mal à trouver des risques concrets relatifs à la non-application de ce paramètre. D'après ma compréhension du paramètre dans son état par défaut et du fonctionnement de l'IPv6, sa non-application entrainera la possibilité pour un attaquant de générer la création d'une adresse IPv6 sur sa cible puisque dans un environnement "normal", les 16 slots disponibles sur l'interface IPv6 ne seront pas toutes utilisées. En principe on laisse donc au travers la configuration par défaut, des paramètres non utilisés qui n'attendent qu'à recevoir les faux router avertissements d'un attaquant.  Alors que si le nombre d'adresses IPv6 est limité à 1 par interface est que celle-ci est déjà configurée lors de la venue de l'attaquant (en statique qui plus est), ce dernier n'aura pas de porte d'entrée possible.

N'hésitez pas à ajouter des informations de compréhension supplémentaires dans les commentaires si vous en avez à ce sujet :).

III. Conclusion

Voilà, nous avons fait le tour des durcissements sysctl recommandés par l'ANSSI dans son guide Recommandations de configuration d'un système GNU/Linux. Vous aurez compris que les raisons de certains durcissements sont faciles à appréhender alors que d'autres sont plus bien abstraits ou répondent à des cas très spécifiques. Quoi qu'il en soit j'espère vous avoir apporté une lumière supplémentaire sur ces éléments.

N'hésitez pas à signaler toute erreur ou précision technique dans les commentaires 🙂

The post Détails des durcissements des sysctl sous Linux : sysctl réseau first appeared on IT-Connect.

Détails des durcissements des sysctl sous Linux : sysctl système

12 mai 2021 à 10:00

I. Présentation

Nous allons dans cet article nous intéresser aux durcissements du noyau proposés par le guide de configuration de l'ANSSI à travers les sysctl. Les guides de bonnes pratiques et de configuration de l'ANSSI sont pour la plupart très pertinents, mais il arrive qu'ils manquent de détails et que la cohérence de certains durcissements puisse être difficile à appréhender. Je vais donc ici m'efforcer de décortiquer les recommandations 22 et 23 du Guide Recommandation de configuration d'un système GNU/Linux de l'ANSSI qui portent sur les paramétrages des sysctl réseau et système en vue du durcissement d'un noyau Linux. Nous parlerons dans cet article des sysctl système et un prochain article portera sur les sysctl réseau.

J'essaierai notamment de mettre en avant les implications en termes de sécurité et les attaques qu'un durcissement permet d'éviter, sans oublier les potentiels effets de bords si ceux-ci sont connus et les éventuelles questions qui restent en suspens après avoir tenté de creuser ce sujet.

Sur les OS Linux, sysctl est utilisé afin de consulter et modifier les paramètres du noyau, cela nous permet donc de configurer certains comportements du noyau comme la prise en compte de l'IPv6 sur nos interfaces réseau ou l'activation de l'ASLR. Les paramètres utilisables sont ceux listés dans le répertoire /proc/sys

On parle souvent de sysctl pour décrire une clé de configuration paramétrable par la commande sysctl. Ne soyez donc pas étonné de lire "On configure le sysctl net.ipv4.ip_forward à 0" pour indiquer que la clé de configuration net.ipv4.ip_forward doit être définie à 0, par exemple 😉

Pour les systèmes utilisant systemd, la configuration des sysctl se trouve dans /etc/sysctl.d/.conf, /usr/lib/sysctl.d/.conf. et /etc/sysctl.conf.

Attention, depuis récemment (2017) il se peut que certains systèmes utilisant systemd n'appliquent plus les configurations sysctl indiquées dans /etc/sysctl.conf. Seuls les fichiers ayant une extensions .conf et situés dans les répertoires /etc/sysctl.d ou /usr/lib/sysctl.d sont appliqués.

➡ A lire également : Détails des durcissements des sysctl sous Linux : sysctl réseau

II. Comment modifier un sysctl

Il existe deux possibilités de modification d'un sysctl, soit de façon temporaire, c'est à dire valable jusqu'au prochain redémarrage, soit de façon persistante, c'est à dire qui persiste après un redémarrage.

Pour modifier une configuration sysctl de façon temporaire, on peut modifier à chaud la valeur stockée dans le fichier correspondant au sysctl à modifier, par exemple :

# echo 1 > /proc/sys/kernel/sysrq

Ou utiliser la commande sysctl pour faire cette même opération :

# sysctl -w kernel.sysrq=1

Pour modifier un sysctl de façon persistante, il faut aller modifier le fichier configuration (/etc/sysctl.d/99-sysctl.conf, ou autre fichier finissant par .conf dans le même dossier) et y modifier ou ajouter notre valeur pour le sysctl souhaité :

Modification persistante d'une sysctl
Modification persistante d'une sysctl

Pour être techniquement plus précis, une configuration modifiant un sysctl est appelée clé. Ici la clé est donc net.ipv4.conf.default.log_martians et 0 est la valeur associée à cette clé.

Pour afficher l'ensemble des sysctl actuellement utilisées et appliquées, la commande suivante est à utiliser :

# sysctl -a

Enfin pour récupérer un sysctl précis, la commande suivante est à utiliser :

# sysctl -n net.ipv4.conf.eth1.log_martians

III. Durcissement des sysctl système Linux

A. Désactivation des SysReq

Les SysReq ou Magic System Request Key sont une fonctionnalité du noyau Linux permettant, via une combinaison de touche réalisable à tout moment, de lancer des commandes bas niveau, par exemple afin de pouvoir redémarrer un système bloqué sans corrompre le système de fichiers ou tuer un programme paralysant les ressources du système. Parmi les actions réalisables :

  • Déterminer le niveau de log de la console
  • Redémarrer l'ordinateur reBoot
  • Redémarrer via kexec pour faire un crashdump Crashdump
  • Envoyer un signal de terminaison (SIGTERM) à tous les processus (sauf init) tErm
  • Tuer le processus qui consomme le plus de mémoire (via oom-killer)
  • Envoyer un signal de fin (SIGKILL, plus ferme que SIGTERM) à tous les processus (sauf init)
  • Tuer tous les processus de la console virtuelle courante.
  • Envoyer un signal de fin (SIGKILL, plus ferme que SIGTERM) à tous les processus (même init)
  • Afficher le contenu actuel de la mémoire Memory
  • Éteindre le systeme via APM Out
  • Afficher sur la console les registres et drapeaux actuels Print
  • Basculer la gestion du clavier de mode brute (raw) à XLATE
  • Synchroniser les disques (tente d'écrire toutes les données non sauvegardées)
  • Afficher une liste des taches et autres informations dans la console
  • Remonter les disques en lecture seule

À noter que même si les SysReq sont activées, une partie seulement de ces actions sont réalisables dans la configuration par défaut. D'autres requièrent une configuration spécifique. Cette combinaison de touche clavier doit être réalisée sur un terminal "physique", entendez par là qu'une connexion SSH ne sera pas suffisante, en théorie :).

Il existe en effet une petite astuce permettant d'exécuter des SysReq depuis une connexion distante, et cela en utilisant directement une fonctionnalité "native" de sysctl, le fichier /proc/sysrq-trigger. Si l'on souhaite redémarrer le système par exemple, il faut envoyer l'instruction "b", et donc :

echo "b" > /proc/sysrq-trigger

Ce fichier n'est cependant modifiable que par l'utilisateur root :

[email protected]:~$ ls -al /proc/sysrq-trigger
 --w------- 1 root root 0 juil. 28  2018 /proc/sysrq-trigger

Pour gérer cela, il faut se rendre dans le fichier /proc/sys/kernel/sysrq ou utiliser la clé kernel.sysrq dans un fichier de configuration sysctl.

Positionner la valeur 1 permet d'activer l'utilisation des SysReq (valeur par défaut sur une majorité de systèmes), positionner la valeur 0 interdit toute utilisation des SysReq. Lorsque la valeur est autre que 0 ou 1, c'est que certaines commandes sont autorisées, d'autres non, à utiliser en connaissance de cause donc. À nouveau, comme cette fonctionnalité est très rarement utilisée, voir inconnue des sysadmins la plupart du temps, mieux vaut la désactiver :

kernel . sysrq = 0

L'ANSSI recommande en effet de positionner la valeur de cette clé à 0 afin de désactiver totalement leur utilisation. On peut imaginer les effets de bords possibles grâce à ces commandes, notamment en ce qui concerne la possibilité de tuer des processus, afficher les registres CPU, démonter un système de fichier, redémarrer la machine, etc. À noter que le plus grand danger reste l'exploitation de ces SysReq à partir d'un terminal physique par un utilisateur non privilégié, mais leur utilisation n'est pas forcément restreinte au terminal physique comme je l'ai indiqué précédemment.

La frontière entre physique et virtuel s'étant quelque peu estompée ces dernières années, j'ignore par exemple si l'on peut lancer des SysReq à partir d'un clavier virtuel, dans le cas d'un accès distant VNC, via une console d'hyperviseur type VMWare/Proxmox, etc.

B. Interdire les core dump des exécutables setuid

Par défaut, le système va réaliser un core dump (extraction de la mémoire) des processus s'arrêtant brusquement, cela est notamment pratique pour du debug, avoir une photo à l'instant du crash permet de voir quelles données ou actions ont potentiellement causé ce crash.

Cependant, ces dumps sont exécutés par le kernel et écrits sur le système avec les droits de l'utilisateur courant (celui ayant lancé la commande). Dans le cadre de l'utilisation d'un exécutable setuid ou setgid, l'extraction mémoire contiendra les informations d'un programme exécuté avec les droits d'un autre utilisateur, probablement avec un plus haut niveau de privilège que l'utilisateur courant ou root, mais sera écrit sur le système avec les droits de l'utilisateur courant (non privilégié). Ainsi, des informations sensibles, permettant potentiellement une élévation de privilège, pourront se trouver dans ce type de fichier et lisible par l'utilisateur courant.

Afin de contrôler ce comportement, on peut utiliser la clé fs.suid_dumpable afin de ne pas produire de core dump pour les exécutables possédant un bit setuid ou setgid.

fs.suid_dumpable = 0

L'ANSSI recommande de passer la valeur de la clé fs.suid_dumpable à 0 pour désactiver tout core dump sur les exécutables possédant un bit setuid ou setgid, et ainsi éviter d'éventuelles fuites de données sensibles concernant les attributs, les fichiers accédés ou d'autres actions d'un utilisateur privilégié.

C. Déréférencement des liens de fichiers

Une des vulnérabilités courantes sous Linux concernant les liens symboliques est le symlink-based time-of-check-time-of-use race (ou symlink race condition). Il s'agit d'un delta de temps entre le moment où un fichier est contrôlé (pour voir si les droits d'accès sont suffisants) et celui où il est utilisé par un programme.

Pendant le laps de temps où ces deux opérations sont effectuées, un utilisateur malveillant peut créer un lien symbolique portant le nom de ce fichier et ainsi manipuler une partie de l'exécution du programme, qui s'exécute idéalement avec un plus haut niveau de privilège. Un exemple courant fourni comme explication est le suivant :

Exemple d'une attaque time-of-check to time-of-use - Wikipedia
Exemple d'une attaque time-of-check to time-of-use - Wikipedia

Dans cet exemple, le programme contrôle les permissions d'un fichier file avec l'instruction access() en C. Puis, dans un deuxième temps si les permissions le permettent, il va écrire dans ce fichier. Dans le cadre d'une attaque, l'attaquant va laisser le fichier tel quel pour la première opération (par exemple créer lui-même le fichier file en permission 777 pour que le programme constate qu'il peut y écrire). Puis, il va remplacer ce fichier par un lien symbolique pointant vers /etc/passwd. Le programme s'exécutant avec un haut niveau de privilège va alors exécuter sa deuxième instruction et écrire dans le fichier file, qui sera en réalité/etc/passwd.

Un très bon labo est mis à disposition sur ce Gitlab Ranjelikasah/ace-Condition-Seedsecurity, je vous le recommande si vous souhaitez expérimenter par vous-même 🙂

Ce type d'attaque est notamment dangereuse sur les setuid/setgid, qui permettent d'exécuter un binaire avec les droits root (ou d'un autre utilisateur en fonction de leur configuration). C'est pourquoi il est recommandé de durcir ces sysctl qui ont plusieurs effets concernant les liens symboliques et les setuid.

Concernant les hardlinks et pour un utilisateur système créant un lien, l'une des conditions suivantes doit être remplie :

  • l'utilisateur peut seulement créer des liens vers des fichiers dont il est le propriétaire
  • l'utilisateur doit avoir les droits d'écriture et de lecture vers le fichier vers lequel souhaite créer un lien.
Démonstration sur l'effet des durcissement sysctl sur la création des hardlinks
Démonstration de l'effet des durcissements sysctl sur la création des hardlinks

Concernant les symlinks et les processus qui sont amenés à suivre des liens symboliques vers des répertoires world-writable qui ont le sticky bit activé :

  • le processus suivant le lien symbolique doit être le propriétaire du lien symbolique
  • le propriétaire du répertoire est également le propriétaire du lien symbolique.

Si vous avez bien compris le fonctionnement de l'attaque présentée, vous comprendrez rapidement quelle devient impossible si ces conditions sont imposées via le durcissement sysctl :

fs.protected_symlinks = 1
fs.protected_hardlinks = 1

Ce paramétrage permet en somme de durcir les conditions d'utilisation des symlinks et des hardlinks afin de se protéger des différentes attaques permettant une élévation de privilège

D. Activation de l’ ASLR

L'ASLR (Address Space Layout Randomization) est un mécanisme permettant de limiter les effets et de complexifier l'exploitation des attaques de type buffer overflow (dépassement de tampon). L'objectif est ici de placer la zone de données dans la mémoire virtuelle de façon aléatoire, changeant ainsi sa position à chaque exécution.

L'exploitation de buffer overflow consiste notamment à contrôler une partie des registres CPU afin de modifier le flux d'exécution d'un programme. Cela passe, entre autres, par le contrôle du registre EIP (Extended Instruction Pointer) qui permet d'indiquer à quel offset (adresse mémoire) la prochaine instruction à exécuter se trouve. En contrôlant le registre EIP, l'attaquant peut indiquer au programme de sauter à un offset précis et dont le contenu est sous son contrôle, notamment s'il a réussi à injecter du code malveillant (shellcode) à cet endroit de la mémoire. En modifiant la répartition et le positionnement des instructions, de la pile (stack), du tas (heap) et autres, en mémoire, l'attaquant n'est plus en capacité de pointer vers son shellcode car celui-ci ne sera jamais au même endroit à chaque exécution.

Pour activer l'ASLR, on peut utiliser la clé kernel.randomize_va_space et y positionner la valeur 2, qui permet de positionner de façon aléatoire (aka randomiser :/ ) la stack (pile), les pages CDSO (virtual dynamic shared object), la mémoire partagée et le segment de données (data segment), qui contient les variables globales et statiques initialisées par le programme. Positionner la valeur 1 aura le même effet, sauf pour le segment de données. La valeur 0 désactive l'ASLR.

kernel.randomize_va_space = 2

Pour plus d'information sur les buffer overflow, je vous oriente vers les très bons articles (en français) d'0x0ff :

E. Mappage de la mémoire des adresses basses

Une vulnérabilité de type NULL pointer dereference est le fait pour un programme d'utiliser un pointeur non initialisé (valant NULL) ou pointant vers une adresse mémoire inexistante (0x00000000). De fait, lorsque ce programme utilisera ce pointeur dans ses instructions, cela causera un crash. Dans le contexte d'exécution du noyau ou d'un programme à haut niveau de privilège, le fait de déclencher intentionnellement l'utilisation d'un pointeur NULL par un attaquant lui permet de faire crasher le programme, voir le système.

Cependant, si l'attaquant parvient à identifier l'adresse mémoire du pointeur en question et à la manipuler pour y insérer les données de son choix avant qu'elle ne soit utilisée activement par le noyau ou un programme à haut niveau de privilège, alors il pourra contrôler son utilisation dans le programme exécuté, menant à une potentielle élévation de privilège.

En C, un pointeur est une variable qui permet de stocker non pas une valeur ("ABC" ou 12,28), mais une adresse mémoire. Lorsqu'un programme démarre, le système lui alloue une zone mémoire dans laquelle il peut s'organiser. Cette zone mémoire est constituée de "cases" de 8 bits (octets). Chacune de ces cases (appelées blocs) est identifiée par un numéro : son adresse. On peut alors accéder à une variable soit par son nom "agePersonne", soit par l'adresse du premier bloc alloué à la variable en question, c'est-à-dire son pointeur.

Il se trouve que le noyau a tendance à plutôt utiliser les adresses mémoires dites "basses", si l'attaquant parvient à manipuler les pointeurs visant des blocs d'adresses mémoires "basses", alors il a plus de chances de trouver un bloc d'adresse qui sera ensuite utilisé par le noyau.

La clé vm.mmap_min_addr est donc une constante qui permet d'empêcher les utilisateurs non privilégiés de créer des mapping mémoires en dessous de cette adresse. Elle permet de définir l'adresse minimale qu'un processus n'ayant pas les droits root peut mapper, adresse que nous allons rehausser par rapport à sa valeur par défaut (0) :

vm.mmap_min_addr = 65536

Attention toutefois à bien tester le fonctionnement de vos programmes et applications avec ce paramètre avant de passer en production.

F. Espace de choix plus grand pour les valeurs de PID

Sous Linux (et Windows), le PID (Process IDentifier) est un numéro unique assigné à un processus en cours d'exécution. Il permet son identification parmi d'autres processus pour leur gestion, par exemple lorsque l'on utilise les commandes ps ou kill.

Comme pour les ports clients, les PID  sont en nombre limité sur un système. Il se peut donc que toute la plage de PID disponible soit saturée par un dysfonctionnement ou une attaque. Dès lors, aucun autre processus ne pourra être créé, car il n'aura aucun PID à utiliser. L'ANSSI recommande d'élargir la plage du nombre de PID disponible sur un système afin d'éviter ou de limiter de tels scénarios :

kernel.pid_max = 65536

Cette configuration permet donc de prévenir d'une saturation de PID entrainant une impossibilité de créer de nouveau processus. Sur les systèmes 32 bits, la valeur max est de 32 768 alors que pour les systèmes 64 bits, elle est de 2^22 (4 194 304, ça fait beaucoup de processus). À noter toutefois que les PID sont "recyclés", c'est-à-dire que lorsqu'un processus avec un certain PID se termine, ce PID peut être réutilisé plus tard par un autre processus. Ce durcissement vise donc à élargir le nombre de processus tournant simultanément sur votre système, ce qui ne sera le cas qu'en cas d'attaque ou pour des serveurs à très haute performance.

G. Obfuscation des adresses mémoires kernel

Un attaquant qui cherche à compromettre un noyau en cours d'exécution en écrasant les structures de données du noyau ou en forçant un jump (saut) vers un code de noyau spécifique doit, dans les deux cas, avoir une idée de l'emplacement des objets cibles en mémoire. Des techniques comme l'ASLR ont été créées dans l'espoir de "dissimuler" cette information, mais cet effort est vain si le noyau divulgue des informations sur l'endroit où il a été placé en mémoire. Il existe en effet plusieurs cas de figure où des adresses mémoires relatives au kernel peuvent être affichées (fuitées) vers l'espace utilisateur, qui obtient alors des informations intéressantes sur les pointeurs à cibler dans le cadre d'une attaque.

L'ANSSI recommande de paramétrer la directive suivante à 1 afin que, dans certains cas, les adresses mémoires relatives au noyau affichées par un programme soit dissimulées (remplacées par des 0) :

 kernel.kptr_restrict = 1

Attention toutefois, cette dissimulation n'est effective uniquement si le programme utilise la notation %pK (au lieu de %p pour un pointeur "normal"). C'est-à-dire que le développeur a marqué le pointeur vers une adresse noyau comme tel et indique donc au système que l'information doit être protégée. Dans le cas où un programme ne respecte pas cette bonne pratique, le durcissement au niveau du sysctl est inutile.

Enfin, si l'utilisateur possède la capabilities CAP_SYSLOG dans le contexte d'exécution du programme, les adresses mémoire kernel seront affichées normalement (paramétrez la sysctl à 2 si vous souhaitez éviter ce cas de figure).

H. Restriction d’accès au buffer dmesg

Sous Linux, la commande dmesg permet de voir les journaux (plus précisément la mémoire tampon des messages) relatifs au kernel, par exemple ceux créés par les drivers, lors du démarrage du système ou au branchement d'un nouveau périphérique. Ces messages sont ensuite stockés dans le fichier /var/log/messages.

L'ANSSI recommande de configurer le sysctl suivant à 1 afin de n'autoriser que les utilisateurs privilégiés à consulter ce type d'information via la commande dmesg :

 kernel.dmesg_restrict = 1

L'objectif est ici de dissimuler les informations relatives aux journaux du noyau de la vue des utilisateurs, ceux-ci peuvent en effet dans certains cas contenir des informations sensibles pouvant être utilisées dans le cadre de futures attaques.

Voici un exemple de l'utilisation de la commande dmesg par un utilisateur non privilégié avec le paramétrage à 1, puis à 0 :

Effet de la sysctl kernel.dmesg_restrict
Effet de la sysctl kernel.dmesg_restrict

I. Restreindre l’utilisation du sous-système perf

Sous Linux, le sous-système perf est une commande très complète et puissante qui permet de mesurer les performances d'un programme ou du système. Il réalise ces mesures en étant au plus proche de l'hardware, ce qui nécessite un niveau de privilège élevé.

L'ANSSI recommande le paramétrage à 2 de la sysctl suivante afin de limiter l'accès des utilisateurs non privilégiés à cette commande :

kernel.perf_event_paranoid = 2

Ainsi, un utilisateur non privilégié ne sera pas en mesure d'utiliser cette commande, qui peut notamment impacter les performances du système. Ce paramétrage est effectif sauf si l'utilisateur en question possède la capabilities CAP_SYS_ADMIN.

Également, les deux sysctl suivantes doivent être paramétrées à 1 :

kernel.perf_event_max_sample_rate = 1 
kernel.perf_cpu_time_max_percent = 1

Ces deux sysctl servent à gérer combien de ressource et de temps CPU le système de performance peut utiliser. Il s'agit d'un pourcentage (1% du temps CPU). Ces configurations visent à limiter l'impact du sous-système perf sur le système lors de son utilisation. Attention, mettre ces deux sysctl à 0 fait tout simplement sauter toute limite, ce qui serait contre-productif 🙂

Quoi qu'il en soit l'idée derrière le paramétrage de ces deux sysctl est de limiter l'impact du sous-système perf. sur les performances du système.

Rendez-vous dans le prochain article pour l'étude des durcissement des sysctl réseau :). N'hésitez pas à signaler toute erreur ou précision technique dans les commentaires 🙂

The post Détails des durcissements des sysctl sous Linux : sysctl système first appeared on IT-Connect.

Debian : comment créer son propre repository local ?

4 mai 2021 à 13:00

I. Présentation

Aujourd'hui, nous allons voir comment mettre en place son propre repository local pour Debian, en l'occurrence Debian 10 dans ce tutoriel. Je vous recommande d'être à l'aise avec Linux de manière générale avant de vous lancer dans le tutoriel tête baissée, car ce n'est pas si simple qu'on pourrait le croire.

L'une des raisons pour lesquelles vous pouvez envisager de configurer un serveur de référentiel apt local est de :

  • diminuer la consommation de la bande passante requise. Notamment si vous avez une centaine d'instances Debian à mettre à jour à une heure précise le week-end.
  • De plus, cela vous permet de disposer aussi dans certains cas d'un parc de serveurs décentralisé et déconnecté d'internet. Certains serveurs n'ont en effet pas le besoin d'atteindre internet à l’exception du processus de mise à jour en fonction de leurs périmètres d'activités.

Toutes les commandes ci-dessous seront exécutées via l'utilisateur root, que se soit sur la machine hébergeant notre repository local ou bien sur la machine cliente.

Prérequis

  • Une machine Debian 10 pour héberger notre dépôt local, avec une connexion internet stable.
    • 256 Go d'espace disque et  4 Go pour la RAM pour être à l'aise
  • Une machine Debian 10 "Client" avec ou sans connexion à internet
    • Disposant de la capacité à communiquer avec la machine hébergeant le repository local par le biais de ping/http. Attention, si vous avez un pare-feu sur votre réseau, n'oubliez d'ouvrir ces flux

Précédemment, nous avons vu comment mettre en place un repository local sous Ubuntu.

II. Installation du serveur web apache2

Nous commençons ce didacticiel, par l'installation d'un serveur Web sur la machine hébergeant notre référentiel local. Nous allons utiliser le service apache2 pour héberger les dépôts. Pensez à ajouter "sudo" devant les commandes qui suivent si vous n'utilisez pas le compte root.

apt update && apt upgrade
apt install apache2

Pour rappel, le répertoire racine du service web Apache et du site par défaut se trouve dans le chemin /var/ www/html. Nous allons créer un répertoire "debian" dans ce dossier, et ce dernier contiendra toute l’arborescence de notre futur repository apt.

mkdir -p /var/www/html/debian

www-data, l'utilisateur par défaut d'apache, devra être le propriétaire du dossier "debian" . Effectuez les changements à l'aide de la commande suivante :

chown www-data:www-data /var/www/html/debian

III. Installation d'apt-mirror

L'étape suivante consiste à installer le paquet apt-mirror. Après avoir installé celui-ci, nous obtiendrons la commande apt-mirror, qui nous permettra de cloner (puis par la suite de synchroniser pour les mises à jour) le référentiel distant vers notre référentiel local.

apt install apt-mirror

Une fois qu'apt-mirror a été installé, nous allons passer à sa configuration. Avant de continuer, pour nous prémunir de toutes erreurs, faite une sauvegarde du fichier original de configuration (pour revenir en arrière si vous le souhaitez plus tard).

cp /etc/apt/mirror.list /etc/apt/mirror.list-bak

Modifiez maintenant le fichier à l'aide de l'éditeur de texte de votre choix et mettez à jour base_path et les référentiels comme indiqué ci-dessous.

A. Configuration d'apt-mirror

nano /etc/apt/mirror.list
############# config ##################
#
set base_path    /var/www/html/debian
#
# set mirror_path  $base_path/mirror
# set skel_path    $base_path/skel
# set var_path     $base_path/var
# set cleanscript $var_path/clean.sh
# set defaultarch  <running host architecture>
# set postmirror_script $var_path/postmirror.sh
# set run_postmirror 0
set nthreads     20
set _tilde 0
#
############# end config ##############

deb http://ftp.fr.debian.org/debian/ buster main contrib non-free
deb http://ftp.fr.debian.org/debian/ buster-updates main contrib non-free
deb http://ftp.fr.debian.org/debian/ buster-proposed-updates main contrib non-free
deb http://ftp.fr.debian.org/debian/ buster-backports main contrib non-free
deb http://security.debian.org/debian-security buster/updates main contrib non-free

# deb http://ftp.us.debian.org/debian unstable main contrib non-free
# deb-src http://ftp.us.debian.org/debian unstable main contrib non-free
# mirror additional architectures
#deb-alpha http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-amd64 http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-armel http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-hppa http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-i386 http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-ia64 http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-m68k http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-mips http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-mipsel http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-powerpc http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-s390 http://ftp.us.debian.org/debian unstable main contrib non-free
#deb-sparc http://ftp.us.debian.org/debian unstable main contrib non-free

clean http://ftp.us.debian.org/debian
Le fichier de configuration /etc/apt/mirror.list doit ressembler à cela

Ce fichier de configuration sera à adapter, si vous arrivez sur ce tutoriel et que votre version Debian est ultérieure à la version actuelle Buster (10.8) [Mars 2021]

Au cas où vous n'auriez pas remarqué, j'ai utilisé les dépôts de paquets Debian 10 principaux. Les autres resteront commentés, car ils ne sont pas forcément nécessaires dans le cas de ma démonstration.

B. Démarrez la mise en miroir des référentiels distants dans le dossier local

Avant de commencer le clone des paquets distants, il vous faut copier le script de post installation dans le répertoire /var/www/debian/var/ en utilisant les deux commandes ci-dessous.

mkdir -p /var/www/html/debian/var
cp /var/spool/apt-mirror/var/postmirror.sh /var/www/html/debian/var

Il est maintenant temps de commencer à mettre en miroir les packages des référentiels distants vers le dossier local de notre système. Exécutez la commande ci-dessous, mais évitez d'exécuter cette commande depuis un terminal ssh, ou bien augmenter le temps de timeout d'une session ssh, car le processus va prendre des heures :

apt-mirror

Et là, bah vous pouvez aller faire autre chose pendant quelques heures le temps que le téléchargement des paquets se fasse. Me concernant avec une connexion fibrée le téléchargement a pris plus de 12H... En fait, Debian bride le débit de download sur leurs serveurs.

C. Résoudre le bug 1 : security.debian.org/debian-security/dists/buster/updates/main/i18n/"Translation-en" 404 Not Found

Comme pour mon didacticiel pour Ubuntu, j'ai rencontré une erreur, impliquant un bug dans le code d'apt-mirror non résolu depuis belle lurette. Un problème remonté depuis Debian 8.X, de ce que j'ai pu voir sur les différents forums.

Afin de vérifier si vous avez le bug ou non, je vous invite à naviguer vers le chemin suivant :

Si vous n'avez pas le dossier i18n/, qui apparait, et bien cela veut dire que ce bug vous impacte aussi. À l'inverse, bingo, le bug a été colmaté. Le cas échéant, je vous demanderai de me faire signe dans les commentaires afin que je mette à jour l'article.

Pour résoudre celui-là, j'ai créé un petit script maison, qui vous permettra d'éliminer cette erreur :

cd /var/www/html/debian/mirror/security.debian.org/debian-security/dists/buster/updates/

Créez un script nommé fix1.sh :

nano fix1.sh

Ajoutez le code ci-dessous et terminez par exécuter la commande chmod dans votre console pour donner les droits d'exécution sur le fichier.

for dist in main contrib non-free; do
    wget http://security.debian.org/debian-security/dists/buster/updates/${dist}/i18n/Translation-en.xz;
    mkdir -p /var/www/html/debian/mirror/security.debian.org/debian-security/dists/buster/updates/${dist}/i18n
    mv Translation-en.xz /var/www/html/debian/mirror/security.debian.org/debian-security/dists/buster/updates/${dist}/i18n/
done
chmod u+x fix1.sh
Résultat de l'exécution du script.

D. Résoudre le bogue 2 : ftp.fr.debian.org/debian/dists/buster-backports/main/i18n/"Translation-en" 404 Not Found

Un bug peut en cacher un autre avec apt-mirror... Nous voici face au second bug que vous rencontrerez non pas avec le dépôt security.debian.org/debian-security, mais avec le dépôt ftp.fr.debian.org/debian/dist/buster-backport.

De nouveau, je vous invite à naviguer vers le chemin suivant :

Si vous n'avez pas le dossier i18n/, qui apparait, et bien cela veut dire que ce bug vous impacte aussi. À l'inverse, vous n'êtes pas concerné et c'est tant mieux ! Le cas échéant, je vous demanderai de me faire signe dans les commentaires afin que je mette à jour l'article.

Pour remédier à ce deuxième bug, voici la marche à suivre (sur le même principe que précédemment) :

cd /var/www/html/debian/mirror/ftp.fr.debian.org/debian/dists/buster-backports
nano fix2.sh

Au sein du script fix2.sh, ajoutez le code ci-dessous et terminez par ajouter les droits d'exécution avec chmod.

for dist in main contrib non-free; do
    wget http://ftp.fr.debian.org/debian/dists/buster-backports/${dist}/i18n/Translation-en.xz;
    mkdir -p /var/www/html/debian/mirror/ftp.fr.debian.org/debian/dists/buster-backports/${dist}/i18n
    mv Translation-en.xz /var/www/html/debian/mirror/ftp.fr.debian.org/debian/dists/buster-backports/${dist}/i18n/
done
chmod u+x fix2.sh

E. Planification de la synchronisation automatique des référentiels

Afin de maintenir votre dépôt local à jour, vous pouvez paramétrer sa mise à jour par l'intermédiaire d'une simple tâche cron. En effet, à chaque fois que notre dépôt local se synchronise avec le distant, s'il récupère de nouveaux paquets, ils sont automatiquement téléchargés, ainsi que leurs fichiers d'index.

Pour éditer la crontab :

crontab -e

Suivez scrupuleusement les directives suivantes :

00 01 * * * /usr/bin/apt-mirror >> apt-mirror-report.txt
00 02 * * * /var/www/html/debian/mirror/ftp.fr.debian.org/debian/dists/buster-backports/fix2.sh
01 02 * * * /var/www/html/debian/mirror/security.debian.org/debian-security/dists/buster/updates/fix1.sh

Comme vous pouvez le constater, la sortie de la première commande sera stockée dans le fichier /root/apt-mirror-syncing-execution-report.txt. Cela vous permettra de suivre s'il y a un problème lors de l’exécution du script sur le long terme. Les deux autres scripts font référence à des scripts qui colmatent les bugs dont je vous parlais ci-dessus. Il devront être exécutés à la suite de la commande apt-mirror.

IV. Configuration de Debian 10 pour utiliser un repository local

Dès lors, nous pouvons tester et vérifier si notre serveur de référentiel apt fonctionne correctement ou non, j'ai un autre système Debian 10 sur lequel je vais mettre à jour le fichier /etc/apt/sources.list afin que la commande apt pointe vers les référentiels locaux au lieu de ceux distants. Alors, connectez-vous au système Debian faisait office de poste client, et modifiez ce qui suit dans la liste sources.list

Mais avant tout, sauvegarder vos sources.list de base avec la commande ci-dessous, au cas où vous souhaitez revenir en arrière et utiliser un dépôt distant plus tard.

cp /etc/apt/sources.list /etc/apt/sources.list.backup

Supprimez le fichier puis recréer le.

rm /etc/apt/sources.list
touch /etc/apt/sources.list

Ouvrez le fichier avec l'éditeur de texte de votre choix.

nano /etc/apt/sources.list

A. Modification des sources.list

Effectuez un copier-coller du code ci-dessous dans le fichier sources.list, et modifiez l'IP de votre serveur hébergeant votre repository local.

deb [arch=amd64 trusted=yes] http://repository-local-ip/debian/mirror/ftp.fr.debian.org/debian/ buster main contrib non-free

deb [arch=amd64 trusted=yes] http://repository-local-ip/debian/mirror/ftp.fr.debian.org/debian/ buster-updates main contrib non-free

deb [arch=amd64 trusted=yes] http://repository-local-ip/debian/mirror/ftp.fr.debian.org/debian/ buster-proposed-updates main contrib non-free

deb [arch=amd64 trusted=yes] http://repository-local-ip/debian/mirror/security.debian.org/debian-security buster/updates main contrib non-free

deb [arch=amd64 trusted=yes] http://repository-local-ip/debian/mirror/ftp.fr.debian.org/debian/ buster-backports main contrib non-free

B. Tests - C'est l'heure de vérité !

Exécutez maintenant la commande « apt update » pour vérifier que la machine cliente reçoit la mise à jour de notre serveur de référentiel apt local

apt update

Parfait, la sortie ci-dessus confirme que la machine cliente est capable de se connecter avec succès à notre référentiel local pour récupérer les packages et les mises à jour.

Vous aurez des mises à jour à appliquer en fonction de si vous avez exécuté apt update && apt upgrade sur votre machine récemment ou non.

Vous pouvez aussi tester votre repository local en installant un service quelconque. Dans mon cas, le service squid proxy.

C. Postface

C'est tout pour cette fois-ci, j'espère que vous êtes arrivé au bout de ce tutoriel sans trop de mal. J'ai essayé d'être le plus clair possible dans mes explications, mais si vous rencontrez quand même des erreurs, lors d'apt update && apt upgrade, n'hésitez pas à rechercher votre erreur sur le net, en stipulant dans la requête que vous utilisez un repository local. C'est en partie comme ça que j'ai affiné le tutoriel, pour qu'il soit le plus clair possible.

The post Debian : comment créer son propre repository local ? first appeared on IT-Connect.

Git : Comment résoudre l’erreur « fatal : pathspec is in submodule »

3 mai 2021 à 13:00

I. Présentation

J’ai récemment réorganisé mes repository Git afin de me faciliter la vie. Plutôt que d’avoir un repository unique PowerShell, un autre Bash, un autre Python, etc, j’ai décidé de me créer un unique repository « Scripts », avec un sous-dossier par langage de scripting : Bash, Python, PowerShell.

J’étais confiant, j’y suis allé à vrai dire un peu vite, et ce qui devait arriver arriva : bim ! Une erreur ! Fatale en plus !

fatal: Pathspec '.\PowerShell\*' is in submodule 'PowerShell'

fatal: Pathspec '.\PowerShell\*' is in submodule 'PowerShell'

Restez avec moi si vous voulez savoir pourquoi cette erreur s’est affichée, et comment la corriger.

II. Prérequis

  • Git installé sur votre poste
  • Un repository distant de configuré (Github, Gitlab, Bitbucket sont les plus connus)

 

III. Explications de l’erreur fatale : Pathspec is in submodule

Jusqu’à aujourd’hui, j’avais 3 dossiers, répartis dans 3 repository Git distincts, pour stocker & gérer mes scripts :

  • Bash-scripts
  • Python
  • PowerShell

J’ai décidé de réunir ces 3 dossiers dans un nouveau repository Git, nommé « Scripts ».

Logiquement, et naïvement, j’ai donc créé un nouveau répertoire « Scripts » sur mon PC, et j’ai copié le contenu des 3 autres dedans, pour me retrouver dans la configuration suivante :

Que du classique lorsqu’on prépare un nouveau répertoire Git.

Me restait donc à initialiser le suivi du répertoire via Git :

cd E:\Repos\Scripts

git init

Une fois fait, il faut encore dire à Git quels sont les fichiers sur lesquels tracker les modifications. Ça s’effectue via la commande :

git add .

NOTE : Le . agit comme un ./* Il indique à Git de tracker tous les fichiers & sous-répertoires présents dans le répertoire de travail actuel.

 

Et c’est à ce moment-là que ça a commencé à coincer.

Mon dossier PowerShell était déjà tracké par Git, dans un autre repository, et il possédait toujours un dossier .git, avec la configuration associée.

Comme vous pouvez le voir sur la capture d'écran ci-dessous, les messages de git sont en général assez parlant. Dans notre cas, la solution nous est donnée. Enfin presque. Je vous dit tout dans un instant.

À ce stade, si vous vous entêtez, lors de votre premier commit, votre dossier « PowerShell » sera purement et simplement ignoré par Git.

Pourtant, le commit se passe bien, sans erreur.

 

Sauf que voilà : j’ai beau effectuer des modifications dans mon dossier PowerShell, git est censé les détecter, et m’afficher les changements lorsque j’utilise les commandes suivantes :

git diff

git status

Or, dans mon cas, Git me retourne un message m'indiquant qu'il n'y a eu aucun changement, et qu'il n'y a donc aucun intérêt à réaliser un commit : "nothing to commit, working tree clean".

nothing to commit, working tree clean

Et côté repository distant, sur Gitlab, je me retrouve avec un dossier PowerShell inaccessible alors que je devrais pouvoir le parcourir et avoir accès à tous mes scripts.

Vraiment, la loose !

Il y a une manière très simple de vérifier si vous avez bien la même erreur que moi. Essayez de rajouter le dossier ou le fichier dans les éléments trackés par Git :

git add ./PowerShell/*

Vous devriez alors obtenir l'erreur "fatal: Pathspec is in submodule".

fatal: Pathspec is in submodule

 

Et voilà : l’explication, c’est que mon dossier PowerShell contenait une configuration git existante. Donc lorsque j’ai initialisé git pour mon nouveau dossier Scripts, le dossier PowerShell, qui était déjà tracké, s’est automatiquement configuré en sous-module. Git considère alors que ce dossier PowerShell étant déjà suivi et ayant déjà des commit, il n'a aucun intérêt à le suivre une seconde fois, d'où le message d'erreur, et d'où le fait que mes modifications ne sont absolument pas détectées lorsque je fais un commit git.

IV. Comment corriger cette erreur ?

Maintenant, comment corriger cette erreur ? C’est très simple et ça ne vous prendra pas plus de 30 secondes.

Pour commencer, supprimez le dossier .git de votre dossier « PowerShell » s’il est encore présent.

Ensuite, vous allez faire oublier à Git le tracking de votre dossier en mode « submodule », en forçant git à supprimer son cache :

git rm --cached <nom-du-dossier>

 

NOTE : Si git est récalcitrant, vous pouvez utiliser le paramètre -f pour le forcer à supprimer son cache.

git rm --cached <nom-du-dossier> -f

 

Vous pouvez alors à nouveau ajouter le tracking git de votre dossier, et vérifier que les fichiers sont cette fois bien reconnus :

git add ./PowerShell/*

git status

Cette fois, on peut bien voir les modifications que j'ai apportées au contenu du dossier PowerShell : en vert les fichiers ajoutés (du point de vue de Git, par rapport au dernier commit).

Il ne vous reste plus qu’à faire votre git push pour envoyer vos données sur votre repository distant, et le tour est joué. ?

V. Conclusion

La prochaine fois que vous voudrez réorganiser vos repository Git, n’oubliez pas de vérifier la configuration Git du repository en question, afin d’éviter de créer par inadvertance des sous-modules là où il n’y en a pas besoin.

Pensez également à bien vérifier que tous les dossiers et fichiers qui vous intéressent sont bien intégrés à la liste des éléments trackés par Git, via la commande :

git status

Et si votre commit coince, votre premier réflexe est d’aller voir l’état de votre repository sur votre serveur distant, et également de regarder la configuration de votre repository Git local dans votre dossier .git.

The post Git : Comment résoudre l’erreur « fatal : pathspec is in submodule » first appeared on IT-Connect.

Linux : comment éviter d’entrer sa passphrase à chaque utilisation d’une clé SSH ?

30 avril 2021 à 13:00

I. Présentation

Pour s’authentifier et se connecter de manière sécurisée à un service ou un serveur, on a 2 possibilités sous Linux : le classique (et désuet) login / mot de passe, ou la clé SSH, protégée par une passphrase.

Plus besoin de se souvenir de 36 mots de passe différents : une clé SSH et c’est parti.

Oui, mais voilà : Quand on est amené à se connecter plusieurs fois par jour à des serveurs via SSH, ou qu’on effectue des rafraîchissements de son repository Git à partir du serveur, la passphrase nous sera demandée, systématiquement, à chaque nouvelle connexion.

Ce qui peut être vraiment lourd au bout de la cinquantième fois.

J’ai une astuce pour vous : vous connaissez Keepass ? Et bien on va reprendre le même principe : on va stocker de manière sécurisée la clé SSH ainsi que la passphrase dans un coffre sécurisé.

Ainsi, plus besoin de taper 50 fois votre passphrase chaque jour, vous ne la saisirez plus qu’une seule fois, au démarrage de votre système Linux. Et la magie fera le reste ! ?

Si vous souhaitez avec plus d'informations sur le système de clé privée/clé publique, je vous invite à lire ce cours écrit par Florian Burnel :

- Clés asymétriques : http://www.it-connect.fr/les-cles-asymetriques/

II. Prérequis

III. Vérifier la présence de la clé SSH

Pour commencer, on va vérifier que votre clé SSH est bien présente sur votre système Linux.

Pour cela, ouvrez un terminal, et tapez la commande :

ls -al ~/.ssh

Vous devriez voir apparaître plusieurs fichiers, celui qui nous intéresse étant id_rsa.

Note : ~ correspond au chemin de votre profil sous Linux, dans mon cas, il s’agit de : /home/thibault, comme on peut le voir sur la capture d’écran ci-dessus.

Avant d’installer et de configurer Keychain, une dernière chose à vérifier : votre clé SSH est une clé privée. Mais on va tout de même s’en assurer du côté des permissions de Linux :

On peut voir dans mon cas que ma clé privée (le fichier id_rsa) n’est pas vraiment privée. On va changer ça de suite, pour éviter des messages d’erreur de nos applications préférées :

sudo chmod 600 ~/.ssh/id_rsa

Note : Si vous n’êtes pas propriétaire des fichiers se trouvant dans votre dossier .ssh, il faudra vous réattribuer la propriété, sinon vous aurez des difficultés pour lire les fichiers.

Dans mon cas, mon nom d’utilisateur étant « thibault », cela donne :

sudo chown thibault :thibault ~/.ssh/id_rsa

On vient d’accorder des droits en lecture / écriture uniquement au propriétaire du fichier, et à personne d’autre. On ne peut pas faire plus privé. ?

IV. Installer et configurer Keychain pour sauvegarder automatiquement la passphrase

Ceux qui me connaissent savent que j'utilise Git pour le versioning de la totalité de mes scripts et des configurations serveurs / logiciels.

Et pour l'exemple, j'ai effectué un git clone, pour copier le contenu d'un répertoire distant (un repository) sur un répertoire local de mon poste. L'authentification s'effectue via ma clé SSH, et forcément, Git me demande de confirmer ma passphrase avant de lancer les actions.

Le truc particulièrement énervant, et notamment quand notre passphrase fait plus de 25 caractères, c'est que si je réexécute la même commande quelques secondes plus tard, je vais devoir à nouveau renseigner la passphrase.

Plutôt fastidieux, notamment lorsqu'on est dans mon cas et qu'on doit la renseigner plus de 50 fois par jour...

Pour éviter de taper encore et encore la même passphrase à chaque fois que l’on fait appel à notre clé SSH, on va s’installer Keychain, puis le configurer.

Pour l’installation, on reste sur du classique de chez classique :

sudo apt install -y keychain

Linux keychain ssh

Note : le -y indique de répondre « Oui » à la question : Êtes-vous sûr de vouloir continuer ? Une option particulièrement utile pour l’automatisation.

Pour vérifier que Keychain est bien installé sur votre système, tapez :

keychain --version

Il vous reste maintenant à modifier votre profil pour ajouter la configuration de keychain. Pour cela, ouvrez le fichier ~/.bashrc dans votre éditeur de texte préféré. Dans mon cas, j’utilise vim, mais libre à vous de passer sur d’autres éditeurs :

vim ~/.bashrc

Et ajoutez la ligne suivante à la fin du fichier :

eval ``keychain --eval --agents ssh id_rsa

À chaque fois que vous rebooterez votre serveur ou que vous démarrerez, un nouveau terminal, keychain s’exécutera.

À la première exécution suite à un reboot, keychain reconnaîtra votre clé SSH et vous demandera de saisir la passphrase :

Par la suite, à chaque nouveau terminal créé, keychain vous avertira qu’il a déjà en stock la clé SSH ainsi que la passphrase. Plus besoin de la taper du coup, keychain s’en chargera à votre place à chaque fois que le système en aura besoin pour se connecter à une ressource distante.

V. Conclusion

Comment s’en assurer ? Dans mon cas, je crée un nouveau répertoire de test et je relance la copie de mon repository Git avec la commande :

git clone <mon-lien-git>

Et pouf ! Par magie, ça se fait, sans action de ma part : plus besoin de taper ma passphrase tout au long de la journée. Je la saisis le matin en arrivant et c’est réglé.

Sacré gain de temps, n’est-ce pas ?

The post Linux : comment éviter d’entrer sa passphrase à chaque utilisation d’une clé SSH ? first appeared on IT-Connect.

Commande sudo : comment configurer sudoers sous Linux ?

29 avril 2021 à 12:30

I. Présentation

Dans ce tutoriel, je vais vous parler de la commande sudo sous Linux et de la configuration du fichier sudoers qui sert à déléguer des droits pour exécuter certaines actions sur la machine.

? Tutoriel disponible au format vidéo :

Lorsque l'on installe une distribution Linux, en l'occurrence Debian , que je vais utiliser tout au long de ce tutoriel, le système est livré avec deux utilisateurs :

  • Un compte "root" qui correspond au super-utilisateur de la machine, avec tous les droits
  • Un compte utilisateur membre du groupe sudo (dépend des distributions et du type d'installation) qui sera nécessaire pour utiliser la machine au quotidien. Ce compte prend le nom que l'on donne à l'installation

Le compte "root" quant à lui sert à configurer le système, installer de nouveaux paquets, etc... Toutes les tâches d'administration système, en fait.

Pour rentrer dans le vif du sujet, parlons de la commande "sudo" et de son intérêt au sein d'un environnement Linux.

II. La commande "sudo"

La commande "sudo" (substitute user do) permet à un utilisateur standard d'exécuter une action en se faisant passer par un autre utilisateur, par défaut "root". Autrement dit, un utilisateur standard peut effectuer une opération normalement réservée à l'utilisateur "root".

Prenons un exemple, pour éditer le fichier système "/etc/hosts" avec l'éditeur nano, il faut saisir cette commande :

nano /etc/hosts

Si je l'exécute à partir d'un utilisateur standard, en l'occurrence ici l'utilisateur "florian" un message va s'afficher pour m'indiquer que le fichier est ouvert en lecture seule, car je n'ai pas les autorisations pour l'enregistrer. Ce serait la même chose pour éditer un autre fichier système, redémarrer la machine ou redémarrer un service.

Maintenant, si j'exécute la commande suivante en ajoutant le préfixe "sudo" :

sudo nano /etc/hosts

Note : dans le cas où sudo n'est pas installé sur votre distribution, il faut procéder à son installation avec votre gestionnaire de paquets favoris, par exemple : apt-get install sudo

Je vais devoir saisir le mot de passe de mon compte "florian" et le fichier va s'ouvrir en écriture !

J'ai pu modifier ce fichier avec la commande "sudo", car l'utilisateur "florian" est membre du groupe "sudo". Avec la commande suivante, on peut vérifier que l'utilisateur est bien membre de ce groupe.

id florian

Il existe plusieurs façons de faire, on aurait pu exécuter cette commande également :

groups florian

La question que l'on peut se poser c'est : pourquoi les membres du groupe "sudo" ont le droit d'effectuer des actions d'administration sur la machine ? La réponse se situe au sein du fichier de configuration de "sudoers" qui se situe à l'emplacement suivant :

/etc/sudoers

Si l'on ouvre ce fichier, on remarque la présence de la ligne suivante :

%sudo     ALL=(ALL:ALL)  ALL

Groupe "sudo" dans /etc/sudoers

Le commentaire au-dessus de cette ligne parle de lui-même : autoriser les membres du groupe sudo à exécuter n'importe quelle commande (avec les droits super-utilisateur).

Passons maintenant à la configuration du fichier /etc/sudoers en lui-même.

Pour lister les autorisations d'un compte sous Linux, je vous oriente vers ce tutoriel en complément de celui-ci : Lister les autorisations d'un compte sous Linux

III. Configuration du fichier sudoers (/etc/sudoers)

A. Éditer la configuration de sudoers avec visudo

Pour modifier le fichier de configuration de sudoers, il y a un outil spécifique : visudo. En fait, on pourrait utiliser nano ou un autre éditeur de texte, mais la bonne pratique c'est d'utiliser visudo.

L'intérêt d'utiliser visudo, c'est que l'outil va verrouiller le fichier de configuration /etc/sudoers pour éviter d'être à plusieurs dessus, mais aussi, et c'est important, il va vérifier la syntaxe des règles ajoutées ou modifiées !

Pour modifier le fichier /etc/sudoers, on utilisera :

sudo visudo

ou

sudo visudo /etc/sudoers

B. Quel est l'intérêt de modifier la configuration de sudoers ?

Lorsque l'on souhaite attribuer des droits à un utilisateur, il y a la facilité : l'ajouter au groupe "sudo", mais ce n'est clairement pas la bonne solution. En fait, si l'on fait une comparaison avec Windows, cela revient à ajouter un utilisateur au groupe "Administrateurs" de la machine.

En configurant le fichier sudoers, on va pouvoir déléguer l'accès à certains fichiers, certaines commandes, à un utilisateur spécifique.

C. Syntaxe d'une règle sudo

Pour créer des règles, il faut respecter une syntaxe précise. Reprenons l'exemple du groupe "sudo" :

%sudo     ALL=(ALL:ALL)  ALL

Voici comment il faut l'interpréter :

Explications directive sudoers sudo

Ce qui permet de mieux comprendre aussi le commentaire associé à cette commande dans le fichier sudoers. Chacune de ces valeurs peut être modifiée pour affiner la règle.

Voici quelques précisions supplémentaires au sujet de la syntaxe :

➡  Utilisateur / groupe : pour spécifier un utilisateur, on indique tout simplement son identifiant, tandis que s'il s'agit d'un groupe on ajoute le préfixe "%". On spécifie un seul utilisateur ou groupe par ligne !

➡ Hôte : le fait d'indiquer ALL permet de dire que cette règle s'applique à toutes les machines

➡ Tous les utilisateurs : permet de spécifier l'utilisateur dont on prend les droits, avec "ALL" on englobe tous les utilisateurs y compris l'utilisateur "root" (ce qui nous intéresse)

➡ Tous les groupes : idem que pour les utilisateurs

➡ Toutes les commandes : permets de spécifier la ou les commandes que l'utilisateur (ou le groupe) spécifié en début de ligne peut exécuter sur la machine. S'il y a plusieurs commandes, il faut utiliser la virgule comme séparateur.

Note : ce qui est intéressant, c'est de donner des droits directement sur des groupes et ensuite d'ajouter le(s) utilisateur(s) à ce groupe.

D. Créer une nouvelle règle dans sudoers

Maintenant, prenons l'exemple d'un utilisateur standard, non membre du groupe "sudo" et nommé "itconnect". Nous allons lui donner les droits pour éditer le fichier /etc/hosts via nano.

Actuellement, la commande sudo ne me permet pas d'ouvrir ce fichier en écriture, car la directive est absente du fichier sudoers. Ce qui donne : "itconnect n'apparaît pas dans le fichier sudoers. Cet événement sera signalé".

À l'aide de l'utilisateur root (ou florian), on va modifier le fichier sudoers avec visudo et ajouter la ligne suivante :

itconnect ALL=(ALL) /usr/bin/nano /etc/hosts

Il est important de préciser qu'il faut indiquer le chemin complet vers le binaire, en l'occurrence ici "nano". Pour trouver facilement le chemin vers le binaire, utilisez la commande "which", par exemple :

which nano

Grâce à cette directive, l'utilisateur itconnect est en mesure de modifier le fichier /etc/hosts ! Il devra exécuter :

sudo nano /etc/hosts

Ensuite, il doit saisir son mot de passe. Il faut savoir que sudoers supporte l'option "NOPASSWD" : elle permet d'indiquer que l'utilisateur peut exécuter cette commande sans devoir saisir son mot de passe. Ce n'est pas recommandé, mais c'est une possibilité.

Si l'on reprend l'exemple précédent, cela donne :

itconnect ALL=(ALL) NOPASSWD:/usr/bin/nano /etc/hosts

Maintenant, pour aller un peu plus loin, voyons comment utiliser la notion d'alias avec sudoers.

E. Sudoers et le caractère d'exclusion "!"

Au sein d'une règle, le fait de spécifier "!" devant la commande va permettre de l'interdire. Par exemple, on peut autoriser l'utilisateur "itconnect" à modifier les mots de passe des utilisateurs, sauf pour l'utilisateur "root". Ce qui donnerait la règle suivante :

itconnect ALL=(ALL) /usr/bin/passwd, !/usr/bin/passwd root

La preuve en image ?

F. Sudoers et les alias

Si l'on regarde le début du fichier sudoers, on remarque plusieurs sections déclarées dans la première partie :

# Host alias specification
# User alias specification
# Cmnd_alias specification

Ces trois sections permettent de déclarer des alias pour les hôtes, les utilisateurs et les commandes. Par exemple, on peut créer un alias d'utilisateurs "ADMINS" et y associer plusieurs utilisateurs. Ensuite, dans les règles on peut utiliser cet alias plutôt que d'appeler les utilisateurs un par un ou de créer un groupe spécifique si l'on veut créer une règle commune à plusieurs utilisateurs.

Prenons un exemple... On va créer un alias d'utilisateur nommé "ADMINS" et qui va faire référence à deux comptes : itconnect et florian. Il faut bien séparer chaque nom par une virgule. Ce qui donne :

User_Alias    ADMINS = itconnect, florian

Ensuite, on va déclarer un alias de commande nommé "SYSTEM" et qui va faire référence à la commande "systemctl", mais il pourrait contenir plusieurs commandes. Ce qui donne :

Cmnd_Alias    SYSTEM = /usr/bin/systemctl

Enfin, pour créer une règle qui autorise les ADMINS à utiliser les commandes SYSTEM, cela donnera la règle suivante :

ADMINS ALL=(ALL)   SYSTEM

Les utilisateurs "itconnect" et "florian" peuvent désormais exécuter toutes les commandes associées à l'alias "SYSTEM".

G. Le dossier /etc/sudoers.d

Je souhaitais vous parler du dossier "/etc/sudoers.d" : il sert à stocker des fichiers déclaratifs pour sudoers qui seront lus en complément du fichier sudoers en lui-même. Attention, tous les fichiers qui contiennent "~" ou "." dans le nom ne seront pas lus ! C'est particulièrement intéressant pour organiser les règles par fichier plutôt que de tout centraliser dans le même fichier : le fichier sudoers sera toujours lu, dans tous les cas.

Pour créer un nouveau fichier nommé "ADMINS", on utilisera :

visudo /etc/sudoers.d/ADMINS

On pourrait tout à fait inclure nos alias et notre règle créés précédemment au sein de ce fichier.

H. Modifier le délai d'expiration de la commande sudo

Lorsque la commande "sudo" est utilisée, on précise le mot de passe du compte utilisateur à l'origine de l'action pour valider l'opération. Ensuite, si l'on exécute une nouvelle commande "sudo", le mot de passe n'est pas demandé, car l'accès reste déverrouillé pendant X minutes. Par défaut, cette valeur semble varier en fonction de la distribution utilisée, parfois 5 minutes, parfois 15 minutes.

Quoi qu'il en soit, il est possible de modifier cette valeur pour indiquer le délai d'expiration (timeout) que vous souhaitez pour sudoers.

Au sein du fichier sudoers, à la suite des autres lignes "Defaults", déclarez la ligne suivante :

Defaults      timestamp_timeout=5

Ce tutoriel sur l'utilisation de la commande sudo et de la configuration de sudoers sous Linux touche à sa fin. Maintenant, à vous de jouer !

PS : vous pouvez retrouver d'autres exemples sur cette page : Exemples Sudoers

The post Commande sudo : comment configurer sudoers sous Linux ? first appeared on IT-Connect.
❌