Для контроля состояния линка будем пинговать шлюз провайдера. Утилита ping
, идущая вместе с FreeBSD и Linux, нам не подходит, т.к. не выдает никаких сообщений при отсутствии ответа проверяемого хоста. То есть нам требуется поведение присущее ping
из windows, выводящей в аналогичном случае «timeout
». После недолгих поисков утилита oping
оказалась идеальным кандидатом.
Собственно шаблон скрипта с подробными комментариями:
- #!/bin/sh
- # $1 - проверяемый IP-адрес
- # $2 - режим работы скрипта
- PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- # Выходим если не задан проверяемый IP
- if [ -z $1 ]; then exit 1; fi
- # Проверка режима работы
- if [ -z $2 ]
- then
- # Отслеживание падения линка
- # Создаем временный файл для хранения статуса линка
- SAVE=$(mktemp)
- # Ловим сигнал завершения и удаляем файл статуса
- trap 'rm -f $SAVE; exit 0;' INT TERM QUIT
- # Пингуем заданный IP-адрес с интервалом в 5 секунд
- # и с помощью xargs вызываем самого себя, передавая
- # результат пинга и имя файла состояния как параметры
- # командной строки.
- oping -4 -i 5 $1 | \
- sed \
- -e '1d' -e '/^--- /d' \
- -e '/packets transmitted/d' \
- -e '/^$/d' -u | \
- xargs -n 1 --delimiter='\n' -I'{}' $0 none check "{}" $SAVE \
- >> /var/log/vpn-watchdog.log
- # Удаляем файл статуса
- rm -f $SAVE
- elif [ $2 = check -a ! -z $4 ]
- then
- # Watchdog
- # $3 - результат пинга
- # $4 - имя файла состояния
- # Получение состояния линка
- STATUS=$(echo $3 | grep -oE '(ms|timeout)$')
- # Сравнение
- if [ ! -z "$STATUS" ]
- then
- # Определение состояния линка и исключение
- # ложного срабатывания
- if [ "$STATUS" = timeout -a "$(cat $4)" != $STATUS ]
- then
- # Реакция на событие
- echo -n "$(date +'%Y-%m-%d %H-%M-%S') TIMEOUT - Restarting... "
- # Далее идет несколько строк команд
- # ...
- echo " done!"
- fi
- # Сохраняем текущее состояние для последующей проверки
- echo -n $STATUS > $4
- fi
- fi
Достоинства данного подхода: не требуется вызывать из крона по расписанию, мониторинг идет непрерывно и, если требуется, время реакции на событие может составить одну-две секунды.