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.
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.
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.
#!/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