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

Предотвращение бесконечной пересылки с двумя маршрутизаторами

Сеть в quesiton выглядит примерно так:

                     /----Inet1
                    /
H1---[111.0/24]---GW1---[99.0/24]
                                 \----GW2-----Inet2

Описание устройства

Вкратце: у H есть более одного возможного маршрута в Интернет.

Предполагается, что H имеет доступ к Интернету через GW2 только тогда, когда этот канал установлен, поэтому GW1 имеет некоторую маршрутизацию на основе политик, специально предназначенную только для H1:

ip rule add from 192.168.111.47 table 991
ip route add default via 192.168.99.1 table 991

Хотя это работает, пока у GW2 есть прямая ссылка на Интернет, проблема возникает, когда эта ссылка не работает. Затем происходит то, что GW2 пересылает пакет обратно на GW1, который снова пересылает обратно на GW2, создавая бесконечный цикл TCP-pingpong. Предпочтительным результатом будет то, что пакет просто отброшен.

Можно ли что-то сделать с iptables на GW1, чтобы предотвратить это? По сути, удобная для iptables версия "Если пакет исходит от GW2, но исходит от H1, отбросьте его"

TL; DR; H1 должен быть разрешен доступ в Интернет только через GW2, но при этом он должен иметь возможность разговаривать как с GW1, так и с GW2.

РЕДАКТИРОВАТЬ: Интерфейсы для GW1: br0.105 для сети «99» и br0.111 для сети «111». Решение может быть или не быть неприятно простым, но я не смог сам создать правильный синтаксис iptables, поэтому помощь будет очень признательна.


PS: Это дополнительный вопрос от этот вопрос

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

Позволять:

br0.105 = interface at GW1 in the 99.0/24 network facing GW2
<mac-gw2> = the MAC address of GW2's interface in the 99.0/24 network facing GW1
<ip-h1> = IP address of H1 from the 111.0/24 network

Затем добавляем правило

iptables -A FORWARD -i br0.105 -s <ip-h1> -m mac --mac-source <mac-gw2> -j REJECT

приведет к отправке сообщения ICMP о недоступности пункта назначения <ip-h1> в случае пакета от <ip-h1> когда-либо возвращается из GW2 к GW1. Идея здесь состоит в том, чтобы фильтровать по MAC-адресу, поскольку у вас есть несколько маршрутов к разным маршрутизаторам через этот интерфейс, и вам нужно различать исходные маршрутизаторы.

Вы можете получить MAC-адрес GW2 либо просмотрев конфигурацию его интерфейса, либо, если у вас нет доступа к нему, просмотрев таблицу кэша ARP GW1 - просто беги arp -n чтобы увидеть текущие записи в кеше.

Обратите внимание, что если GW1 выполняет NAT для трафика, уходящего через <int2> затем <ip-h1> должен быть IP-адрес <int2>, а не один из H1.

Поскольку вы просили способ подстановки MAC-адреса - его нет, модуль iptables mac требует точного совпадения. Но вы, очевидно, могли бы написать это (быстро и грязно, добавьте проверки, соответствующие вашему уровню паранойи, перед запуском в производство):

#!/bin/bash

# variables
# the IP address of GW2
IP_GW2=192.168.99.1
# the IP address of H1
IP_H1=192.168.111.47
# the configuration file containing GW2's MAC address
CONFIG_MAC_GW2="/etc/default/iptables-mac-gw2"
# the "arping" utility (used to resolve an IP address to a MAC address)
ARPING=/usr/sbin/arping

# include $CONFIG_MAC_GW2, if exists
test -f $CONFIG_MAC_GW2 && source $CONFIG_MAC_GW2
# test if $MAC_GW2 is empty or undefined
if [ ! -n "$MAC_GW2" ]; then
  MAC_GW2=`$ARPING $IP_GW2 -c 1 -r`
  if [ $? == 1 ]; then
     echo \$MAC_GW2 has not been configured and could not be detected using "$ARPING $IP_GW2 -c 1 -r"
     exit 1
  fi
  # write the discovered MAC address into $CONFIG-MAC-GW2 so we don't have 
  # to resolve it on succeeding runs
  echo MAC_GW2=${MAC_GW2} > $CONFIG_MAC_GW2
fi
# [...]
iptables -A FORWARD -i br0.105 -s $IP_H1 -m mac --mac-source $MAC_GW2 -j REJECT

Поскольку G1 - это Linux-сервер, почему бы просто не протестировать внешний интерфейс G2 с помощью ping-теста и изменить маршрут по умолчанию, когда он не отвечает? И, черт возьми, если вы сделаете это правильно, вы можете автоматически выполнить резервное копирование, когда пинги снова начнут работать.