
У нас есть избыточные 10G оптоволоконные соединения с нашим вышестоящим интернет-провайдером в конфигурации active/failover. Между нашим маршрутизатором и вышестоящим маршрутизатором у нас есть пара брандмауэров, на которых запущен Vyos в прозрачном режиме. Мы используем BGP для объявления маршрутов и не можем изменить большинство параметров.
Если связь с одним из маршрутизаторов отключается (например, с тем, что x
на рисунке — это наш самый распространенный тип отказа), вся сеть становится недоступной до тайм-аута BGP (до 150 секунд). Я уже знаю, что если мы принудительно отключим связь с другой стороны моста, наши маршрутизаторы немедленно начнут пересылать трафик через другую связь.
Есть ли способ автоматически отключить одну сторону моста на брандмауэре, если другая сторона выйдет из строя?
Есть ли какие-то скрытые подводные камни в этом решении?
решение1
Я бы запустил скрипт на машинах VyOS, который проверяет состояние восходящего соединения, а затем выполняет ifdown
/ ifup
на другой стороне по мере необходимости.
Самый простой способ сделать это — поместить скрипты /etc/network/if-down.d
(проверить, является ли интерфейс, который упал, обновленной стороной, и вывести из строя другую его сторону) и /etc/network/if-up.d
(проверить, является ли интерфейс, который поднялся, обновленной стороной, и вывести из строя другую его сторону).
В качестве альтернативы вы можете запускать скрипт мониторинга раз в минуту с помощью cron (или Systemd Timers, или любого аналогичного планировщика), или вы можете написать его как бесконечный цикл, который засыпает на несколько секунд, чтобы получить проверку менее чем за минуту.
решение2
Я написал скрипт, который проверяет интерфейсы, /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