Superviser une Livebox 5 avec un script Bash

Superviser une Livebox 5 avec un script Bash

La supervision d’une Livebox est un enjeu important pour quiconque souhaite surveiller la stabilité et la qualité de sa connexion Internet. Bien que les solutions de monitoring comme Centreon ou Nagios existent, elles nécessitent souvent des plugins adaptés aux équipements spécifiques. Dans cet article, nous allons présenter un script Bash permettant de superviser une Livebox 5, basé sur une évolution d’un ancien script pour Livebox 4.

Étape 1 : Déclaration des variables et préparation

Le script commence par définir plusieurs variables essentielles : l’adresse IP de la Livebox (IP_LIVEBOX5), le mot de passe administrateur, ainsi qu’un répertoire temporaire dans /tmp pour stocker les fichiers intermédiaires (cookies, réponses JSON, etc.).
Une fonction cleanup assure la suppression automatique de ces fichiers à la fin de l’exécution.

Étape 2 : Authentification

Avant toute récupération d’informations de la Livebox 5 d'orange, le script vérifie la connectivité avec la box via un ping. Ensuite, une requête cURL est envoyée à l’API interne de la Livebox afin d’obtenir un contextID. Celui-ci est indispensable pour toutes les requêtes suivantes. Si cette étape échoue, le script s’arrête avec un message critique.

Étape 3 : Récupération des données

Grâce au contextID, la commande getMIBs permet de rapatrier les informations réseaux au format JSON. Ces données incluent :

  • l’adresse IP WAN,

  • l’état de la connexion,

  • les débits montant et descendant,

  • la durée de bail DHCP,

  • les informations ONT (signal, température, tension).

Le script utilise jq pour extraire proprement ces valeurs.

Étape 4 : Analyse et supervision

Plusieurs fonctions interprètent ces données :

  • infosDhcp affiche le serveur DHCP et la durée restante du bail,

  • etatConnexion vérifie la disponibilité d’Internet,

  • infosDebit compare les débits avec des seuils d’alerte,

  • SignalONT, temperatureONT et voltageONT surveillent respectivement la qualité du signal optique, la température et la tension.

Chaque fonction retourne un statut au format Nagios/Centreon (OK, WARNING, CRITICAL) accompagné de métriques exploitables.

Étape 5 : Exécution

Le script s’utilise avec un argument spécifique :

./supervision_livebox.sh -infosdebit
./supervision_livebox.sh -etatconnexion

Contenu du script :

Voici le code source du script en entier pour la Livebox 5 Orange (désolé pour la mise en forme, j'essairai d'améliorer ça plus tard) :

 

#!/bin/bash

###########################################
# Script ORIGINAL :
# Firmware Livebox 4 = 3.4.10 g0-f-sip-fr #
#     Script mis a jour le 06/04/2018     #
###########################################

# Modifié par Mathieu C Février 2025
# Adapté pour une Livebox 5
# Modifié le 13/05/2025 - Optimisation pour éviter les lectures multiples du fichier MIBs.json

#############################
# Declaration des variables #
#############################
myLivebox=IP_LIVEBOX5
myPassword=MOT_DE_PASS_ADMIN

myBashDir=/usr/lib/centreon/plugins

# Utiliser /tmp pour les fichiers temporaires pour éviter les problèmes de permission
tmpDir=$(mktemp -d)
myOutput="$tmpDir/livebox_output.txt"
myCookies="$tmpDir/livebox_cookies.txt"

# Fonction de nettoyage pour supprimer les fichiers temporaires
cleanup() {
  rm -rf "$tmpDir"
}

# S'assurer que les fichiers temporaires sont supprimés à la fin du script
trap cleanup EXIT

########################################
# Connexion et recuperation du cookies #
########################################
# Vérifier la connectivité avec la Livebox avant de continuer
if ! ping -c 1 -W 2 $myLivebox > /dev/null 2>&1; then
    echo "CRITICAL: Impossible de se connecter à la Livebox ($myLivebox)"
    exit 2
fi

# Utiliser un fichier de cookies temporaire pour l'authentification
curl_result=$(curl -s -o "$myOutput" -X POST -c "$myCookies" -H 'Content-Type: application/x-sah-ws-4-call+json' -H 'Authorization: X-Sah-Login' -d "{\"service\":\"sah.Device.Information\",\"method\":\"createContext\",\"parameters\":{\"applicationName\":\"so_sdkut\",\"username\":\"admin\",\"password\":\"$myPassword\"}}" http://$myLivebox/ws)

# Vérifier si la connexion a réussi
if [ $? -ne 0 ] || [ ! -s "$myCookies" ]; then
    echo "CRITICAL: Échec de l'authentification à la Livebox"
    exit 2
fi

##################################################
# Lecture du cookies pour utilisation ulterieure #
##################################################
myContextID=$(cat "$myOutput" | grep -o '"contextID":"[^"]*' | cut -d'"' -f4)

# Vérifier si le contextID a été extrait correctement
if [ -z "$myContextID" ]; then
    echo "CRITICAL: Impossible d'obtenir le contexte d'authentification"
    exit 2
fi

###############################################################################################
# Envoi des commandes pour recuperer les informtations et stockage dans la variable getMIBs   #
###############################################################################################
# Utilisation du contextID pour récupérer les MIBs
getMIBs=$(curl -s -b "$myCookies" -X POST -H 'Content-Type: application/x-sah-ws-4-call+json' -H "X-Context: $myContextID" -d "{\"service\":\"NeMo.Intf.data\",\"method\":\"getMIBs\",\"parameters\":{}}" http://$myLivebox/ws)

# Vérifier si getMIBs contient des erreurs
if echo "$getMIBs" | grep -q "Permission denied"; then
    echo "CRITICAL: Erreur d'autorisation lors de la récupération des données"
    exit 2
fi

# Sauvegarde des données pour référence future (optionnel, commenté par défaut)
# echo "$getMIBs" > $myBashDir/MIBs.json

#######################################################
# Deconnexion                                         #
#######################################################
curl -s -b "$myCookies" -X POST http://$myLivebox/logout > /dev/null 2>&1

#############################################################################
# Extraction des informations directement depuis la variable getMIBs        #
#############################################################################
# Vérifier si getMIBs contient des données valides
if ! echo "$getMIBs" | jq . > /dev/null 2>&1; then
    echo "CRITICAL: Les données récupérées ne sont pas au format JSON valide"
    exit 2
fi

# Extraction des informations DHCP et lease avec vérification d'erreur
iPadresse=$(echo "$getMIBs" | jq -r '.status.dhcp.dhcp_data.IPAddress // "N/A"')
serveurDhcp=$(echo "$getMIBs" | jq -r '.status.dhcp.dhcp_data.DHCPServer // "N/A"')
dureeLease=$(echo "$getMIBs" | jq -r '.status.dhcp.dhcp_data.LeaseTime // 0')
dureeLeaseRestant=$(echo "$getMIBs" | jq -r '.status.dhcp.dhcp_data.LeaseTimeRemaining // 0')

# Convertir en heures avec vérification pour éviter les erreurs arithmétiques
if [[ "$dureeLease" =~ ^[0-9]+$ ]]; then
    dureeLeaseHeures=$((dureeLease/3600))
else
    dureeLeaseHeures=0
fi

if [[ "$dureeLeaseRestant" =~ ^[0-9]+$ ]]; then
    LeaseRestantHeures=$((dureeLeaseRestant/3600))
else
    LeaseRestantHeures=0
fi

# Extraction des informations sur la ligne DSL avec vérification d'erreur
etatConnexionDSL=$(echo "$getMIBs" | jq -r '.status.base.dhcp_data.Status // "false"')
upTime=$(echo "$getMIBs" | jq -r '.status.dhcp.dhcp_data.Uptime // 0')

if [[ "$upTime" =~ ^[0-9]+$ ]]; then
    upTimeHeures=$((upTime/3600))
else
    upTimeHeures=0
fi

# Extraction de l'uptime débit et marge de bruit avec vérification d'erreur
UpstreamCurrRate=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.UpstreamCurrRate // 0')
DownstreamCurrRate=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.DownstreamCurrRate // 0')

# Extraction des infos ONT avec vérification d'erreur
SignalRXpower=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.SignalRxPower // 0')
SignalTXpower=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.SignalTxPower // 0')
TemperatureONT=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.Temperature // 0')
VoltageONT=$(echo "$getMIBs" | jq -r '.status.gpon.veip0.Voltage // 0')

function infosDhcp () {

  echo "OK: Serveur DHCP : $serveurDhcp, Duree lease restante : $LeaseRestantHeures heures sur $dureeLeaseHeures heures | LeaseLeftHeures=$(($LeaseRestantHeures))Heures"
  exit 0

}

function ipActuelle () {

  echo "OK: Adresse IP WAN actuelle : $iPadresse"
  exit 0

}

function etatConnexion (){

  if [[ $etatConnexionDSL == "true" ]]; then

    echo "OK: Connexion fonctionnelle depuis $(($upTimeHeures/24)) jour(s)"
    exit 0

  else

    echo "CRITICAL: Connexion non fonctionelle. Message : $etatConnexionDSL"
    exit 2

  fi


}

function infosDebit (){

  # Vérifier que les valeurs sont numériques avant conversion
  if [[ ! "$UpstreamCurrRate" =~ ^[0-9]+$ ]] || [[ ! "$DownstreamCurrRate" =~ ^[0-9]+$ ]]; then
    echo "CRITICAL: Données de débit non valides ou non disponibles"
    exit 2
  fi

  # Conversion des débits en Gb/s pour la comparaison
  UpstreamRate=$(echo "scale=2; $UpstreamCurrRate/1000000" | bc)
  DownstreamRate=$(echo "scale=2; $DownstreamCurrRate/1000000" | bc)

  # Seuils en Gb/s ajustés pour une offre à 500 Mbps en download
  SeuilWarningUpstream=0.25    # 250 Mbps en upload
  SeuilCriticalUpstream=0.15   # 150 Mbps en upload

  SeuilWarningDownstream=0.45  # 450 Mbps en download (90% de l'offre)
  SeuilCriticalDownstream=0.35 # 350 Mbps en download (70% de l'offre)

  if [[ "$etatConnexionDSL" == "true" ]]; then

    if (( $(echo "$UpstreamRate < $SeuilCriticalUpstream" | bc -l) || $(echo "$DownstreamRate < $SeuilCriticalDownstream" | bc -l) )); then
          echo "CRITICAL: Débit montant : $UpstreamRate Gb/s , débit descendant : $DownstreamRate Gb/s | UpStream=${UpstreamRate}Gb;${SeuilWarningUpstream};${SeuilCriticalUpstream} DownStream=${DownstreamRate}Gb;${SeuilWarningDownstream};${SeuilCriticalDownstream}"
          exit 2

    elif (( $(echo "$UpstreamRate < $SeuilWarningUpstream" | bc -l) || $(echo "$DownstreamRate < $SeuilWarningDownstream" | bc -l) )); then
          echo "WARNING: Débit montant : $UpstreamRate Gb/s , débit descendant : $DownstreamRate Gb/s | UpStream=${UpstreamRate}Gb;${SeuilWarningUpstream};${SeuilCriticalUpstream} DownStream=${DownstreamRate}Gb;${SeuilWarningDownstream};${SeuilCriticalDownstream}"
          exit 1

    fi

    echo "OK: Débit montant : $UpstreamRate Gb/s , débit descendant : $DownstreamRate Gb/s | UpStream=${UpstreamRate}Gb;${SeuilWarningUpstream};${SeuilCriticalUpstream} DownStream=${DownstreamRate}Gb;${SeuilWarningDownstream};${SeuilCriticalDownstream}"
    exit 0

  else

    echo "CRITICAL: Connexion non fonctionnelle. Message : $etatConnexionDSL"
    exit 2

  fi
}

function SignalONT (){

  SeuilCriticalRXPower=-27000
  SeuilWarningRXPower=-20000

  SeuilCriticalTXPower=5000
  SeuilWarningTXPower=3000


    if [[ $SignalRXpower -lt $SeuilCriticalRXPower ]] || [[ $SignalTXpower -gt $SeuilCriticalTXPower ]]; then

          echo "CRITICAL: Signal Réception : $(($SignalRXpower/1000)) dBm , Signal émission : $(($SignalTXpower/1000)) dBm | SignalRX=$(($SignalRXpower/1000))dBm;$(($SeuilWarningRXPower/1000));$(($SeuilCriticalRXPower/1000)) SignalTX=$(($SignalTXpower/1000))dBm;$(($SeuilWarningTXPower/1000));$(($SeuilCriticalTXPower/1000))"
          exit 2

    elif [[ $SignalRXpower -lt $SeuilWarningRXPower ]] || [[ $SignalTXpower -gt $SeuilWarningTXPower ]]; then

          echo "WARNING: Signal Réception : $(($SignalRXpower/1000)) dBm , Signal émission : $(($SignalTXpower/1000)) dBm | SignalRX=$(($SignalRXpower/1000))dBm;$(($SeuilWarningRXPower/1000));$(($SeuilCriticalRXPower/1000)) SignalTX=$(($SignalTXpower/1000))dBm;$(($SeuilWarningTXPower/1000));$(($SeuilCriticalTXPower/1000))"
          exit 1

    fi

    echo "OK: Signal Réception : $(($SignalRXpower/1000)) dBm , Signal émission : $(($SignalTXpower/1000)) dBm | SignalRX=$(($SignalRXpower/1000))dBm;$(($SeuilWarningRXPower/1000));$(($SeuilCriticalRXPower/1000)) SignalTX=$(($SignalTXpower/1000))dbm;$(($SeuilWarningTXPower/1000));$(($SeuilCriticalTXPower/1000))"
    exit 0

}

function temperatureONT (){

 seuilTemperatureWarning=55
 seuilTemperatureCritique=65

 if [[ $TemperatureONT -gt $seuilTemperatureCritique ]]; then

          echo "CRITICAL: Température prise ONT : $TemperatureONT°C | Temperature=$TemperatureONT°C;$seuilTemperatureWarning;$seuilTemperatureCritique"
          exit 2

  elif [[ $TemperatureONT -gt $seuilTemperatureWarning ]]; then

          echo "WARNING: Température prise ONT : $TemperatureONT°C | Temperature=$TemperatureONT°C;$seuilTemperatureWarning;$seuilTemperatureCritique"
          exit 1

  fi

  echo "OK: Température prise ONT : $TemperatureONT°C | Temperature=$TemperatureONT°C;$seuilTemperatureWarning;$seuilTemperatureCritique"
  exit 0



}

function voltageONT (){

  # on converse les 3 chiffres après la virgule :
 voltageONTprecis=$(echo "scale=3; $VoltageONT/1000" | bc)

 seuilVoltageWarning=50
 seuilVoltageCritique=60

 VoltageONT=$(($VoltageONT/1000))

 if [[ $VoltageONT -gt $seuilVoltageCritique ]]; then

          echo "CRITICAL: Voltage prise ONT : $voltageONTprecis Volts | Tension=$voltageONTprecis;$seuilVoltageWarning;$seuilVoltageCritique"
          exit 2

  elif [[ $VoltageONT -gt $seuilVoltageWarning ]]; then

          echo "WARNING: Voltage prise ONT : $voltageONTprecis Volts | Tension=$voltageONTprecis;$seuilVoltageWarning;$seuilVoltageCritique"
          exit 1

  fi

  echo "OK: Voltage prise ONT : $voltageONTprecis Volts | Tension=$voltageONTprecis;$seuilVoltageWarning;$seuilVoltageCritique"
  exit 0



}


if [ "$1" = "-infosdhcp" ]; then

   infosDhcp

elif [ "$1" = "-etatconnexion" ]; then

   etatConnexion

elif [ "$1" = "-infosdebit" ]; then

   infosDebit

elif [ "$1" = "-infossignalont" ]; then

   SignalONT

elif [ "$1" = "-tempont" ]; then

   temperatureONT

elif [ "$1" = "-voltageont" ]; then

   voltageONT

elif [ "$1" = "-ipactuelle" ]; then

   ipActuelle


else

   echo
   echo "Veuillez spécifier une option valide :"
   echo
   echo "-infosdhcp     : Informations DHCP et durée du bail"
   echo "-etatconnexion : État de la connexion internet"
   echo "-infosdebit    : Informations sur les débits montant et descendant"  
   echo "-infossignalont: Informations sur les signaux ONT (réception/émission)"
   echo "-tempont       : Température de la prise ONT"
   echo "-voltageont    : Voltage de la prise ONT"
   echo "-ipactuelle    : Adresse IP WAN actuelle"
   echo

fi
# Fin du script
Partager cet article :

Articles récents

Configurer un serveur OpenVPN sur un EdgeRouterX Ubiquiti
Configurer un serveur OpenVPN sur un EdgeRouterX Ubiquiti

18 June 2026

Vous avez un EdgeRouter Ubiquiti (EdgeOS) et vous voulez pouvoir accéder à votre réseau local depuis l'extrérieur, en toute sécurité; ? Dans ce tuto, on monte p...

Lire la suite
Pourquoi depuis fin 2025 vos mails Free ne fonctionnent plus dans Outlook ?
Pourquoi depuis fin 2025 vos mails Free ne fonctionnent plus dans Outlook ?

16 June 2026

&nbsp; Depuis fin 2025, de nombreux utilisateurs Free constatent un probl&egrave;me identique : leurs mails fonctionnent parfaitement sur le webmail Free ou depuis un smartphone, mais le client Outlo...

Lire la suite
Exposer un VirtualHost local en permanence avec ngrok
Exposer un VirtualHost local en permanence avec ngrok

12 June 2026

Configurer un service autonome pour ngrok sur un serveur Linux

Lire la suite