Назад | Перейти на главную страницу

Синхронизация состояний мостовых интерфейсов

У нас есть резервные оптоволоконные каналы 10G к нашему поставщику услуг Интернета в активной / резервной конфигурации. Между нашим маршрутизатором и маршрутизатором восходящего потока у нас есть пара межсетевых экранов, на которых Vyos работает в прозрачном режиме. Мы используем BGP для рекламы маршрутов, и мы не можем изменить большинство параметров.

Рисование:

Если связь с одним из маршрутизаторов обрывается (например, с x на рисунке - это наш самый распространенный тип сбоя), вся сеть недоступна до истечения времени ожидания BGP (до 150 секунд). Я уже знаю, что если мы принудительно отключим канал на другой стороне моста, наши маршрутизаторы немедленно начнут пересылать трафик через другой канал.

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

Есть ли в этом решении какие-то скрытые подводные камни?

Я написал скрипт, который проверяет интерфейсы на соответствие /sys чтобы определить, являются ли они членами моста, а затем отскочить от моста. VyOS использует netplugd для мониторинга интерфейсов и почему-то мой скрипт его сбивает (наверное, напишу отдельный вопрос по этому поводу), но я думаю, что это хорошее общее решение.

#!/bin/bash

## This script will bounce a br interface if a member interface goes down.
## This will cause router BGP timers to reset, making outages last only seconds instead of minutes.
##
## This script is called by netplug on Vyos:
## /etc/netplug/linkdown.d/my-brdown
##
## Version History
## 1.0 - Initial version
##

LOCKDIR=/var/run/my-bridge-ctl

# Since we only have one br, not going to implement this right now.
#IGNORE_BRIDGES=()

IFACE=$1

#Remove the lock directory
function cleanup {
    if rmdir $LOCKDIR; then
        logger -is -t "my-bridge-ctl" -p "kern.info" "Finished"
    else
        logger -is -t "my-bridge-ctl" -p "kern.error" "Failed to remove lock directory '$LOCKDIR'"
        exit 1
    fi
}

if mkdir $LOCKDIR; then
    #Ensure that if we "grabbed a lock", we release it
    #Works for SIGTERM and SIGINT(Ctrl-C)
    trap "cleanup" EXIT

    logger -is -t "my-bridge-ctl" -p "kern.info" "Acquired lock, running"

    # Processing starts here

    IFACE_DESC=$(<"/sys/class/net/${IFACE}/ifalias")
    IFACE_BR_DIR="/sys/class/net/${IFACE}/brport"

    if [ ! -d "$IFACE_BR_DIR" ]; then
        logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC-no desc}) went down. Not a member of a bridge. Skipping."
    else
        IFACE_BR_LINK=$(realpath "/sys/class/net/${IFACE}/master")
        IFACE_BR_NAME=$(basename $IFACE_BR_LINK)
        IFACE_BR_DESC=$(<"${IFACE_BR_LINK}/ifalias")
        logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC:-no desc}) went down. Member of bridge ${IFACE_BR_NAME} (${IFACE_BR_DESC:-no desc})."

        # TODO: Insert IGNORE_BRIDGE check here

        find "${IFACE_BR_LINK}/brif" -type l -print0 | while IFS= read -r -d $'\0' IFACE_BR_MEMBER_LINK; do
            IFACE_BR_MEMBER_NAME=$(basename $IFACE_BR_MEMBER_LINK)
            logger -is -t "my-bridge-ctl" -p "kern.info" "Handling ${IFACE_BR_NAME} member interface ${IFACE_BR_MEMBER_NAME} (${IFACE_BR_MEMBER_LINK})."

            # Actually do the bounce
            ip link set dev ${IFACE_BR_MEMBER_NAME} down && sleep 2 && ip link set dev ${IFACE_BR_MEMBER_NAME} up

            logger -is -t "my-bridge-ctl" -p "kern.info" "Interface ${IFACE_BR_MEMBER_NAME} bounced."
        done
    fi

    sleep 5
else
    logger -is -t "my-bridge-ctl" -p "kern.info" "Could not create lock directory '$LOCKDIR'"
    exit 1
fi

Я бы запустил сценарий на машинах VyOS, который проверяет состояние восходящего соединения, а затем выполняет ifdown/ifup с другой стороны по мере необходимости.

Самый простой способ сделать это - поместить скрипты в /etc/network/if-down.d (проверьте, является ли упавший интерфейс обновленной стороной, и опустите другую его сторону) и /etc/network/if-up.d (проверьте, является ли интерфейс, который появился, обновленной стороной, и поднимите другую сторону).
В качестве альтернативы вы можете запускать сценарий мониторинга один раз в минуту с помощью cron (или Systemd Timers, или любого аналогичного планировщика), или вы можете написать его как бесконечный цикл, который спит на несколько секунд, чтобы получить субминутную проверку.