Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: Noyau

Niveau :      
Résumé : make menuconfig ; make ; make-kpkg

Un bon sysadmin doit savoir recompiler son noyau, et ce pour plusieurs raisons. Tout d'abord, c'est l'occasion de passer en revue les nouveautés (support d'un nouveau driver, changement d'architecture ...), c'est aussi comme ça qu'on peut ajouter les patchs dont on a besoin. Ensuite cela peut permettre de se passer de l'initrd (et donc de gagner une étape au boot) et enfin cela permet de faire des noyaux purement monolithiques si l'on veut renforcer la sécurité d'équipements critiques.

Avant de compiler un noyau, il faut le configurer. Cette étape est longue, très longue, surtout pour une première fois. Mais c'est aussi la plus intéressante. Je vais donc vous la présenter en long, en large, et surtout en travers. Si cela vous parait lourd, ne partez pas, sautez quelques étapes et revenez-y plus tard.

La base

Commençons par récupérer les sources du noyau. Personnellement je prends les sources officielles de Linus, simples à trouver :

# usuellement on se met dans /usr/src, mais ça n'a rien d'obligatoire
$ lftp ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.XXX.tar.bz2
# qu'on va décompresser
$ tar xfj linux-2.6.XXX.tar.bz2
$ cd linux-2.6.XXX

# les debianeux peuvent aussi avoir les sources patchés debian
$ apt-get install linux-source-2.6.XX

Nous allons récupérer la configuration actuelle du noyau pour partir sur des bases saines et ne pas avoir peur de tout casser si on saute une étape. Le fichier de configuration s'appelle .config

# la meilleur méthode si disponible : lire la configuration en live
$ zcat/proc/config.gz > .config
# sinon récupérer un ancien fichier
$ cp ../linux-2.6.XX-1/.config .
# ou celui fourni par la distrib
$ cp /boot/config-2.6.XX-1 .config

Lançons la configuration :

# en mode texte (il vous faut libncurses5-dev)
$ make menuconfig
# en mode graphique (qvec qt depuis quelque temps)
$ make xconfig 
# ou avec gtk
$ make gconfig

continue reading...

Niveau :      
Résumé : dmsetup

Maintenant que vous savez tout sur lvm, regardons sous le capot, pour voir comment ça tourne.

lvm

Lvm n'est en réalité qu'une surcouche à un système bien intégré dans linux et qui se nomme device-mapper ou dm en abrégé. Dm ne fait qu'une chose et il le fait bien : mapper (cartographier) un ou plusieurs périphériques de bloc sur un autre périphérique. Donc ce que fait lvm quand vous déclarez un nouveau lv, c'est uniquement déclarer à device mapper qu'un nouveau périphérique de bloc (le lv) correspond à telle et telle portion d'un périphérique physique (les pv).

Bon lvm fait un peu plus que ça puisqu'il sait faire tout ça tout seul au démarrage sans rien vous demander, il stocke ses informations au bon endroit sur les disques et tout marche de façon transparente. Mais supposons que nous voulions le faire nous-même à la main. C'est parfaitement possible avec la commande dmsetup :

# on crée un device nommé monlv, qui fait 10000 blocs et qui est mappé sur /dev/hda à partir du 1234e bloc
$ echo 0 10000 linear /dev/hda 1234 | dmsetup create monlv

Si vous voulez savoir comment sont fait vos lv, il suffit simplement de le demander à dmsetup :

$ dmsetup table /dev/mapper/vg0-lv0
>0 1028160 linear /dev/hda 0
>1028160 3903762 linear /dev/hdb 0

continue reading...

Niveau :      
Résumé : iptables -m timeout --timeout ; iptables -C

Bon léger retard. Après quelques erreurs de manip j'ai perdu mon patch indiqué précédemment. Ext3 contrairement à ext2 ne pardonne pas dans ce genre de situation. Heureusement photorec est mon ami et j'ai donc retrouvé mon patch.

La partie netfilter

Il s'agit d'un module netfilter permettant d'inclure des règles temporaires dans le firewall. Celles-ci ne matcheront que pendant une durée limitée. Par exemple vous voulez offrir temporairement un accès à votre serveur de photo classées Y à un ami :

$ iptables -A INPUT -s 192.168.2.1 -p tcp --dport 80 -m timeout --timeout 3600 -j ACCEPT

Si vous avez un outil (comme fail2ban) qui analyse vos logs et qui filtre les paquets de gens qui vous attaquent, vous pourrez lui indiquer que les règles sont temporaires (hé oui, si l'ip est une ip dynamique vous pouvez bloquer à vie quelqu'un qui ne devrait pas être bloqué).

$ iptables -A INPUT -s 192.168.2.1 -m timeout --timeout 86400 -j DROP

Je m'aperçois maintenant que j'aurai du nommer ce module ephemeral plutôt que timeout.

La partie iptables

Comme vous l'aurez compris, cela marche grâce à un nouveau match dans netfilter, ce qui veut dire que les règles ne disparaissent pas vraiment du firewall. C'est pourquoi le patch iptables intègre non seulement le traitement de --timeout mais ajoute aussi une nouvelle option. L'option -C permet de nettoyer les règles qui ne matcheront plus jamais. Il vous faudra donc l'utiliser régulièrement (par exemple dans cron.daily) pour éviter de trop encombrer votre firewall.

$ iptables -C
# ou
$ iptables -C INPUT

Les patchs

Maintenant vous voulez savoir comment faire pour avoir cet outil merveilleux. Tout d'abord téléchargez les 2 patchs en pièces jointes. L'un est pour le noyau, l'autre pour iptables. Ils ont été testés pour un linux 2.6.23, ils devraient marcher sur un 2.6.24 ou un 2.6.22, mais les changements sur netfilter font qu'il est peu probable qu'il marchent sur un noyau plus ancien.

Puis dans votre répertoire source linux tapez :

$ patch -p1 < timeout-linux.patch

Puis :

$ make menuconfig
# -> Networking  --->
#    Networking options  --->  
#    Network packet filtering framework (Netfilter)  --->
#    Core Netfilter Configuration  --->
#    rule timeout "match" support 

Et recompilez le module comme vous savez le faire (voire tout le noyau).

Maintenant même chose pour iptables

$ patch -p1 < timeout-iptables.patch

Et recompilez. N'oubliez pas de charger le module xt_timeout

$ modprobe xt_timeout

Et faire vos règles comme vous le désirez ...

Les patchs sont ici et .

Aujourd'hui, franchement à la bourre, pour rester dans le thème je vais vous parler rapidement de la célèbre technique dite de la rache

Cette technique est connue pour être la plus efficace pour votre travail. À expérimenter dès que le temps vous manque, vous verrez ça fonctionne à tous les coups. Si votre patron vous a rendu complètement inITIL, sachez que la rache ne respecte pas du tout ITIL. Par contre la rache est suffisamment flexible pour s'adapter à tous les types de projet, du plus grand au plus petit, du plus court au plus long. La rache c'est bon mangez-en.

Et pour les impatients, un aperçu du prochain article. J'ai écrit un patch à netfilter/iptables pour permettre de donner une durée de vie limitée à vos règles de firewall. Petit exemple :

# Une règle qui ne matchera plus dans 1h
$ iptables -A INPUT -s 127.0.0.1 -m timeout --timeout 3600 -J DROP

# Les règles ne matchant plus restant en mémoire, il faut les nettoyer de temps en temps
$ iptables -C INPUT

Niveau :      
Résumé : sysrq ; sysrq-trigger ; sysrqd

Sysrq, nom de la touche clavier pour system request (aussi connue sous le nom de print-screen). Les magic-sysrq sont une fonctionnalité optionnelle du noyau utilisant cette touche. Lorsqu'elle est compilée dans votre noyau et activée, elle est disponible en utilisant la combinaison de touche alt-sysrq-X où X est une touche du clavier.

Ces touches sont particulièrement utiles en situation d'urgence. Les plus importantes à mémoriser sont 'sub'. Une utilisation typique ressemblera plutôt à 'rfesiub' (pensez a laisser un peu de temps entre les touches).

Les touches les plus courantes sont :

  • b : reboot pur et simple de la machine
  • e : termine proprement (SIGTERM) tous les processus
  • f : tue un processus consommateur de mémoire (au hasard)
  • h : affiche l'aide si vous êtes en console (la touche espace aussi)
  • i : tue (SIGKILL) tous les processus
  • k : tue les processus lancés dans la console en cours (dont xorg si c'est le cas), Cela permet de récupérer l'accès au clavier. Certaines mesures de sécurité exigent de l'utiliser avant de se logguer en console pour tuer d'éventuels keyloggers.
  • r : réinitialise le mode de fonctionnement du clavier (à la suite d'un crash de xorg par exemple)
  • s : synchronise les systèmes de fichier (pour ne pas avoir de problèmes avant un reboot violent)
  • u : passe les systèmes de fichier en lecture seule
  • 0-9 : change le loglevel des messages du noyau

Et d'autres plus rares :

  • c : lance un kexec
  • d : affiche les locks en cours
  • m : affiche un dump mémoire
  • n : utilisé pour le temps réel
  • o : éteint la machine (ne marche pas toujours)
  • p : affiche les registres du processeur
  • q : affiche les timers
  • t : affiche des informations sur les processus
  • w : affiche les processus bloqués

Il est possible de désactiver l'usage de ces fonctionnalités

$ echo 0 > /proc/sys/kernel/sysrq

Ou plus finement avec un nombre supérieur à 1 (voir /usr/src/linux/Documentation/sysrq.txt).

Et si vous êtes à distance vous pouvez faire appel à une de ces fonctions en ligne de commande :

$ echo s > /proc/sysrq-trigger

Et si vous êtes encore plus à distance (ssh ne fonctionne plus), il y a aussi moyen de les déclencher avec sysrqd. Sysrqd est un démon qui doit tourner sur la machine (bloquée donc bon courage). Et à ce moment :

# port 4094
$ telnet crashed.machine sysrqd

Niveau :      
Résumé : syscall

Qu'est-ce qu'un appel système ?

Prenons le code suivant :

fopen("/tmp/toto", "r");

Ceci est simplement un appel de fonction, fonction écrite dans la libc et donc disponible à tout bon programme écrit en C (notez que le manuel de fopen est dans la section 3)

Prenons ensuite le code suivant :

open("/tmp/toto", O_RDONLY);

Ceci vous semble aussi être un appel de fonction comme les autres. Hé bien vous avez presque raison. En fait cette fonction est dans la libc, mais celle-ci ne fait que rediriger l'appel vers une fonction du noyau. C'est un appel système (syscall), notez cette fois que le manuel de open est dans la section 2.

Quels sont-ils ?

Il existe un grand nombre d'appels système. Tous sont numérotés, et ce numéro ne peut pas changer, en effet, le changer reviendrait à casser tous les binaires fonctionnant sous linux. Par contre, il arrive de temps en temps qu'un appel système soit ajouté, mais ce genre de chose est toujours étudié en profondeur, car cela signifie qu'il devra être maintenu à vie par les développeurs du noyau. C'est ce qu'on appelle l'API stable du noyau.

Parmi les appels système, on trouve de tout, enfin tout ce qui est du ressort du noyau. Vous pourrez en trouver la liste dans les sources. Toutes les fonctions concernant le système de fichiers, le réseau, les droits, les utilisateurs ou les processus se retrouvent ici.

Comment ça marche ?

L'implémentation d'un appel système dépend complètement du processeur. En effet, il faut une instruction qui offre quelques garanties au noyau pour permettre son bon fonctionnement.

Ces garanties sont des privilèges particuliers accordés au code au code appelé. Par exemple, le code appelé peut avoir des droits d'accès au matériel et il ne peut pas être modifié par le code appelant.

Intéressons-nous à des processeurs assez répandus, les x86. L'instruction qui nous intéresse est l'interruption (int). Linux a choisi l'interruption 80 pour mettre en place ses appels système. Mais tout ceci est caché par la libc qui fait elle-même l'appel. Mais l'instruction int est infiniment lente et Intel a décidé de fournir une autre instruction du même style, en plus rapide (sysenter). Il fallait donc une méthode pour que linux utilise cette nouvelle instruction sans pour autant casser les logiciels existants.

Linus a choisi de permettre les appels système sans avoir à se se poser la question de la méthode à utiliser. Depuis linux 2.5, tous les processus disposent d'une page spéciale créée par le noyau contenant le code pour faire l'appel système. Et c'est lui qui choisi la meilleure méthode disponible. On appelle cette page la VDSO (Virtual Dynamically-linked Shared Object). C'est elle que vous voyez lorsque vous faites un ldd sur un exécutable et qu'il contient l'une de ces lignes :

linux-gate.so.1 =>  (0xffffe000)
linux-vdso.so.1 =>  (0x00007fffa6dfe000)

PS : int 80 reste disponible sur toutes les version de linux

PPS : fopen fait appel à open en interne

PPPS : pour mémoire dos avait choisi l'interruption 21 pour ses propres fonctions

Niveau :      
Résumé : cat /dev/vcs1

Parfois, vous voulez lire le contenu de la console d'une machine, par exemple si vous êtes sur une machine distante et que vous vouliez vérifier ce qui se passe, ou que vous êtes une grosse feignasse qui refuse de taper ctrl-alt-f1. Enfin vous pourrez aussi lire ce qui se passe sur le terminal qui est derrière votre serveur X (en général rien). Alors je vais tout vous expliquer.

Linux propose plusieurs device pour lire ses terminaux. Ils s'appellent /dev/vcsX et /dev/vcsaX. Selon les systèmes, il peuvent aussi se trouver dans le répertoire /dev/vc/X (X étant le numéro du terminal).

Il existe plusieurs méthodes pour en lire le contenu, il faut dans tous les cas être root pour le lire (ls -l /dev/vcs* pour vérifier). Tout d'abord intéressons-nous à vcs1, celui-ci contient uniquement le texte du terminal.

À l'ancienne :

# 1 pour le premier terminal et fd/1 pour stdout
$ setterm -dump 1 -file /proc/self/fd/1

Méthode ultra simple, attention, il faut que votre terminal en cours fasse la même largeur que le terminal à lire (en général 80 colonnes) :

$ cat /dev/vcs1

Même chose mais sans les inconvénients :

$ fold -w 80 /dev/vcs1 && echo -e "n"

Mais tout ceci n'inclue pas les couleurs ni la position du curseur. vcsa1 contient ces informations. Pour les afficher proprement je vous ai préparé un petit script perl.


continue reading...