Сети

Настройка маршрутизации для двух интерфейсов с GRE туннелем

Решение проблемы асимметричной маршрутизации при настройке GRE туннеля с двумя сетевыми интерфейсами. Использование таблиц маршрутизации и CONNMARK.

5 ответов 12 просмотров

Как настроить маршрутизацию для двух сетевых интерфейсов на VPS-шлюзе с GRE туннелем? Проблема: при обращении к сервису через первый интерфейс (11.1.1.1:11336) все работает корректно, но при обращении через второй интерфейс (22.2.2.2:11336) запросы доходят до сервиса, а ответы возвращаются через первый интерфейс. Конфигурация включает iptables-правила для проброса порта, таблицы маршрутизации (isp1, isp2) и правила маркировки соединений. Как исправить маршрутизацию ответных пакетов через тот же интерфейс, через который пришел запрос?

Настройка маршрутизации ответных пакетов через GRE туннель требует использования таблиц маршрутизации и маркировки соединений с помощью iptables и CONNMARK. Основная проблема, с которой вы столкнулись, возникает из-за асимметричной маршрутизации, когда ответы возвращаются через другой интерфейс, через который пришел запрос. Для решения этой проблемы необходимо создать отдельные таблицы маршрутизации для каждого интерфейса и правильно настроить маркировку соединений.


Содержание


Проблема маршрутизации ответных пакетов через GRE туннель

При работе с GRE туннелем на VPS-шлюзе с двумя сетевыми интерфейсами возникает классическая проблема асимметричной маршрутизации. Когда клиент обращается к вашему сервису через первый интерфейс (11.1.1.1:11336), все работает корректно, а при обращении через второй интерфейс (22.2.2.2:11336) запросы успешно доходят до сервиса, но ответы возвращаются через первый интерфейс.

Эта проблема возникает потому, что система по умолчанию не сохраняет информацию о том, через какой интерфейс пришел запрос, и использует стандартные правила маршрутизации для ответов. В Linux-системах для решения этой задачи используются специальные таблицы маршрутизации и механизмы маркировки соединений.

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


Настройка таблиц маршрутизации для двух интерфейсов

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

Сначала создайте файл с таблицами маршрутизации:

bash
echo "100 isp1" >> /etc/iproute2/rt_tables
echo "101 isp2" >> /etc/iproute2/rt_tables

Затем настройте маршруты для каждой таблицы. Для интерфейса eth0 (11.1.1.1):

bash
ip route add default via 11.1.1.1 dev eth0 table isp1
ip route add 11.1.1.1/32 dev eth0 src 11.1.1.1 table isp1

Для интерфейса eth1 (22.2.2.2):

bash
ip route add default via 22.2.2.2 dev eth1 table isp2
ip route add 22.2.2.2/32 dev eth1 src 22.2.2.2 table isp2

Теперь создайте правила маршрутизации, которые будут определять, какую таблицу использовать для входящих пакетов:

bash
ip rule add from 11.1.1.1 table isp1
ip rule add from 22.2.2.2 table isp2

Эти правила гарантируют, что пакеты, исходящие от адресов ваших интерфейсов, будут маршрутизироваться через соответствующие таблицы. Однако для решения проблемы с ответными пакетами этого недостаточно — необходимо добавить правила для восстановления маркировки соединений в iptables.

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


Использование iptables и CONNMARK для правильной маршрутизации

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

Настройте таблицу mangle в iptables:

bash
# Маркировка входящих пакетов через GRE туннель
iptables -t mangle -A PREROUTING -d $OLD_PUB_IP -p udp --dport $VPN_PORT -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -d $OLD_PUB_IP -p udp --dport $VPN_PORT -j CONNMARK --save-mark

# Восстановление маркировки для исходящих пакетов
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

# Маршрутизация на основе маркировки
iptables -t mangle -A PREROUTING -m mark --mark 1 -j ACCEPT
iptables -t mangle -A OUTPUT -m mark --mark 1 -j ACCEPT

Затем настройте правила маршрутизации на основе маркировки:

bash
ip rule add fwmark 1 table isp1
ip rule add fwmark 2 table isp2

Для восстановления маркировки соединений в исходящих пакетах добавьте:

bash
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

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

IT специалисты подчеркивают, что маркировка соединений (CONNMARK) эффективнее маркировки отдельных пакетов, так как сохраняется для всего соединения, что критически важно для правильной работы GRE туннелей и обеспечения стабильной маршрутизации.


Конфигурация NAT для GRE туннеля

При настройке GRE туннеля с двумя интерфейсами необходимо правильно настроить NAT (Network Address Translation). Важно помнить, что DNAT (Destination NAT) выполняется до фильтрации, а SNAT (Source NAT) - после, что критически важно для работы GRE туннелей.

Настройте проброс портов для GRE туннеля:

bash
# Проброс порта на первый интерфейс
iptables -t nat -A PREROUTING -d 11.1.1.1 -p tcp --dport 11336 -j DNAT --to-destination $SERVICE_IP:11336
iptables -t nat -A POSTROUTING -d $SERVICE_IP -p tcp --dport 11336 -j SNAT --to-source 11.1.1.1

# Проброс порта на второй интерфейс
iptables -t nat -A PREROUTING -d 22.2.2.2 -p tcp --dport 11336 -j DNAT --to-destination $SERVICE_IP:11336
iptables -t nat -A POSTROUTING -d $SERVICE_IP -p tcp --dport 11336 -j SNAT --to-source 22.2.2.2

Для корректной работы GRE туннеля с двумя интерфейсами также необходимо настроить правила маскарадинга:

bash
# Маскарадинг для трафика из таблицы isp1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o gre0 -j MASQUERADE

# Маскарадинг для трафика из таблицы isp2
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o gre0 -j MASQUERADE

Важно убедиться, что правила iptables для GRE туннеля не конфликтуют с правилами маркировки соединений. Для этого рекомендуется сначала настроить таблицы маршрутизации и маркировку соединений, а затем добавлять правила NAT.

Авторы статей по Linux-сетям подчеркивают, что при настройке iptables для GRE туннеля критически важно понимать порядок обработки пакетов и что маркировка соединений должна выполняться до правил NAT, чтобы обеспечить правильную маршрутизацию ответных пакетов.


Проверка и отладка маршрутизации

После настройки таблиц маршрутизации и iptables необходимо провести тщательное тестирование для проверки правильности конфигурации. Начните с проверки таблиц маршрутизации:

bash
ip route show table isp1
ip route show table isp2

Затем проверьте правила маршрутизации:

bash
ip rule show

Для тестирования маршрутизации используйте утилиту traceroute или tracepath:

bash
# Тестирование маршрута для первого интерфейса
traceroute -s 11.1.1.1 -p 11336 $SERVICE_IP

# Тестирование маршрута для второго интерфейса
traceroute -s 22.2.2.2 -p 11336 $SERVICE_IP

Для проверки маркировки соединений используйте утилиту conntrack:

bash
conntrack -L

Если вы обнаруживаете, что ответы все еще возвращаются через неправильный интерфейс, проверьте следующие моменты:

  1. Правильность настройки таблиц маршрутизации
  2. Корректность правил iptables для маркировки соединений
  3. Отсутствие конфликтов в правилах NAT
  4. Порядок обработки пакетов в цепочках iptables

Для отладки можно временно включить логирование iptables:

bash
iptables -t mangle -A PREROUTING -j LOG --log-prefix "MANGLE_PREROUTING: "
iptables -t mangle -A OUTPUT -j LOG --log-prefix "MANGLE_OUTPUT: "

Это позволит вам видеть, какие пакеты обрабатываются и как они маркируются.

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


Альтернативные решения для разных сценариев

В зависимости от вашей конфигурации и требований могут подойти альтернативные подходы к решению проблемы маршрутизации ответных пакетов через GRE туннель.

Метод без использования CONNMARK

Если вам требуется более простое решение без сложной настройки iptables, можно использовать метод, основанный только на таблицах маршрутизации:

bash
# Создание таблиц маршрутизации
echo "100 table1" >> /etc/iproute2/rt_tables
echo "101 table2" >> /etc/iproute2/rt_tables

# Настройка маршрутизации на основе исходных адресов
ip rule add from 11.1.1.1 table table1
ip route add default via 11.1.1.1 dev eth0 table table1
ip rule add from 22.2.2.2 table table2
ip route add default via 22.2.2.2 dev eth1 table table2

Этот метод проще и не требует сложной настройки iptables для маркировки соединений, но может быть менее гибким в сложных сценариях.

Использование policy routing

Для более сложных конфигураций можно использовать policy routing с маркировкой пакетов на основе различных критериев:

bash
# Маркировка пакетов на основе порта
iptables -t mangle -A PREROUTING -p tcp --dport 11336 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p udp --dport 11336 -j MARK --set-mark 2

# Маршрутизация на основе маркировки
ip rule add fwmark 1 table isp1
ip rule add fwmark 2 table isp2

Использование multipath routing

Если у вас есть несколько каналов связи одного провайдера, можно использовать multipath routing:

bash
# Настройка multipath маршрута
ip route add default nexthop via 11.1.1.1 dev eth0 weight 1 \
nexthop via 22.2.2.2 dev eth1 weight 1

Системные администраторы отмечают, что выбор метода зависит от конкретных требований к производительности, отказоустойчивости и сложности конфигурации. Для большинства случаев использования GRE туннеля с двумя интерфейсов метод с CONNMARK является наиболее надёжным и гибким решением.


Источники

  1. Настройка маркировки соединений для GRE туннеля — Техническое решение проблемы асимметричной маршрутизации с использованием CONNMARK: http://www.simtreas.ru/~dzo/peremark/

  2. Основы iptables для начинающих — Подробное объяснение порядка обработки пакетов и важности маркировки соединений: https://interface31.ru/tech_it/2020/02/osnovy-iptables-dlya-nachinayushhih-chast-1.html

  3. Настройка таблиц маршрутизации для двух интерфейсов — Статья по настройке маршрутизации через разные провайдеры: https://habr.com/ru/articles/108690/

  4. Настройка нескольких таблиц маршрутизации на одном сервере — Альтернативный подход без использования CONNMARK: https://timeweb.com/ru/community/articles/nastroyka-neskolkih-tablic-marshrutizacii-na-odnom-servere

Заключение

Правильная настройка маршрутизации для двух сетевых интерфейсов на VPS-шлюзе с GRE туннелем требует комплексного подхода, включающего создание таблиц маршрутизации, настройку iptables для маркировки соединений и правильную конфигурацию NAT. Основная проблема, с которой вы столкнулись, решается с использованием механизма CONNMARK, который сохраняет метку для всего соединения, гарантируя, что ответы вернутся через тот же интерфейс, через который пришел запрос.

Для большинства случаев рекомендуется использовать метод с CONNMARK, так как он обеспечивает максимальную гибкость и надёжность. Однако для простых конфигураций может подойти альтернативный метод, основанный только на таблицах маршрутизации без использования iptables.

Для решения проблемы маршрутизации ответных пакетов через GRE туннель используйте двойную маркировку соединений. В PREROUTING mangle сначала устанавливаем MARK, затем сохраняем CONNMARK. Для входящих пакетов через GRE туннель применяем правила:

iptables -t mangle -A PREROUTING -d $OLD_PUB_IP -p udp --dport $VPN_PORT -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -d $OLD_PUB_IP -p udp --dport $VPN_PORT -j CONNMARK --save-mark

Затем восстанавливаем connmark и добавляем правила маршрутизации в отдельные таблицы. Это гарантирует возврат ответов через тот же интерфейс.

Записки IT специалиста / Блог

При настройке iptables для GRE туннеля важно понимать порядок обработки пакетов. Маркировка соединений (CONNMARK) эффективнее маркировки отдельных пакетов, так как сохраняется для всего соединения. Для правильной маршрутизации через два интерфейса используйте таблицу mangle в цепочке PREROUTING для маркировки входящих пакетов, а затем восстанавливайте маркировку в OUTPUT. DNAT выполняется до фильтрации, а SNAT - после.

P

Для настройки маршрутизации ответных пакетов через GRE туннель с двумя интерфейсами создайте отдельные таблицы маршрутизации для каждого провайдера. Сначала создайте таблицы:

ip route add default via 11.1.1.1 dev eth0 table isp1
ip route add default via 22.2.2.2 dev eth1 table isp2

Затем пометьте входящие пакеты через CONNMARK и создайте правила fwmark. Для восстановления маркировки в исходящих пакетах добавьте:

iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

Это обеспечит возврат ответов через тот же интерфейс.

Татьяна Щурова / Системный администратор

Альтернативный подход к решению проблемы с маршрутизацией через GRE туннель - создание таблиц маршрутизации без использования CONNMARK. Добавьте таблицы в /etc/iproute2/rt_tables:

echo 100 table1 >> /etc/iproute2/rt_tables
echo 101 table2 >> /etc/iproute2/rt_tables

Затем создайте правила маршрутизации на основе исходных адресов:

ip rule add from 11.1.1.1 table table1
ip route add default via 11.1.1.1 dev eth0 table table1
ip rule add from 22.2.2.2 table table2
ip route add default via 22.2.2.2 dev eth1 table table2

Этот метод проще и не требует сложной настройки iptables.

Авторы
P
Системный администратор
Татьяна Щурова / Системный администратор
Системный администратор
Источники
Проверено модерацией
Модерация