NSG logo
NSG heading

Документы в формате PDF, архив (FTP) и Web-справка открываются в новом окне

Усложним предыдущий пример. Требуется обеспечить доступ в Интернет при следующих условиях:

  • Имеется один канал Ethernet и два оператора LTE.
  • Канал Ethernet в любом случае приоритетный.
  • Оба оператора LTE равноценны.
  • Необходимо обеспечить минимальное время переключения на резервный канал.
  • Приложения или туннели, работающие через это устройство, не очень хорошо реагируют на смену канала — долго переинициализирутся, восстанавливают свои сессии, и т.п. По этой причине необходимо минимизировать число переключений, а именно: если устройство уже работает по одному из каналов LTE, то следует оставаться на нём и не переходить на другой без явной необходимости. Уходить с этого канала следует только либо при его падении, либо при поднятии основного канала Ethernet.

Используется устройство NSG–1700 с двумя опциями LTE/3G. Как и в предыдущем примере, работоспособность каждого из каналов контролируется с помощью ping. Особенность данной задачи в том, что столь сложный и разветвлённый алгоритм выбора канала связи (к тому же, как правило, уникальный для каждого заказчика) уже невозможно описать последовательной иерархией метрик или каких-либо иных критериев. Чтобы предусмотреть все возможные варианты, придётся ниже написать полноценный скрипт с большим числом условных переходов.

Подключение офиса к Интернет по Ethernet с резервированием через 2 операторов LTE

Предварительные настройки:

  • SIM-карта первого оператора установлена в верхнее гнездо
  • SIM-карта второго оператора установлена в нижнее гнездо
  • Запрос PIN-кода на картах отключён

Для отправки пингов на 3 контрольных хоста (каждого из операторов) по фиксированным маршрутам удобнее использовать маршрутизацию на основе установленных правил и раздельные таблицы маршрутизации. Таблица маршрутизации для Ethernet заполняется при помощи стартового скрипта (можно вместо этого использовать протокол static в механизме динамической маршрутизации). Интерфейсы LTE получают маршруты по DHCP и пишут их каждый в свою таблицу.

port                       
: eth0                     
: : adm-state              = "up"
: : ifAddress              
: : : prefix               = "192.168.1.1/24"
: eth1                     
: : ifAddress              
: : : prefix               = "123.45.67.89/24"
: m1                       
: : type                   = "lte"
: : ifAddress              
: : : configurable         = "dhcp"
: : : dhcp-options         
: : : : default-gw-table   = 2
: m2                       
: : type                   = "lte"
: : provider
: : : main
: : : : attempts = 0
: : : aux
: : : : attempts = 1
: : ifAddress              
: : : configurable         = "dhcp"
: : : dhcp-options         
: : : : default-gw-table   = 3
services
: daemons
: : table1setup
: : : adm-state = "up"
: : : auto-restart = "false"
: : : command = "ip route add default via 123.45.67.90 table 1"

Далее, каждый из пингов отправляется по своей таблице; если это не удалось сделать (соединение LTE отсутствует, и в этой таблице нет маршрутов), то следующим правилом он уничтожается, чтобы случайно не маршрутизировался по остальным правилам куда не надо.

ip                         
: rule                     
: : 1                      
: : : to                   = "123.45.67.77/32"
: : : table                = "1"
: : 2                      
: : : to                   = "123.45.67.77/32"
: : : type                 = "blackhole"
: : 3                      
: : : to                   = "34.12.56.98/32"
: : : table                = "2"
: : 4                      
: : : to                   = "34.12.56.98/32"
: : : type                 = "blackhole"
: : 5                      
: : : to                   = "54.67.89.12/32"
: : : table                = "3"
: : 6                      
: : : to                   = "54.67.89.12/32"
: : : type                 = "blackhole"

Если устройство пропускает через себя транзитный трафик, необходим NAT на каждом из интерфейсов. Если весь трафик локальной сети должен уходить только в туннель, то это не требуется (равно как и очистка таблиц NAT при помощи conntrack -F ниже в скриптах).

ip
: nat
: : POSTROUTING       
: : : 1               
: : : : out-interface = "eth1"
: : : : target = "SNAT"
: : : : to-source = "123.45.67.89"
: : : 2               
: : : : out-interface = "m1"
: : : : target = "MASQUERADE"
: : : 3               
: : : : out-interface = "m2"
: : : : target = "MASQUERADE"

Скрипт для выбора канала связи, о котором говорилось выше, удобно оформить в виде генератора событий. В рамках обработчика событий он будет изображать из себя некий виртуальный датчик с именем channel и возможными состояниями nil, eth, m1 и m2, соответственно. Поскольку этот громоздкий скрипт удобнее писать по строкам и с отступами, то для начала, создаём такую ветвь конфигурации:

services
: event-handler            
: : event-generators       
: : : mypoopyrouteselector 
: : : : enable             = true
: : : : command            = "\n" 

Поле, содержащее последовательности \n или \r, при редактировании в Web-интерфейсе преобразуется в двумерное текстовое окно; при работе в консольной командной оболочке его можно открыть в текстовом редакторе при помощи команды command=_edit или command=_fullscreen. Вставляем туда сам скрипт в удобочитаемом виде:

PING0=123.45.67.77;
PING1=34.12.56.98;
PING2=54.67.89.12;
COUNT0=2;
COUNT1=2;
COUNT2=2;
TO0=3;
TO1=5;
TO2=5;
echo channel:nil;
CHANNEL=NIL;
while true; do
  if ping -c$COUNT0 -i$TO0 $PING0 > /dev/null; then
    echo channel:eth;
    CHANNEL=ETH;
  else
    if [ x$CHANNEL = xM2 ] > /dev/null; then
      if ping -c$COUNT2 -i$TO2 $PING2 > /dev/null; then
        echo channel:m2;
        CHANNEL=M2;
      else
        if ping -c$COUNT1 -i$TO1 $PING1 > /dev/null; then
          echo channel:m1;
          CHANNEL=M1;
        else
          echo channel:nil;
          CHANNEL=NIL;
        fi;
      fi;
    else
      if ping -c$COUNT1 -i$TO1 $PING1 > /dev/null; then
        echo channel:m1;
        CHANNEL=M1;
      else
        if ping -c$COUNT2 -i$TO2 $PING2 > /dev/null; then
          echo channel:m2;
          CHANNEL=M2;
        else
          echo channel:nil;
          CHANNEL=NIL;
        fi;
      fi;
    fi;
  fi;
done;

Число пингов и интервалы между ними можно варьировать, чтобы минимизировать время реагирования, но избежать ложных срабатываний. При выходе из редактора получится длинная трудночитаемая строка, но при последующем редактировании она снова преобразуется в двумерный текст.

Обработчик событий реагирует на события этого датчика, т.е. на переход из одного состояния в другое, следующим образом:

services
: event-handler
: : 1                      
: : : virt-sensor          = "channel"
: : : prev-state           = "other"
: : : state                = "eth"
: : : script               = "ip route del default;
                              ip route add default dev eth1 via 123.45.67.90;
                              conntrack -F;
                              logger -tCHANNELS switched to Ethernet;"
: : 2                      
: : : virt-sensor          = "channel"
: : : prev-state           = "other"
: : : state                = "m1"
: : : script               = "ip route del default;
                              ip route add default dev $(nsgsh -q .system.get-iface-name=m1);
                              conntrack -F;
                              logger -tCHANNELS switched to LTE-1;"
: : 3                      
: : : virt-sensor          = "channel"
: : : prev-state           = "other"
: : : state                = "m2"
: : : script               = "ip route del default;
                              ip route add default dev $(nsgsh -q .system.get-iface-name=m2);
                              conntrack -F;
                              logger -tCHANNELS switched to LTE-2;"
: : 4                      
: : : virt-sensor          = "channel"
: : : prev-state           = "other"
: : : state                = "nil"
: : : script               = "ip route del default;
                              logger -tNO CHANNELS available!!!;"

Скрипты здесь можно записывать в строку или, как это было сделано выше, в несколько строк. Для наглядности добавлена запись событий в syslog.


Дополнительные замечания:

Задавать маршрут через широковещательный интерфейс только с помощью его имени (dev) вместо явного указания следующего шлюза (via) — не очень корректно, но для существующих интерфейсов LTE в устройствах NSG это допустимо. Да и то приходится определять имя интерфейса динамически, поскольку оно не тождественно имени физического порта и может изменяться в зависимости от конкретного чипа LTE и порядка падения/поднятия интерфейсов. Более корректно было бы определить шлюз по умолчанию, назначенный для выбранного интерфейса LTE (а также интерфейса Ethernet, если он настраивается динамически по DHCP) и указать его явным образом. В ближайших версиях NSG Linux будет предложен простой механизм для этой цели.

В более простых конфигурациях (Ethernet+LTE или 2×LTE) данную конфигурацию можно упростить, но, в принципе, она работоспособна и так — маршрут в отсутствующий интерфейс просто никогда не будет назначаться.

Явное указание APN, имени пользователя и пароля в современных сотовых сетях не требуется. Если они указаны оператором явно (сети 2G, некоторые устаревшие сети 3G или услуга VPN сотовых операторов), они указываются в узлах provider.main и provider.aux, соответственно.

Обязательно задание пароля для доступа к устройству.

В целях безопасности настоятельно рекомендуется также:

  • Отключить Telnet и использовать для удалённого управления только SSH
  • Заблокировать HTTP с помощью фильтров и использовать для удалённого управления только HTTPS

© ООО "ЭН–ЭС–ДЖИ" 2004–2017 Web-master