LINUX.ORG.RU
ФорумAdmin

Openvpn с двумя хвостами и MARK/CONNMARK


0

1

значит конфигурация такая. есть Openvpn сервер, с двумя провайдерами, соотв две статики, eth1 - 1.1.1.1 gw 1.1.1.2 eth2 - 2.2.2.1 gw 2.2.2.2

 
ip r:
1.1.1.0/24 dev eth1  proto kernel  scope link  src 1.1.1.1 
2.2.2.0/24 dev eth2  proto kernel  scope link  src 2.2.2.1 
default via 2.2.2.2 dev eth2 

ip r s t 1:
default via 1.1.1.2 dev eth1

ip r s t 2:
default via 2.2.2.2 dev eth2

ip ru:
0:	from all lookup local 
32760:	from all fwmark 0x2 lookup 1 
32764:	from 1.1.1.1 lookup 1
32765:	from 2.2.2.1 lookup 2
32766:	from all lookup main 
32767:	from all lookup default 

iptables:

iptables -t mangle -A INPUT -i eth1 -p udp --dport 1194 -j MARK --set-mark 2
iptables -t mangle -A INPUT -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
это базовые правила по которым дол;но все работать как надо, но... маршрутами стоят соот шлюзы провайдеров, соотв добавлены правила ip rule для хождения трафика через те интерфейсы с которых они пришли, таким образом работает автоматическое переключение дефолтного маршрута, в случае падения одного из провайдеров. у впн клиентов в конфигах прописаны обе статики сервера, чтобы в случае отказа какой либо, клиент подключался через другую. все работает хорошо, только есть один момент, не возможно подключится к впн серверу по той статике которая в данный момент не является маршрутом по умолчанию в мейне, смотрю в iptraf , клиент пытается подключиться , а ответ от сервера идет через дефолтный маршрут , а не через тот шлюз с которого пришел. сейчас начнете тыкать носом в эту тему iproute2+connmark, уже как только не извращался с коннмарком, видимо коннмарк не может тут корректно работать, тк соединение фактически не установлено те первый пакет имеет статус UNREPLIED, а просто марк сюда не подходит тк надо следить фактически за ответами сервера после долгих ковыряний прихожу к выводу, что пока это особенность работы опенвпн сервера, тк на этом же сервере вэбсервер работает как надо по обоим интерфейсам и без использования коннмарка, достаточно только правил маршрутизации. и напоследок лог того как маркируются пакеты в Iptables
sudo iptables -L -n -v -t mangle
Chain PREROUTING (policy ACCEPT 13180 packets, 7377K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    9   682 CONNMARK   all  --  eth1   *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore 
    2    84 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match !0x0 LOG flags 0 level 4 
    2    84 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           connmark match !0x0 LOG flags 0 level 4 

Chain INPUT (policy ACCEPT 1892 packets, 238K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    3   126 MARK       udp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           udp dpt:1194 MARK xset 0x2/0xffffffff 
    6   508 CONNMARK   all  --  eth1   *       0.0.0.0/0            0.0.0.0/0           CONNMARK save 
    3   126 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           connmark match !0x0 LOG flags 0 level 4 
    3   126 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match !0x0 LOG flags 0 level 4 

Chain FORWARD (policy ACCEPT 11288 packets, 7139K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           connmark match !0x0 LOG flags 0 level 4 
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match !0x0 LOG flags 0 level 4 

Chain OUTPUT (policy ACCEPT 1606 packets, 289K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 1606  289K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore 
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match !0x0 LOG flags 0 level 4 
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           connmark match !0x0 LOG flags 0 level 4 

Chain POSTROUTING (policy ACCEPT 12894 packets, 7428K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match !0x0 LOG flags 0 level 4 
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           connmark match !0x0 LOG flags 0 level 4 
отсюда видно, что входящие соединения маркируются, марки сохраняются в соединениях, но не восстанавливаются, думаю как раз потому, что ответ опенвпн сервера начинает исходить с другим адресом источника( с другого интерфейса), из-за этого модуль коннтрак не считает его родственным соединению и не восстанавливает марку.



Последнее исправление: xeon_greg (всего исправлений: 1)

Вот такое дополнение для роут таблицы №1 вроде как должно пофиксить проблему:

table 1:

1.1.1.0/24 dev eth1 src 1.1.1.1
default via 1.1.1.2 dev eth1
BOOBLIK ★★★★
()
Ответ на: комментарий от BOOBLIK

а смысл в нем если оно уже содержится в main? проблема ведь в том что впнсервер изначально формирует ответ с другим адресом источника (eth2)

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

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

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

Много букв, читать не стал.

При ответе на запрос отвечающему не нужно выбирать адрес источника пакета - он отвечает на др. пакет.

Как только есть несколько интерфейсов и возможность ассиметричной маршрутизации, сразу нужно вспомнить про rp_filter. Эти грабли нужно помнить!

У локально сгенерированных пакетов есть проблема ( если сокет не прибит к определенному адресу) - нужно выбрать адрес источника ( по таблице машрутизации).

Наличие dgw в основной таблице маршутизации - основной источник проблем в таких ситауциях.

32760:	from all fwmark 0x2 lookup 1 
32764:	from 1.1.1.1 lookup 1
32765:	from 2.2.2.1 lookup 2

источник проблем при обрашении к соседним машинам, т.к. не просматриваются прямые маршруты (которые есть в main).

Порядок правил должен быть

1 local

2 main (без dgw и со всеми дополнительными локальными маршрутиами)

3 все специфические правила (from,fwmark)

4 какая-нибудь табличка с dgw по-умолчанию

п.4 нужен для локально генерируемых пакетов без явно заданного адреса и меток!

отладка правил упрощается с использованием «ip ro get»

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 2)
Ответ на: комментарий от vel

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

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

Сидеть на двух стульях одновременно - не просто, особенно если хочется это делать элегантно :)

Какая проблема вынести dgw из main (если управлять сервером локально или через ipkvm или с локальной тачки) ? Да даже если удаленно - добавить маршрут до себя и грохнуть dgw.

vel ★★★★★
()
Ответ на: комментарий от vel

да по возможности, при минимальном использовании людьми сервера попробую таки вынести дгв из мейна, посмотрю на результат

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

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

Ничего удивительного - Apache использует TCP. Переведите OpenVPN на TCP и его поведение тоже изменится.

VitalkaDrug ★★
()
Ответ на: комментарий от VitalkaDrug

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

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

4 какая-нибудь табличка с dgw по-умолчанию

п.4 нужен для локально генерируемых пакетов без явно заданного адреса и меток!

таки не канает для локальных процессов, смотрят они исключительно в мейн и дефолт(и если там пусто то - network unreachable) а кастомно созданную как будто игнорируют напроч,хоть она и по приоритету выше их

xeon_greg
() автор топика
Ответ на: комментарий от xeon_greg

получается таки отследить, ответы впн сервера, которые исходят не через тот шлюз что нужно, по состоянию пакета, у него статус NEW, также получается поставить на него марку и с помощью правила маршрутизации завернуть в нужный интерфейс, НО, адрес источника остается старым хоть уже и в новом интерфейсе, при попытке подмены адреса источника в нате, ядро выставляет новый ! исходящий порт , те отличный от 1194, :) попытка подмены в нате вместе с портом, те принудительно заменить адрес.порт, согласно iptraf ответа не дает вообще, хотя iptables счетчиком пакетов показывает что правило работает и пакеты таки натятся. опять тупик...

xeon_greg
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.