Monitorizar una web

Monitorizar una web desde la terminal

Verificar si un sitio web está activo o inactivo desde la terminal

Vamos a crear un script para automatizar la comprobación de uno o varios dominios y nos avise mandándonos un correo electrónico cuando esté caído.

Existen varios servicios, incluso algunos gratuitos como Uptimerobot, Instatus, Pulsetic, Better Stack, Super Monitoring, Site24x7 y DownNotifier entre otros, en la red pero nada mejor que tener uno mismo el control de nuestros dominios.

Comprobar si un dominio está caído

Para comprobar que un dominio está activo disponemos de diferentes comandos para hacerlo.

Realmente no son comandos especiales para tal efecto sino que nos valemos de ciertas funcionalidades u opciones para hacer esta comprobación de comandos muy usados y conocidos.

El primero es el comando ping al cual le añadimos la opción -c 4 y acto seguido le pasamos el dominio a comprobar.

ping -c 4 dominio.com

La opción c 4 indica que mande la señal solo el número de veces indicado, en este caso 4, ya que si no lo indicamos no tendría fin.

El segundo comando con el que podemos comprobar que el dominio está resolviendo es wget añadiéndole la opción -S --spider.

wget -S --spider https://dominio.com

Al añadir la opción -S --spider el comando wget se comporta como una araña web, lo que significa que no descargará las páginas, solo verificará que existen.

El tercer comando es curl con la opción -I y seguida del dominio.

curl -I https://dominio.com

Con la opción -I se obtienen solo los encabezados (headers) del documento que nos sirve el dominio al acceder a él.


Crear un script para comprobar que un dominio está activo

Realmente podemos usar cualquiera de los anteriores métodos para comprobar el dominio aunque alguno puede fallar por diferentes motivos.

Por ejemplo, el comando ping nos dará un error si el servidor donde está alojado el dominio tiene bloqueado el puerto por donde se reciben.

Así que el script lo que va a hacer es comprobar de las tres maneras y solo si las tres dan error nos mandará un aviso de que el dominio no resuelve.

Vamos a crear un archivo al que llamaremos comprobar_dominio.sh con el siguiente contenido:

#!/bin/bash

# Variable que contiene el dominio a comprobar
DOMINIO="dominio.com"

# Comprobación con ping
ping -c 4 $DOMINIO > /dev/null 2>&1
PING_RESULT=$?

# Comprobación con wget
wget -S --spider https://$DOMINIO > /dev/null 2>&1
WGET_RESULT=$?

# Comprobación con curl
curl -I https://$DOMINIO > /dev/null 2>&1
CURL_RESULT=$?

# Si todas las comprobaciones fallan, imprime el mensaje de que la web no responde
if [ $PING_RESULT -ne 0 ] && [ $WGET_RESULT -ne 0 ] && [ $CURL_RESULT -ne 0 ]; then
   echo "La web $DOMINIO no responde"
fi

El siguiente paso es darle permiso de ejecución a nuestro archivo:

chmod +x comprobar_dominio.sh

Si cambiamos el contenido de la variable ‘DOMINIO’ por nuestro dominio podremos ejecutarlo de la siguiente manera:

./comprobar_dominio.sh

Hay que tener en cuenta que, de la forma que está programado, solo nos avisará si el dominio falla.

Aviso de no resolución del dominio por correo electrónico

La solución anterior está bien para ejecutarlo sobre la marcha pero si queremos automatizar y despreocuparnos tendremos que generar un aviso por correo electrónico que nos enviará el sistema cuando falle el dominio.

Para que nuestro sistema pueda enviarnos un correo electrónico tenemos que tener instalado msmtp que nos permite manejar la autenticación por SMTP.

Instalamos, si no lo tenemos instalado, msmtp:

sudo apt install msmtp

El siguiente paso es crear el archivo de configuración en nuestro directorio de usuario, dándole el permiso necesario, en esta caso ‘600’:

touch ~/.msmtprc
chmod 600 ~/.msmtprc

Después lo editamos con el editor preferido y establecemos la siguiente configuración cambiando los valores de nuestro servidor SMTP:

nano ~/.msmtprc
defaults
auth           on
tls           on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile       ~/.msmtp.log

account default
host           smtp.servidor.com
port           587
from           usuario@servidor.com
user           usuario@servidor.com
password       contraseña

Cada uno usará los datos de su cuenta de correo electrónico y sustituirá los valores ‘host’, ‘from’, ‘user’ y ‘password’, ya que el ‘port’ suele ser 587.

El script modificado y actualizado queda de la siguiente manera:

#!/bin/bash

# Variable que contiene el dominio a chequear
DOMINIO="dominio.com"

# Variables de correo electrónico
EMAIL_FROM="usuario@servidor.com"
EMAIL_TO="destinatario@dominio.com"
EMAIL_SUBJECT="Alerta: La web $DOMINIO no responde"

# Mensaje del correo
EMAIL_BODY="La web $DOMINIO no responde a las comprobaciones realizadas."

# Comprobación con ping
ping -c 4 $DOMINIO > /dev/null 2>&1
PING_RESULT=$?

# Comprobación con wget
wget -S --spider https://$DOMINIO > /dev/null 2>&1
WGET_RESULT=$?

# Comprobación con curl
curl -I https://$DOMINIO > /dev/null 2>&1
CURL_RESULT=$?

# Función para enviar el correo electrónico usando msmtp
enviar_correo() {
  {
       echo "Subject: $EMAIL_SUBJECT"
       echo "From: $EMAIL_FROM"
       echo "To: $EMAIL_TO"
       echo
       echo "$EMAIL_BODY"
  } | msmtp --debug --from=$EMAIL_FROM -t $EMAIL_TO
}

# Si todas las comprobaciones fallan, enviar el correo electrónico
if [ $PING_RESULT -ne 0 ] && [ $WGET_RESULT -ne 0 ] && [ $CURL_RESULT -ne 0 ]; then
  enviar_correo
fi

El siguiente paso es añadir un sistema de logs, de forma que cada vez que se haga una comprobación, se almacenará el evento en un registro.

Para ello crearemos el archivo ‘comprobar_dominio.log’:

touch comprobar_dominio.log
#!/bin/bash

# Variable que contiene el dominio a chequear
DOMINIO="dominio.com"

# Variables de correo electrónico
EMAIL_FROM="usuario@servidor.com"
EMAIL_TO="destinatario@dominio.com"
EMAIL_SUBJECT="Alerta: La web $DOMINIO no responde"

# Mensaje del correo
EMAIL_BODY="La web $DOMINIO no responde a las comprobaciones realizadas."

# Archivo de registro
LOG_FILE="/path/to/comprobar_dominio.log"

# Comprobación con ping
ping -c 4 $DOMINIO > /dev/null 2>&1
PING_RESULT=$?

# Comprobación con wget
wget -S --spider https://$DOMINIO > /dev/null 2>&1
WGET_RESULT=$?

# Comprobación con curl
curl -I https://$DOMINIO > /dev/null 2>&1
CURL_RESULT=$?

# Función para enviar el correo electrónico usando msmtp
enviar_correo() {
  {
       echo "Subject: $EMAIL_SUBJECT"
       echo "From: $EMAIL_FROM"
       echo "To: $EMAIL_TO"
       echo
       echo "$EMAIL_BODY"
  } | msmtp --debug --from=$EMAIL_FROM -t $EMAIL_TO
}

# Función para registrar el evento en el archivo de registro
registrar_evento() {
   TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
   echo "$TIMESTAMP - $1" >> $LOG_FILE
}

# Comprobación del estado de las pruebas
if [ $PING_RESULT -ne 0 ] && [ $WGET_RESULT -ne 0 ] && [ $CURL_RESULT -ne 0 ]; then
   # Todas las comprobaciones fallaron
  enviar_correo
  registrar_evento "$DOMINIO no responde. Se ha enviado un correo a $EMAIL_TO."
else
   # Al menos una comprobación fue exitosa
  registrar_evento "$DOMINIO está funcionando correctamente."
fi

En el archivo log se almacenará la fecha, hora y el mensaje de que está funcionando o lo contrario.

La última funcionalidad a añadir al script será que para evitar enviar correos repetidamente mientras el dominio esté caído, vamos a almacenar el estado anterior del dominio, de forma que si el dominio ya estaba caído y se había enviado un correo, no se enviará otro correo.

Se volverá a enviar un correo cuando el dominio vuelva a estar en línea, indicando que ya está funcionando y desde cuándo estaba caído.

#!/bin/bash

# Variable que contiene el dominio a chequear
DOMINIO="dominio.com"

# Variables de correo electrónico
EMAIL_FROM="usuario@servidor.com"
EMAIL_TO="destinatario@dominio.com"
EMAIL_SUBJECT_CAIDO="Alerta: La web $DOMINIO no responde"
EMAIL_SUBJECT_RECUPERADO="Notificación: La web $DOMINIO ha vuelto a funcionar"

# Mensajes del correo
EMAIL_BODY_CAIDO="La web $DOMINIO no responde a las comprobaciones realizadas."
EMAIL_BODY_RECUPERADO="La web $DOMINIO ha vuelto a funcionar. Estaba caída desde:"

# Archivo de registro
LOG_FILE="comprobar_dominio.log"

# Archivo de estado
STATUS_FILE="comprobar_dominio.status"

# Comprobación con ping
ping -c 4 $DOMINIO > /dev/null 2>&1
PING_RESULT=$?

# Comprobación con wget
wget -S --spider https://$DOMINIO > /dev/null 2>&1
WGET_RESULT=$?

# Comprobación con curl
curl -I https://$DOMINIO > /dev/null 2>&1
CURL_RESULT=$?

# Función para enviar el correo electrónico usando msmtp
enviar_correo() {
  local subject=$1
  local body=$2
  {
       echo "Subject: $subject"
       echo "From: $EMAIL_FROM"
       echo "To: $EMAIL_TO"
       echo
       echo "$body"
  } | msmtp --debug --from=$EMAIL_FROM -t $EMAIL_TO
}

# Función para registrar el evento en el archivo de registro
registrar_evento() {
  local mensaje=$1
   TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
   echo "$TIMESTAMP - $mensaje" >> $LOG_FILE
}

# Leer estado anterior
if [ -f $STATUS_FILE ]; then
   source $STATUS_FILE
else
   PREV_STATUS="UP"
   LAST_DOWN_TIME=""
fi

# Comprobación del estado de las pruebas
if [ $PING_RESULT -ne 0 ] && [ $WGET_RESULT -ne 0 ] && [ $CURL_RESULT -ne 0 ]; then
   # Todas las comprobaciones fallaron
   CURRENT_STATUS="DOWN"
   if [ "$PREV_STATUS" != "DOWN" ]; then
       # El dominio ha caído por primera vez
       LAST_DOWN_TIME=$(date +"%Y-%m-%d %H:%M:%S")
      enviar_correo "$EMAIL_SUBJECT_CAIDO" "$EMAIL_BODY_CAIDO"
   fi
  registrar_evento "$DOMINIO no responde. Estado: DOWN."
else
   # Al menos una comprobación fue exitosa
   CURRENT_STATUS="UP"
   if [ "$PREV_STATUS" == "DOWN" ]; then
       # El dominio ha vuelto a estar en línea
       UP_TIME=$(date +"%Y-%m-%d %H:%M:%S")
       EMAIL_BODY_RECUPERADO_FULL="$EMAIL_BODY_RECUPERADO $LAST_DOWN_TIME"
      enviar_correo "$EMAIL_SUBJECT_RECUPERADO" "$EMAIL_BODY_RECUPERADO_FULL"
      registrar_evento "$DOMINIO ha vuelto a funcionar. Estaba caído desde: $LAST_DOWN_TIME."
   else
      registrar_evento "$DOMINIO está funcionando correctamente. Estado: UP."
   fi
fi

# Guardar el estado actual
echo "PREV_STATUS=$CURRENT_STATUS" > $STATUS_FILE
echo "LAST_DOWN_TIME=\"$LAST_DOWN_TIME\"" >> $STATUS_FILE

Y para rematar la automatización añadiremos la ejecución del script al cron del sistema para que se ejecute a intervalos regulares.

crontab -e

Y para que se ejecute cada cinco minutos, añadimos:

*/5 * * * * /path/a/comprobar_dominio.sh

Pues con esto ya tenemos nuestro propio sistema para que nos avise cuando se nos caiga un dominio.

Todo comprobado y funcionando.

Sobre mi

Trabajo en el desarrollo de webs profesionales desde hace más de 25 años.
También me dedico a mis proyectos personales.

Últimas notas publicadas

Categorías

Scroll al inicio