= Système d'automatisation = Ce module couvre les principaux objectifs de script pour l'examen LPI 201. Vous n'avez pas besoin d'apprendre un nouveau langage comme perl ou bash. Tout ce qui est attendu est de décrire avec précision ce qu'est un script. La connaissance de la syntaxe exacte pour une langue spécifique de script n'est pas prévu. La meilleure façon de s'entraîner pour cela est de passer par quelques exemples. Pour cela, nous allons mettre en œuvre les tâches automatisées suggérées dans les objectifs LPI. ## ## États possibles du document ## ## {a_trad} -> à traduire (disponible) ## {traduc} -> en cours de traduction ## {a_reli} -> à relire ## {relect} -> en cours de relecture ## {publie} -> publié (à jour) ## {a_revi} -> à réviser (à mettre à jour) ## '''État''' : {a_reli} [[../|Retour au document principal]] <> '''Pré-requis''' * Niveau LPIC 1 == 1. Rédaction de simples scripts perl (utilisation de modules) == La documentation en ligne pour perl est contenue dans le paquet '''perldoc'''.Les pages de manuel sont divisées en sections. Par exemple, la section '''perlintro''' peut être consulté avec: {{{ man perlintro }}} Ou {{{ perldoc perlintro }}} Voici un résumé de ce perldoc: {{{ Un script Perl doit être en lecture et exécutable. La première ligne du script doit pointer vers l'interpréteur. Par exemple si vous voulez pointer sur ''/usr/bin/perl'', la première ligne dans le script doit être : #!/usr/bin/perl }}} Il existe trois types de variables qui peuvent être déclarées et référencé comme dans le script qui suit: {{{ # Scalars (scalaire) my $VARIABLE = “value”; #déclare la VARIABLE print (“$VARIABLE \n”); #affiche VARIABLE }}} {{{ # Arrays (tableau) my @ARRAY = (“color1”,”color2”,”color3”); # déclare le tableau $index=0 # print ARRAY while ($index < @ARRAY) { print (“element of $index is @ARRAY[$index] \n”); $index++; } }}} {{{ # Hashes or Associative Arrays (hachage ou tableau associé ) ({key,value} pairs) my %HASH=(“color1”, “blue”,”color2”, “red”, “color3”, “white”); foreach $key (keys %HASH) { print (“The key $key corresponds to the value $HASH{$key} \n”); } @color_rank = sort keys %HASH; # assign the keys to an array }}} == 2.En utilisant le module Perl taint pour sécuriser les données == Le module '''taint''' est utilisé pour vérifier que les variables externes fournies par l'utilisateur ne peuvent pas être utilisés pour exploiter le système. Ce module est automatiquement utilisé lors de l'exécution des scripts qui ont le bit setuid ou setgid activé. Il est possible de forcer un script perl pour passer le module '''taint''' avec l'option '''-T'''. Par exemple l'appel système ci-dessous permettra à tout utilisateur de lire des fichiers avec un accès en lecture: ||'''insecure.pl'''|| {{{ #!/usr/bin/perl $FILENAME=ARGV[0] # C'est l'équivalent de $1 en bash system(“/usr/bin/less”, $FILENAME); }}} Si le script est par le SUID root ou si l'option '''-T''' est utilisée, alors le module '''taint''' sera appelé et ce script ne s'exécutera pas. ||'''check-secure.pl'''|| {{{ #!/usr/bin/perl -T $FILENAME=ARGV[0] # this is the equivalent to $1 in bash system(“/usr/bin/less”, $FILENAME); }}} En fait, le script check-secure.pl n'est pas sécurisé, il aura tout simplement pas fonctionner avec le SUID root ou l'option '''-T'''. Ici cette version de ''insecure.pl'' qui travaillent autour du mécanisme '''taint''' et vraiment PAS Sécurisé !!! {{{ if (open (FILE,"$FILENAME")) { $line = ; while ($line ne "") { print ($line); $line = ; } } }}} == 3.Installation du module Perl (CPAN) == Lisez les pages suivantes de perldoc pour informations sur les modules perl : {{{ man perlmod }}} Un ensemble de fonctions spécifiques peuvent être écrites sous forme de modules et importés dans les nouveaux scripts avec la directive: {{{ use module }}} Il y a deux méthodes disponibles pour télécharger, compiler et installer des modules de www.cpan.org '''Méthode 1:''' Les modules peuvent être téléchargés a partir de www.cpan.org et construit de la manière suivante : Décompresser l'archive et écrire : {{{ perl Makefile.pl make make test make install }}} '''Méthode 2:''' Utiliser l'outil '''cpan''' Nous pouvons configurer interactivement CPAN de la manière suivante : {{{ cpan }}} {{{ CPAN is the world-wide archive of perl resources. It consists of about 100 sites that all replicate the same contents all around the globe. Many countries have at least one CPAN site already. The resources found on CPAN are easily accessible with the CPAN.pm module. If you want to use CPAN.pm, you have to configure it properly Are you ready for manual configuration? [yes] This can also be done with the commandline CPAN build and cache directory? [/root/.cpan] How big should the disk cache be for keeping the build directories with all the intermediate files? Cache size for build directory (in MB)? [10] Where is your gzip program? [/bin/gzip] Where is your tar program? [/bin/tar] Where is your unzip program? [/usr/bin/unzip] Where is your make program? [/usr/bin/make] Where is your links program? [/usr/bin/links] Where is your wget program? [/usr/bin/wget] Warning: ncftpget not found in PATH Where is your ncftpget program? [] /usr/bin/lftpget Now we need to know where your favorite CPAN sites are located. [...] (1) Africa (2) Asia (3) Central America (4) Europe (5) North America (6) Oceania (7) South America Select your continent (or several nearby continents) [] 4 [...] cpan shell -- CPAN exploration and modules installation (v1.7601) ReadLine support available (try 'install Bundle::CPAN') cpan> install [...] }}} Une fois que CPAN est configuré, nous pouvons installer des modules en ligne de commande {{{ perl -MCPAN -e “install MODULENAME” }}} Les modules sont installés dans les sous-répertoires de '''/usr/lib/perl'''. On peut vérifier si un module spécifique est installé avec: {{{ perl -MMODULENAME -e 1 }}} Pour un exemple d'application utilisant des modules perl voir l'annexe. == 4.Vérifier l'exécution des processus == Une recherche dans la sortie de '''ps''' pour un processus en utilisant '''grep''' retourne parfois un état positif, même si le processus ne fonctionne pas! Cela est dû au fait que le processus lui-même, ici '''grep''' est parfois imprimé par '''ps'''. Comme dans l'exemple ci-dessous: {{{ ps au|grep junk root 13643 0.0 0.2 1724 600 pts/1 S 11:22 0:00 grep junk }}} Inutile de dire qu'il n'y a pas d'outils pré-installés appelé junk en général, de sorte que la ligne ci-dessus reviendrait à une évaluation positive dans un script! Il y a un travail autour de ce problème. __Utilisation de pgrep__ Cet outil recherche les sortie de '''ps''' pour les PIDs des processus qui correspondent à la recherche des critères. Par exemple: {{{ ps aux | pgrep -u root httpd }}} Ceci correspondra à tous les processus '''httpd''' géré par l'utilisateur '''root'''. On peut également utiliser '''pgrep''' comme '''grep''' avec un seul mot clé. __Use |grep -v grep__ En canalisant la sortie de '''ps''' en ''grep -v grep'' peut empêcher '''grep''' de se trouver. Cela ne fonctionnera pas toutefois si le processus que vous surveillez contient la chaîne ''grep''. {{{ ps aux | grep smbd | grep -v grep }}} == 5.Le contrôle des processus et générer des alertes == Cet objectif nous donne l'occasion d'utiliser les capacités de contrôle de flux avec bash pour faire un choix lors de la vérification de l'état d'un processus donné. Disons que nous voulons vérifier que le démon smbd est en cours d'exécution, puis redémarrez-le et envoyez un message si il est arrêtée, et ne rien faire si il est toujours en cours d'exécution. Le script suivant sera: {{{ #!/bin/bash PROCESS=smb if ps aux | grep "$PROCESS" | grep -v grep >/dev/null ; then echo Process $PROCESS is running else echo Process $PROCESS is stopped – Restarting it ... /etc/rc.d/init.d/smb start > /dev/null fi }}} Vérification de la réponse d'un hôte à l'aide de '''ping''': {{{ #!/bin/bash while (true) do #obtenir le temps de 10 sorties de ping x=$(ping -c 10 $1 | cut -d"=" -f4 | tail +2|head | sed "s/ms//") #Vérifie dans une boucle ceux qui sont plus long que 14ms for times in $x do dectimes=$(echo $times | cut -d. -f1) # obtenir un nombre entier if [ $(($dectimes-14)) -gt 0 ]; then echo Time exceeded 14ms: $times fi done done }}} === Script annexe pour analyser les fichiers journaux et les envoyer par courriel === Nous pouvons utiliser un script perl pour exécuter un ordre de lecture dans '''/var/run/utmp''' et obtenir une recherche qui correspondent à tous les utilisateurs connectés et envoyer la ligne a root. {{{ #!/usr/bin/perl $LOGFILE="/tmp/lastlog"; $line="0"; system("last> $LOGFILE"); open (MAIL, "| mail root"); if (open (FILE,"$LOGFILE")) { while ($line ne "") { $line=; if ($line =~ still) { print MAIL $line; } } } close MAIL; }}} Si ce script doit s'exécuter toutes les heures et qu'il est appelé /usr/bin/last-log.pl, alors vous pouvez créer un lien symbolique dans '''/etc/cron.hourly''' pointant vers lui. === Surveiller les fichiers modifiés et de générer des alertes e-mail === Une empreinte digitale de 128 bits (ou "message-digest) pour un fichier peut être calculée avec '''md5sum'''. Le script suivant va vérifier le checksum MD5 de tous les fichiers dans '''/etc''' et comparer les sortie avec diff. S'il y a des différences, les fichiers modifiés sont envoyés à l'utilisateur root. {{{ #!/bin/bash touch /tmp/md5old touch /tmp/md5new mv /tmp/md5new /tmp/md5old for files in $(find /etc -type f ) do md5sum $files >> /tmp/md5new done x=$(diff /tmp/md5old /tmp/md5new) if [ -z "$x" ]; then break else echo $x |mail root fi }}} Notez que la première fois que vous exécutez ce script tous les fichiers seront considérés comme changés! La vérification de fingerprint MD5 valide peut être effectuer a partir de l'entrée standard (STDIN) ou a partir d'une liste pré-calculé utilisant '''md5sum -c''' (--check). Nous avons d'abord calculer ces montants avec : {{{ find /etc -type f | xargs md5sum > etc-md5.dat }}} Nous allons ensuite transmettre le contenu de ''etc-md5.dat'' à '''md5sum -c'''. Si par exemple on supprime quelques lignes vides dans '''/etc/sysctl.conf''', nous pouvons voir que quelque chose a changé avec : {{{ md5sum -c etc-md5.dat | grep -v OK /etc/sysctl.conf: FAILED md5sum: WARNING: 1 of 1906 computed checksums did NOT match }}} === Écrire un script qui avertit les administrateurs lorsque quelqu'un connecte ou se déconnecte === Il n'est pas une bonne idée de poster toutes ces informations, mais il est possible de les rassembler et, éventuellement, les formater en utilisant XML ou HTML. Ici, nous lisons à partir d'une liste d'utilisateurs que nous voulons suivre le fichier ''/etc/checks'' et envoyer un e-mail dès qu' ils sont connectés. Cela peut fonctionner grâce à un cron toutes les minutes. Cela signifie que quand quelqu'un de la liste est connecté, un e-mail à chaque minute sera envoyé! {{{ #!/bin/bash for luser in $(cat /etc/checks) do x=$(last |grep $luser|grep still) if [ -n "$x" ]; then echo User $luser is logged in | mail root; fi done }}} == 6.Utiliser Rsync == Rsync fonctionne comme une commande '''rcp''' ou '''scp''' optimisé. Il permet de copier seulement dans le répertoire de destination, les fichiers qui sont manquants ou ont été modifiés dans le répertoire source. Même avec des fichiers modifiés '''rsync''' enverra seulement la différence entre les deux fichiers. Les syntaxes sont : {{{ rsync SRC HOST:/DEST rsync HOST:/SRC DEST }}} On peut changer la valeur de la variable de shell distant ''RSYNC_RSH'' utilisé par rsync: {{{ export RSYNC_RSH=ssh }}} Voici un exemple de script utilisant '''rsync''' pour garder "Fedora à jour" par des mises à jour sur le serveur local: {{{ #!/bin/sh cd /var/ftp/pub/updates/fedora ( date echo echo "=== Sync Files ===" rsync -vaz --delete --delete-excluded --exclude="*/debug/*" rsync://rsync.mirror.ac.uk:873/download.fedora.redhat.com/pub/fedora/linux/core/up dates/1/ linux/core/updates/1/ 2>&1 echo "=== Sync Files Done ===" echo date ) | mail -s "Fedora Updates Sync Results" andrew@anvil.org }}}