Резервирование канала интернет

В этой статье резервированием канала я буду называть систему автоматического ввода резервного подключения к сети интернет при отсутствии связи по главному каналу. Простым примером может быть обычный офисный (или домашний) роутер в штатном режиме раздающий проводной интернет клиентам, но при потере связи с провайдером, задействующий резервное подключение посредством USB-модема. Но если для современных роутеров поддержка USB-модемов становится уже обычной практикой, то такие "экзотические", но не менее полезные функции как резервирование каналов, присущи лишь топовым недешевым офисным моделям (или ещё более дорогим промышленным решениям). При этом в функции резервирования каналов нет абсолютно ничего труднореализуемого.

Будем считать, что на данном этапе вы уже научились поднимать модемное PPP-соединение на вашем устройстве под управлением TCL, так как вся последующая настройка будет сводиться к автоматическому подключению модемного соединения при потере связи с основным интернет-каналом. Но вначале поговорим немного о маршрутизации.

Учитывая что на TCL-роутере планируется как минимум 3 сетевых интерфейса (основной, резервный и локальный) нам необходимо указать маршрутизатору определенные правила взаимодействия между этими интерфейсами. Для этого существует маршрутизация с таблицами правил. Раньше, когда у нас было всего два интерфейса (основной WAN и локальный LAN(WLAN)) маршрут был вполне очевиден: Из WAN в LAN(WLAN) и наоборот. Он конфигурировался самой системой автоматически и устанавливался по умолчанию - default route. Если мы просто подключим ещё один канал интернета (модемный PPP) у нас ничего не выйдет. Роутер не будет знать что теперь весь траффик (или его часть) необходимо пустить по модемному соединению. Для этого придется немого откорректировать таблицу маршрутизации. А именно удалить старый default route и вместо него задать новый маршрут по умолчанию, но уже через интерфейс ppp0:

route del default
route add default dev ppp0

Как видно, всё уместилось всего в две строчки. Далее переходим к решению поставленой задачи. Каким-то образом нашему роутеру необходимо знать, что связь по основному каналу прервалась. Обычно это делается "пингованием" удаленного сервера в интернете с заведомо высоким uptime (временем бесперебойной работы). Обычно таким сервером выступает DNS от GOOGLE с IP 8.8.4.4 и 8.8.8.8:

ping -c 2 -W 3 -q 8.8.8.8

Параметры команды заданы таким образом, что наш роутер будет отсылать 2 ping-запроса на IP-адрес 8.8.8.8. Если в течении 3-ёх секунд не последует ответа от удаленного сервера - соединение интернет можно считать потеряным.

Чтобы не изобретать велосипед, я взял готовую логику работы интернет-АВР, которая использует специальный файл-флаг для контроля наличия запущеного резерва канала. Если после проверки доступности основного канала роутер потерпит неудачу, специальный шелл-скрипт создаст модемное соединение и файл-флаг, внесет изменения в таблицу маршрутизации. При этом мы продолжим пинговать основной канал. Когда же соединение по нему восстановится, будут произведены обратные действия: возврат таблицы маршрутизации в исходное состояние, отключение модемного соединения, удаление файл-флага. Добавлю ещё несколько нюансов необходимых для корректной работы скрипта АВР. Первый касается пинга основного канала. Как только мы настроим маршрутизацию на модемное соединение пинг пойдёт через наш PPP-интерфейс. Чтобы привязать жестко ping-запросы к основному каналу запишем в таблицу маршрутизации исключение для адреса 8.8.8.8:

route add -host 8.8.8.8 gw 192.168.0.1

В этом примере 192.168.0.1 - шлюз моего основного провайдера. У вас он будет иным. Таким образом мы говорим нашему Tiny Core Linux все запросы касаемо адреса 8.8.8.8 отправлять на шлюз провайдера основного канала. Второй нюанс касается адресов DNS-сервера. Эти адреса тоже сменятся после перехода на резервный канал. И если ваших локальных клиентов обслуживает DNS-сервер dnsmasq, то интернет у них работать не будет. Решений этого вопроса два. Самый простой - задать в конфигурационном файле /home/conf/dnsmasq.conf статически адреса внешних DNS серверов:

/home/conf/dnsmasq.conf

...
  server=8.8.4.4
  server=77.88.8.1
  server=77.88.8.8
  server=208.67.220.220
  server=208.67.222.222
  server=198.153.192.1
  server=198.153.194.1
...

Обратите внимание, мы специально не вносим в список адрес DNS-сервера от GOOGLE 8.8.8.8. При переходе на резервный канал, запросы к этому серверу перестанут работать.

Другой вариант - замена /etc/resolv.conf откуда dnsmasq берет адреса DNS-серверов нашего провайдера. При успешном модемном подключении провайдер мобильной сети выдает свои DNS-адреса. Они находятся в файле /etc/ppp/resolv.conf. Если мы подменим этим файлом оригинал, dnsmasq начнет использовать корректные адреса. Какой вариант выбрать - решать вам. Я реализовал в скрипте второй случай. Сам же скрипт получился таким:

/opt/avr.sh

#!/bin/sh
# Файл-флаг
LOCKFILE="/opt/wd_flags/avr"
# Файл журнала
LOGFILE="/opt/cron/watchdog.log"
#Пингуем проверочный хост через основной канал:
ping -c 2 -W 3 -n -q 8.8.8.8 > /dev/null
#Если возникла ошибка (хост не доступен):
if [ $? -ne "0" ]
then
# Если нет файла-флага - создаем его:
 if [ ! -f $LOCKFILE ]
   then touch $LOCKFILE &&
   echo "["`date +'%Y/%m/%d %H:%M:%S'`"] Internet connetction changed to RESERVE (modem)" >> $LOGFILE &&
   /opt/switch_to_ppp.sh
  fi
#Если же всё хорошо:
 else
#Если есть файл-флаг:
 if [ -f $LOCKFILE ]
  then
#Переключаемся на проводной интернет, удаляем файл-флаг и записываем событие в файл журнала:
  echo "["`date +'%Y/%m/%d %H:%M:%S'`"] Internet connetction changed to MAIN (lan)" >> $LOGFILE &&
  rm -f $LOCKFILE &&
  /opt/switch_to_lan.sh
 fi
fi

Это основной скрипт. Его ежеминутное выполнение мы реализуем путем добавления в cron-расписание /opt/watchdog.sh. Помимо этого скрипта создадим ещё два. /opt/switch_to_ppp.sh и /opt/switch_to_lan.sh. Они будут вносить основные изменения при переходе с основного канала на резервный и наоборот.

/opt/switch_to_ppp.sh

#!/bin/sh
#starting up PPP:
 pppd file /home/conf/ppp/mobile
#change resolv.conf:
 if [ ! -f /etc/resolv.conf.main ]
  then
  mv /etc/resolv.conf /etc/resolv.conf.main &&
  cp /etc/ppp/resolv.conf /etc/resolv.conf
 fi
#renew default route:
 route del default
 route add default dev ppp0
 route add -host 8.8.8.8 gw 192.168.0.1
#change NAT:
 iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

И шелл-скрипт, который будет переключать на основной канал, когда связь с ним возобновится:

/opt/switch_to_lan.sh

#!/bin/sh
#shutting down ppp:
 /usr/local/etc/init.d/pppd stop
#change resolv.conf:
 if [ -s /etc/resolv.conf.main ]
  then mv /etc/resolv.conf.main /etc/resolv.conf
 fi
#renew default route:
 route del -host 8.8.8.8
 route del default
 route add default gw 192.168.0.1
#change NAT:
 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Не забудьте сделать бэкап, чтобы сохранить созданные файлы.

ранее: "PPPD. PPPoE."далее: "Переходим на PHP-FPM"

Обсуждение темы ещё не открыто. Вы можете быть первым.


Оставить комментарий

Имя:

Сообщение: