Сбой VPN-шлюза в пользовательской таблице маршрутизации

Сбой VPN-шлюза в пользовательской таблице маршрутизации

Моя цель — настроить контейнер так, чтобы он вел себя как маршрутизатор, распределяющий нагрузку по нескольким VPN-подключениям.

Для этого я вероятностно помечаю инициирующие пакеты следующим образом:

iptables -I PREROUTING -t mangle -j CONNMARK --restore-mark
iptables -A PREROUTING -t mangle -m statistic --mode random --probability .50 -j MARK --set-mark 200 -m mark --mark 0
iptables -A PREROUTING -t mangle -j MARK --set-mark 201 -m mark --mark 0
iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark

Который выбирает одну из двух таблиц маршрутизации:

echo "200     tun0" >> /etc/iproute2/rt_tables
echo "201     tun1" >> /etc/iproute2/rt_tables 
ip rule add fwmark 200 table tun0
ip rule add fwmark 201 table tun1

Я считаю, что таблица маршрутизации выбирается правильно, потому что когда я настраиваю любую из таблиц tun0/1 для использования VPN-шлюза, трафик, похоже, не возвращается. A tcpdumpпоказывает, что трафик выходит, но любая команда не выполняется.

ip route add default 10.7.7.1 dev tun0 table tun0
ip route add default 10.7.7.1 dev tun1 table tun1

Если таблицы tun0/1 используют не-VPN шлюз, 10.10.10.1трафик ведет себя как и ожидалось. Я также могу выбирать между VPN шлюзами, установив маршрут по умолчанию в главной таблице:

ip route add default 10.7.7.1 dev tun0/1

Так что проблема, похоже, возникает, когда шлюз VPN выбирается через одну из пользовательских таблиц, а не через основную таблицу. Любые подсказки/диагностика/советы приветствуются!

Примечание: Я настроил необходимые параметры:

echo 0 > /proc/sys/net/ipv4/conf/**/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
sysctl -w net.ipv4.fwmark_reflect=1
sysctl -w net.ipv4.ip_forward=1

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE

ОТВЕЧАТЬ:

Ответ @AB дает решение. Мне нужно добавить маршрут для трафика, возвращающегося в локальную сеть, в таблицы tun0/1:

ip r a 10.10.10.0/24 via 10.10.10.1 table tun0
ip r a 10.10.10.0/24 via 10.10.10.1 table tun1

Как сказал @AB, без этих маркировок пакеты отправляются обратно в тот контейнер, в котором они были получены.

решение1

Давайте проследим, что произойдет.

  • Пакет (первый из нового потока) поступает из нетуннельного интерфейса
  • conntrackсоздать новую запись для этого пакета, начав новый поток
  • пакет получает (случайным образом, на этот раз: ) отметку 200 перед решением о маршрутизации
  • пакет маршрутизируется с использованием таблицы 200
  • таблица 200 имеет одну возможность: пакет будет отправлен черезtun0
  • метка пакета сохраняется для всего потока в егоconntrackзапись (т.е.:коннмарк).

Пока все хорошо, пакет (и его поток) был сбалансирован по нагрузке черезtun0.

Что же происходит, когдаотвечатьпакет в этом потоке возвращается?

  • ответный пакет приходит отtun0

  • Ответный пакет идентифицируетсяconntrackкак часть существующего потока

  • пакет наследует отметку 200 от своегоконнмарксвязанный с существующим потоком до принятия решения о маршрутизации

  • пакет маршрутизируется с использованием таблицы 200

  • таблица 200 имеет одну возможность: пакет будет отправлен черезtun0

    Упс: ответный пакет направляется обратно оттуда, откуда он пришел: через туннельный интерфейс, а не оттуда, откуда пришел исходный пакет потока.

  • В зависимости от того, отключил ли маршрутизатор следующего перехода (удаленная конечная точка туннеля) функцию Strict Reverse Path Forwarding ( rp_filter=0) или нет, пакет либо отбрасывается, либо снова направляется обратно, создавая петлю до тех пор, пока его уменьшающееся значение TTL не достигнет 0.

Таким образом, проблема возникает, когда VPN-шлюз выбирается через одну из пользовательских таблиц, а не через основную таблицу.

Действительно,основнойТаблица маршрутизации имеет более одного маршрута по умолчанию. Обычно она включает один или несколько маршрутов LAN. Поэтому, когда нет метки, ответ маршрутизируется правильно после оценкивсеосновных записей таблицы маршрутизации, а не просто следуя маршруту по умолчанию.

Эти дополнительные маршруты локальной сети: маршруты с использованиемeth0иeth1или, по крайней мере, тот, который включает клиентские запросы, если не оба, также должен быть скопирован в дополнительные таблицы маршрутизации 200 и 201.


Дополнительное замечание (не относится к случаю OP): В настройке, работающей в противоположном направлении: исходные потоки из отдельных узлов, которые используют один и тот же (частный) IP-адрес источника к одному и тому же сервису, могут быть два различных потока, выглядящих одинаково (один и тот же 5-uple protocol, saddr, sport, daddr, dport), за исключением их туннельного интерфейса. По умолчаниюconntrackбудет видеть один поток. Чтобы предотвратить это, можно использоватьзоны conntrack, (со значением, выбранным для представления интерфейса) иметьconntrackобращайтесь с ними по отдельности.

Связанный контент