Synchronisation des listes noires de forums phpBB (avec PostgreSQL 8.1)

En bref

Ce script lit les listes noires de plusieurs sites phpBB et les synchronise.

Les listes synchronisées sont les listes des adresses IP et des adresses électroniques bannies. Les noms d'utilisateurs bannis ne sont pas synchronisés, car phpBB gère une liste de noms de comptes locale à la base qu'il n'est pas possible simplement de transposer dans une autre base.

Limitations

Ce script ajoute les entrées supplémentaires d'une liste aux autres listes. Il ne synchronise pas les suppressions. Donc, les listes ne peuvent que grossir. Une entrée supprimée sera automatiquement restaurée par la prochaine synchronisation.

Précautions d'emploi et avertissements

/!\ Attention ! N'utilisez pas ces commandes sans avoir préalablement réalisé une sauvegarde de votre base de données (en plus, avec PostgreSQL, c'est très simple — cf. les commandes pg_dump et pg_dumpall).

/!\ Dans tous les cas, l'utilisation de ces scripts se fait à vos risques et périls.

Installation

Éditez le script et modifiez la variable BASES, en indiquant la liste de vos bases de données phpBB.

Ce script suppose que l'utilisateur en cours peut se connecter à PostgreSQL sans utiliser de mot de passe. Si ce n'est pas le cas, quelques adaptations mineures sont nécessaires.

Le script fusion.sh

# Auteur :   Jean-Philippe Guérard
# Adr. él. : jean TIRET philippe POINT guerard CHEZ tigreraye POINT org
# Date :     $Date: 2007/04/27 23:51:22 $
# Version :  $Revision: 1.3 $

# $Id: fusion.sh,v 1.3 2007/04/27 23:51:22 fevrier Exp fevrier $

# Ce script lit les listes noires de plusieurs
# sites phpBB et les synchronise.

# Les listes synchronisées sont les listes des adresses IP
# et des adresses électroniques bannies. Les noms
# d'utilisateurs bannis ne sont pas synchronisés, car phpBB
# gère une liste de noms de comptes locale à la base qu'il
# n'est pas possible simplement de transposer dans une autre
# base.

# Liste des bases (remplacez ces bases par vos propres bases)

BASES="forum1 forum2 forum3"

# Choix du niveau de détail par défaut
# 0 -> Pas d'information, à part les messages d'erreur
#      des commandes utilisées.
# 1 -> Affichage en clair des entrées ajoutées aux bases
# 2 -> Affichage en format brut des entrées ajoutées aux bases

[ -z "${NIVEAU_DE_DETAIL}" ] && NIVEAU_DE_DETAIL=1

# Création du répertoire de travail

TEMP=$(/bin/mktemp -d) || exit 1

/bin/mkdir -p "${TEMP}/ajouts"

# Automatisation du nettoyage du répertoire de travail

nettoyage() {

  /bin/rm -rf "${TEMP}"
  trap - EXIT

}

trap nettoyage EXIT

# Vidage du contenu de la table de bannissement
# L'utilisation de la fonction COPY permet de gérer
# proprement l'échappement des caractères

extraction() {

  typeset BASE="${1}"

  /usr/bin/psql "${BASE}" -A -t \
      -c "COPY phpbb_banlist ( ban_ip , ban_email ) TO STDOUT" | \
    /usr/bin/gawk -F '\t' '( $1 != "\\N" ) || ( $2 != "\\N" ) { print }'

}

# Création de la liste globale et des listes propres à chaque
# base (merci tee). La liste globale et les listes par base
# sont triées et les entrées en double sont supprimées.

LISTE_GLOBALE="${TEMP}/liste-globale.txt"

( for i in ${BASES} ; do

  extraction "${i}" | \
      /usr/bin/sort | \
      /usr/bin/uniq | \
      /usr/bin/tee "${TEMP}/${i}.txt"

  done ) | /usr/bin/sort | /usr/bin/uniq > "${LISTE_GLOBALE}"

# Recherche des entrées manquantes

for i in ${BASES} ; do

 # On calcule la liste des entrées manquantes de
 # la base en cours, tout simplement en utilisant
 # la commande diff

 /usr/bin/diff "${TEMP}/${i}.txt" "${LISTE_GLOBALE}" | \
     gawk '/^>/ { sub( "^> " , "" ) ; print }' > "${TEMP}/ajouts/${i}.txt"

 # Si il y a des lignes à ajouter, impression
 # des entres à ajouter

 if [ -s "${TEMP}/ajouts/${i}.txt" ] ; then

   if [ "${NIVEAU_DE_DETAIL}" -ge 1 ] ; then

     # Calcul du nombre de ligne pour
     # l'affichage du bilan

     NB_LIGNES=$(/usr/bin/wc -l "${TEMP}/ajouts/${i}.txt" \
                   | gawk '{ print $1 }')

     if [ "${NB_LIGNES}" -ge 2 ] ; then

       LIGNES="lignes"

     else

       LIGNES="ligne"

     fi

     /bin/echo
     /bin/echo "Base ${i} : ${NB_LIGNES} ${LIGNES} à ajouter"
     /bin/echo

     # Impression du résultat brut

     if [ "${NIVEAU_DE_DETAIL}" -ge 2 ] ; then
       /bin/echo "Données brutes à ajouter"
       /bin/cat "${TEMP}/ajouts/${i}.txt"
       /bin/echo

     fi

     # Impression du résultat en clair

     /bin/cat "${TEMP}/ajouts/${i}.txt" | \
       /usr/bin/gawk -F '\t' '

         # Extraction du nombre hexadécimale situé à la
         # position indiquée, conversion en décimal,
         # puis remplacement des 255 par le motif « * »

         function decode_composant_IP_phpBB( IP_phpBB, position,    nombre )
         {
             nombre = strtonum( "0x" substr( IP_phpBB, position, 2 ) )
             if ( nombre == 255 ) nombre="*"
             return nombre
         }

         # Décodage d une adresse IP telle que codée par phpBB

         function decode_IP_phpBB( IP_phpBB,    A, B, C, D )
         {
             A = decode_composant_IP_phpBB( IP_phpBB, 1 )
             B = decode_composant_IP_phpBB( IP_phpBB, 3 )
             C = decode_composant_IP_phpBB( IP_phpBB, 5 )
             D = decode_composant_IP_phpBB( IP_phpBB, 7 )
             return A "." B "." C "." D
         }

         ( $1 != "\\N" ) {
             print "Ajout de l\047adresse IP : " decode_IP_phpBB( $1 )
         }

         ( $2 != "\\N" ) {
             print "Ajout de l\047adresse électronique : " $2
         }
       '

       /bin/echo

   fi

   # Mise à jour de la base de données

   /bin/cat "${TEMP}/ajouts/${i}.txt" | \
     /usr/bin/psql "${i}" -q \
         -c "COPY phpbb_banlist ( ban_ip , ban_email ) FROM STDOUT ;"

 fi

done

exit 0

Creative Commons License