← Semaine 14
semaine 14 - regex et textes

Fouiller et transformer les textes

Les fichiers de config, les logs, les sorties de commandes : tout est texte sur un serveur. Cette semaine, vous devenez chirurgien du texte avec les regex, grep, sed et awk.
la methode - etape 1

La méthode des moutons : constante et variable

On veut détecter à la fois :

/liste/mouton /liste/moutons /liste/mouton/ /liste/moutons/
La partie constante
/liste/mouton - présente dans TOUS les cas.
Les parties variables
Le « s » à la fin, et le « / » final - parfois là, parfois pas.
Toute regex commence par cette question : qu'est-ce qui ne bouge jamais, qu'est-ce qui varie ?
la methode - etape 2

Ajouter les multiplicateurs

# 1. La partie constante /liste/mouton # 2. Le s optionnel (? = 0 ou 1 fois) /liste/moutons? # 3. Le / final optionnel /liste/moutons?/? # 4. Le symbole de fin de chaine /liste/moutons?/?$

Les multiplicateurs à connaître : ? (0 ou 1), + (1 ou plus), * (0 ou plus), et les crochets [0-9] (un caractère de l'ensemble).

la methode - etape 3

Capturer un chiffre : /mouton/[0-9]+/

Pour détecter /mouton/4/, /mouton/7/, /mouton/44/...

# La constante : /mouton/ ... / # La variable : le chiffre entre les deux barres /mouton/[0-9]+/$ # [0-9] = un chiffre, + = un ou plusieurs, $ = fin

Puis on l'insère dans la fonction match en échappant les / avec des \ :

if( requete.url.match(/\/mouton\/[0-9]+\/$/) )
la methode - etape 4

Isoler une valeur : les parenthèses

# Les parentheses CAPTURENT ce qu'elles entourent if( trouvailles = requete.url.match(/\/mouton\/([0-9]+)\/$/) ) # Le resultat est un tableau : trouvailles[0] # toute la chaine matchee trouvailles[1] # la premiere parenthese -> le chiffre ! trouvailles[2] # la seconde parenthese, etc. var id = trouvailles[1];
C'est exactement ainsi qu'un serveur web extrait le « 42 » de /mouton/42/ pour aller chercher le bon mouton dans la base de données.
grep

grep : chercher les lignes qui contiennent

# Syntaxe generale $ grep 'motif' fichier # En pipeline (le cas le plus frequent) $ ps aux | grep sshd # Les options a connaitre $ grep -i 'motif' fichier # ignorer la casse $ grep -v 'motif' fichier # lignes INVERSES $ grep -rn 'motif' /etc/ # recursif avec numeros de ligne $ grep -c 'motif' fichier # COMPTER les lignes
grep - pieges

grep : à retenir et pièges

À retenir
  • grep filtre des LIGNES, pas des mots isolés
  • Sensible à la casse par défaut : -i pour ignorer
  • Les options se combinent : -rn, -iv...
  • Le motif peut être une chaîne simple ou une regex
Pièges à éviter
  • Oublier les guillemets quand le motif a des espaces
  • Confondre -v (inverse) et -i (casse)
  • Vouloir REMPLACER avec grep : ça, c'est le travail de sed !
sed

sed : la substitution s///

# UNE commande a connaitre : la substitution $ sed 's/motif/remplacement/flag' fichier $ cat fichier | sed 's/ancien/nouveau/g' # Les flags : s/a/b/ # remplace UNE fois par ligne s/a/b/g # remplace TOUTES les occurrences (global) s/a/b/i # sans attention a la casse # Modifier le fichier directement (prudence !) $ sed -i 's/ancien/nouveau/g' fichier
Le piège classique : oublier le g et ne remplacer qu'une occurrence par ligne. Et -e se met devant CHAQUE expression, pas une seule fois pour toutes.
awk

awk : l'extracteur de champs

awk sait filtrer, remplacer, extraire, formater. Dans ce cours : on se concentre sur l'extraction de champs.

# Extraire le champ 2 (le PID) $ ps aux | grep sshd | awk '{print $2}' # Plusieurs champs d'un coup $ ps aux | awk '{print $1, $2, $11}'
awk
Gère naturellement les espaces multiples. awk '{print $5}' et c'est réglé.
cut
A besoin d'un délimiteur exact : il faut souvent tr -s ' ' avant. (Semaine 13 !)

Hors-sujet BEGIN/END, boucles, fonctions : awk est presque un langage complet, on n'en utilise ici QUE l'extraction.

cas concret

Analyser un log : démasquer les attaquants

Votre serveur note chaque tentative SSH ratée dans /var/log/auth.log :

# Les tentatives ratees $ sudo grep "Failed password" /var/log/auth.log | head -n 3 # Extraire l'IP de chaque ligne, compter par IP, trier $ sudo grep "Failed password" /var/log/auth.log \ | awk '{print $(NF-3)}' \ | sort | uniq -c | sort -rn | head
Le palmarès des IP qui attaquent votre serveur ! C'est exactement ce travail que fail2ban (semaine 0) automatise pour vous, ligne de log par ligne de log.
le partage des roles

Qui fait quoi dans la famille texte

grep
CHERCHE les lignes. Le filtre horizontal.
sed
REMPLACE dans les lignes. Le transformateur.
awk
EXTRAIT les colonnes. Le découpeur intelligent.
sort, uniq, wc
TRIENT, dédoublonnent, comptent. Les statisticiens.
# Et ensemble, ils font des miracles : $ commande | grep motif | awk '{print $2}' | sort | uniq -c | sort -rn
resume

Le texte n'a plus de secrets

La méthode
Constante, variable, multiplicateur, $ de fin, parenthèses pour capturer.
Les outils
grep cherche, sed remplace, awk extrait.
Le réflexe
Tout log se fouille, tout config se transforme, en une chaîne de pipes.

Au laboratoire de la semaine 14 : construisez vos regex et faites parler les logs de votre VPS !