Chequear estado túnel IPSEC en pfSense y reiniciar si está caído

Hola muy buenas

hoy os pongo un pequeño script que he tuneado (muy poco también es cierto) para chequear el estado de un túnel IPSEC establecido con un firewall pfSense y en caso de estar caído, reiniciar el túnel.

Me ha pasado que tengo unos túneles establecidos con el pfSense contra diversos Cisco y a veces , sin saber muy bien por qué, se caen. Así que después de varias pruebas, he decidido monitorizar el estado del túnel y reiniciarlo si está caído.

El script original está en

https://wiki.strongswan.org/attachments/314/ipsec-monitor.sh

En mi caso, he cambiado para que en lugar de utilizar el comando NC , pues me utilizara un ping. Por alguna razón el comando NC no me estaba funcionando bien.

El código completo es

#!/usr/local/bin/bash

function main()
{
local SLEEP_SECONDS=60
while [[ 0 == 0 ]]; do
monitor_from_file $*
sleep $SLEEP_SECONDS
done
}

function monitor_vpn_ip_port()
{
local CONN_NAME=$1
local IP=$2
local PORT=$3

ping -S 192.168.2.1 -c1 -W5 $IP || ( \
echo “$IP $PORT did not respond, resetting connection $CONN_NAME”; \
ipsec down $CONN_NAME; ipsec up $CONN_NAME; )
}

function monitor_from_file()
{
local FILE=$1
if [[ ! -e $FILE ]]; then
echo “Can not find file $FILE.”
return 1
fi

# load the file into memory. Hope it’s not too big. 🙂
# -t strips out the newlines on each line.
mapfile -t MYARRAY < $FILE
# init local variable to contain the current connection name.
local CONN=
for LINE in “${MYARRAY[@]}”; do
# Skip over any lines that have the comment at the very beginning.
# if [[ $LINE =~ ^\# ]]; then continue

# Look for a line that looks like this which defines a VPN connection:
# conn CONNECTION-NAME
if [[ $LINE =~ ^conn[\ ] ]]; then
# extract the part after the “conn ” to get the name.
CONN=`echo $LINE | sed ‘s/^conn //’`

# Look for a line where we have the commented ‘monitor’ keyword.
# Example: #monitor 172.17.105.80 9898
elif [[ $LINE =~ \#monitor ]]; then
# Remove everything from the beginning up to and including the “#monitor ”
IP_PORT=`echo $LINE | sed ‘s/^.*#monitor //’`
printf “`date` monitoring $CONN \t $IP_PORT\n”
# IP_PORT should be space delimited and hence should work as separate parameters.
monitor_vpn_ip_port $CONN $IP_PORT

# if we have a blank line, that ends any connection configuration.
elif [[ $LINE =~ ^$ ]]; then
CONN=
fi
done
}

# now start running the script by calling main() with all parameters.
main $*

Adicionalmente, hay que poner en un fichero, las direcciones IP que quieras monitorizar y el nombre de la conexión que quieras resetear en caso necesario. En mi caso el fichero es así:

conn con11000
#monitor 192.168.168.250
conn con5000
#monitor 192.168.169.250

Tengo 2 conexiones a monitorizar, que se llaman con11000 y con5000 (estos nombres se pueden ver en /var/etc/ipsec/ipsec.conf) , y quiero ver si están vivas las maquinas 192.168.168.250 para la con11000 y 192.168.169.250 para la con5000. Aquí podéis poner tantas conexiones como queráis , precedidas de la palabra conn y luego con el #monitor la ip de esa conexión que servirá para verificar si la conexión está funcionando o no.

Luego para llamar al monitor es simplemente ejecutar “./ipsec_monitor.sh <nombre-fichero-donde-esten-las-ip-a-monitorizar>”, por ejemplo “./ipsec_monitor.sh vpn.txt”

El script se ejecuta cada 60 segundos, y eso lo podéis controlar con la variable SLEEP_SECONDS. También podéis quitarla y meterlo en un cron o ajustarlo a conveniencia 🙂

Suerte!



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.