LINUX.ORG.RU
ФорумAdmin

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

 , ,


1

1

Приветсвую! Есть почтовый сервер с двумя сетевухами, каждая смотрит в сторону своего провайдера. Назовем так eth0 основной канал (быстрый), eth1 резервный канал (медленный). Задача такая. Постоянно сидим на быстром канале, если канал отрубился и находится в дауне как минимум 20 сек, перепрыгиваем на резервный (медленный). Если основной канал вернулся, возвращаемся обратно. Сначала думал поиграть с метриками в маршрутах, а нет тупик. Может типа скрипта который будет запускатся каждые 20 сек?

ping 8.8.8.8 -I eth0
if echo "Destination Host Unreachable"
   {
    ifconfig eth0 down;
    ifconfig eth1 up;
   }
   else
   {
    ifconfig eth0 up;
    ifconfig eth1 down;   
   }

Пример конечно весьма условный, но думаю суть понятна. Или есть более правильные пути?



Последнее исправление: hobbit (всего исправлений: 1)

Ищи доки LARTC.

gruy ★★★★★
()

дык достаточно менять адрес шлюза по умолчанию. Зачем сами интерфейсы дергать?

Тем более, что положив eth0 ты уже через него ничего не протестируешь.

А вот как тестировать «живость» интерфейса - это уже совсем другой вопрос.

vel ★★★★★
()

Куда ты там перепрыгивать сам по себе собрался? Клиенты откуда узнают что адрес сервера меняется туда-сюда?

firkax ★★★★★
()
Ответ на: комментарий от firkax

Round-robin? Но вы отчасти правы, если вопрос про внешних клиентов (не сервера, а именно клиентов) то всё может быть не так однозначно, бывает что оффтопик «не очень» с этим справляется.

anc ★★★★★
()
Ответ на: комментарий от anc

дык достаточно менять адрес шлюза по умолчанию. Зачем сами интерфейсы дергать? Тем более, что положив eth0 ты уже через него ничего не протестируешь. А вот как тестировать «живость» интерфейса - это уже совсем другой вопрос.

ОК, меняем маршрут. Говорим ходить через иной шлюз?

Куда ты там перепрыгивать сам по себе собрался? Клиенты откуда узнают что адрес сервера меняется туда-сюда?

Не хотел про клиентови писать, что бы не грузить лишней информацией. Клиенты сидят в локальной сети. У почтовика есть третий интерфейс, о котором я «забыл» сообщить. Тот самый который смотрит в локалку. Так что для внутренних клиентов ничего не меняется. Для внешних клиентов немного по другому. Они стучатся на сервак по доменному имени. У хостера в ДНС зоне прописываем две MX-записи (у каждой МХ своя «А» запись со своим ip адресом) работающие по приоритету: если ip с более высоким приоритетом не работает, то письмо будет отправлено на следующий по приоритету. Как то так.

Вопрос тестирования интерфейса на «живость» остается открытым.

Humaxoid
() автор топика
Ответ на: комментарий от Humaxoid

Решение просто:
  настроить маршрутизацию для пингуемых IP-адресов
  через нужный интерфейс.

  Если, например, будем определять живость интерфейса
  пингуя адрес 8.8.8.8,
  то нужно настроить маршрутизацию для 8.8.8. через 
  этот интерфейс...
  Лучше, конечно, пинговать несколько адресов...

ru_org_linux
()

можно раз в 20с пинговать или выкачивать какой-то файл с впс, либо страничку фиксированного размера и смотреть на время. если не удовлетворяет условия - менять маршрут как было предложено выше.

посомтри еще вот это

flant ★★★★
()
Ответ на: комментарий от AVL2

Нашел любопытный скрипт который меняет дефолтовый шлюз в таблице маршрутов при пропадании основного канала. Расписал комментарии так, как сам понял его работу. Понимание не полное, так как скрипт не заработал. Поправьте если что не так.

#!/bin/bash

# Данный скрипт пингует шлюз основного канала и смотрит сколько пингов вернулось.
# Если мы на основном канале и потерялось больше двух пакетов из шести, то переключаемся на резервный.
# Если мы на резервном и на основном потерялось меньше двух пингов, то переключаемся обратно на основной.

GW_DEFAULT="11.22.33.44"  # IP шлюза на основном канале
IF_DEFAULT="eth0"         # Интерфейс основного канала
GW_BACKUP="55.66.77.88"   # IP шлюза на резервном канале
IF_BACKUP="eth2"          # Интерфейс резервного канала

# Определяем текущий шлюз
GW_CURRENT=$(route -n | grep -E "^0.0.0.0 .* UG .*" | awk '{print $2}')

# Пингуем контрольный хост
PINGS=$(ping -c 5 -i .5 -w 6 -I ${IF_DEFAULT} 8.8.8.8 | grep "packets transmitted" | awk '{print $4}')
# Где:
# -c количество пакетов для отправки
# -i интервал в секундах между отправкой пакетов

if [ "${GW_CURRENT}" == "${GW_DEFAULT}" ];   # если текущий шлюз является основным
  then
    if [ "${PINGS}" -le "5" ]; then
        echo "Переход на резервный маршрут"
        route del default
        route add default gw ${GW_BACKUP} ${IF_BACKUP}
    fi
  else
    if [ "${PINGS}" -gt "5" ]; then
      echo "Возврат к основному маршруту"
      route del default
      route add default gw ${GW_DEFAULT} ${IF_DEFAULT}
    fi
fi

Разъясните пожалуйста действие этой строки?

PINGS=$(ping -c 5 -i .5 -w 6 -I ${IF_DEFAULT} 8.8.8.8 | grep "packets transmitted" | awk '{print $4}')
И эти условия
if [ "${PINGS}" -le "5" ];
if [ "${PINGS}" -gt "5" ];
Спасибо большое!

Humaxoid
() автор топика
Последнее исправление: Humaxoid (всего исправлений: 1)
Ответ на: комментарий от Humaxoid

пингует шлюз основного канала .. этой строки?

нет, пингует 8.8.8.8 через интерфейс основного канала

И этой

если полученных пакетов меньше или равно 5

больше 5

yandrey ★★
()
Последнее исправление: yandrey (всего исправлений: 2)
Ответ на: комментарий от Humaxoid

grep «packets transmitted» | awk '{print $4}')

Ужас ужасный.

anc ★★★★★
()
Ответ на: комментарий от Humaxoid

Спасибо, к своему стыду не знал что можно пинговать через конкретный интерфейс в обход гейта

rukez ★★★★
()
Ответ на: комментарий от Humaxoid

Само по себе решение узкое.

Во первых, оно не учитывает возможные входящие включения. Лучше бы для начала настроить мультиисп.

https://shorewall.org/MultiISP.html

Как вариант, настроить его через system-networkd

В этом случае без проблем можно пользоваться обоими каналами сразу, тестировать оба канала и включать/выключать через ip rule.

AVL2 ★★★★★
()
Ответ на: комментарий от yandrey

Спасибо! Сейчас резервирование работает. При пропадании основного канала, перепрыгивает на резервный. Другая беда нарисовалась, при появлении основного канала, не возвращается обратно. Запускается данный скрипт через крон, с переодичностью 3 мин.

#!/bin/bash

# Скрипт пингует удаленный хост 8.8.8.8 через основной канал и смотрит сколько пингов вернулось.
# Если мы на основном канале потерялось больше двух пакетов из шести, то переключается на резервный.
# Если мы на резервном и на основном потерялось меньше двух пингов, то переключаемся обратно на основной.

GW_DEFAULT="11.22.33.44" # IP шлюза на основном канале
IF_DEFAULT="eth0"        # Интерфейс основного канала - ТТК
GW_BACKUP="55.66.77.88"  # IP шлюза на резервном канале
IF_BACKUP="eth2"         # Интерфейс резервного канала - Freedom

# Определяем текущий шлюз
GW_CURRENT=$(route -n | grep -E "^0.0.0.0 .* UG .*" | awk '{print $2}')

# Пингуем контрольный хост
PINGS=$(ping -c10 -w30 -I ${IF_DEFAULT} 8.8.8.8 | grep "icmp_req=" | wc -l)

# Где:
# -c 10 отправляем только 10 пакетов
# -i 20 отправляем пакет каждые 20 секунд
# -w 30 пинговать не более 30 секунд
# -I интерфейс

if [ "${GW_CURRENT}" == "${GW_DEFAULT}" ];  then         # если текущий шлюз равен основному шлюзу, тогда проверим условие ниже

    if [ "${PINGS}" -le "3" ];  then                     # если полученных пакетов меньше или равно 3, тогда...
        echo "Переход на резервный маршрут"
        route del default
        route add default gw ${GW_BACKUP} ${IF_BACKUP}
    fi
else                                                     # иначе
    if [ "${PINGS}" -gt "3" ];  then                     # если полученных пакетов больше 3, тогда...
      echo "Возврат к основному маршруту"
      route del default
      route add default gw ${GW_DEFAULT} ${IF_DEFAULT}
    fi
fi

Humaxoid
() автор топика
Ответ на: комментарий от Humaxoid

На резервном канале при работающем осном ответы ping -I eth0 8.8.8.8 есть?

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

yandrey ★★
()
Ответ на: комментарий от yandrey

На резервном канале при работающем осном ответы ping -I eth0 8.8.8.8 есть?

Если работает основной, на резервном пингов нет. Потому как в таблице маршрутов по дефолту установлен шлюз основного правайдера. И наоборот, если работает резервный канал, через основной канал пинги не ходят, по тойже причине.

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

Мне и не нужен снаружи доступ к нему, все юзеры сидят в локалке. Почта исходящаа и входящая при резервировании по любому бегает (про приоритеты МХ записей я писал выше). Городить полноценный мультиван под мои требования? Зачем? Вот как раз таки пинговать провайдерский шлюз не лучшее решение. Т.к возможны случаи что если у провайдера интернет отвалится, шлюз останется доступным. Что пинговать, это всё лирика. Не в этом вопрос.

Humaxoid
() автор топика
Ответ на: комментарий от Humaxoid

Парни, спасибо за помощь! Нашел ошибку. Нужно было пинговать не с основного интерфейса, а с текущего. Но перед этим определить через какой интерфейс на данный момент работаем. Для этого пришлось создать еще одну строку кода.

IF_CURRENT=$(route -n | grep -E "^0.0.0.0 .* UG .*" | awk '{print $8}')

Humaxoid
() автор топика
Последнее исправление: Humaxoid (всего исправлений: 1)
Ответ на: комментарий от Humaxoid

Тогда уж надо делать все по современному и компактней, этот скрипт, наверно, писался в 2000x)

...

GW_CURRENT=$(ip route | awk '/^default/ { print $3 }')

...

IF_CURRENT=$(ip route | awk '/^default/ { print $5 }')

...
    if [ "${PINGS}" -le "3" ];  then
        echo "Переход на резервный маршрут"
        ip route replace default via ${GW_BACKUP} dev ${IF_BACKUP}
    fi
else
    if [ "${PINGS}" -gt "3" ];  then
      echo "Возврат к основному маршруту"
      ip route replace default via ${GW_DEFAULT} dev ${IF_DEFAULT}
    fi
...

Городить полноценный мультиван под мои требования? Зачем?

Хотя бы, чтобы пришедшее на интерфейс, на него и возвращалось, независимо default он или нет.

yandrey ★★
()
Последнее исправление: yandrey (всего исправлений: 1)
Ответ на: комментарий от yandrey

ip route replace default via ${GW_BACKUP} dev ${IF_BACKUP}

Изначально тоже думал об изменени маршрута. replace c cамого начала не сработал. Возвращает RTNETLINK answers: No such process. Пришлось городить огород (удаление дефолтового маршрута + добавление нового шлюза)

Humaxoid
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.