LINUX.ORG.RU

HELP с policy-routing'ом.

 , , , ,


0

1

Здравствуйте. Имеется сервер с 2мя аплинками разной пропускной способности и с разными подсетями IP-адресов (и разными шлюзами, естественно, предположим, главный и основной интерфейс имеет IP 1.1.1.2 и резервный имеет IP 2.2.2.2.) Была произведена настройка роутинга для того, чтобы пакеты для каждого интерфейса приходили и уходили только на этот конкретный интерфейс (руководствовался статьей http://lartc.org/howto/lartc.rpdb.multiple-links.html). Работает, хорошо. Но позже возникла необходимость отправлять запросы к DNS через второй, резервный аплинк, а не основной, тот что по дефолту. Для этого было применено маркирование пакетов:

-A OUTPUT -p tcp -m tcp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
-A OUTPUT -p udp -m udp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
Маркирование работает, -j LOG подтверждает это:
MARK=0x1
Далее я попытался использовать ip route policy routing based on packet marks, как указано в статье http://lartc.org/howto/lartc.netfilter.html.

ip rule:

0:      from all lookup local
32763:  from 1.1.1.2 lookup eth0
32764:  from 2.2.2.2 lookup eth1
32765:  from all fwmark 0x1 lookup eth1
32766:  from all lookup main
32767:  from all lookup default
cat /etc/iproute2/rt_tables:
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep

200 eth0
201 eth1
202 eth0:0
В /etc/network/interfaces имеется следующее:
up ip route add 1.1.1.0/24 dev eth0 src 1.1.1.2 table eth0
up ip route add 2.2.2.0/26 dev eth1 src 2.2.2.2 table eth1
up ip route add default via 1.1.1.1 table eth0
up ip route add default via 2.2.2.1 table eth1
up ip rule add prio 32763 from 1.1.1.2 table eth0
up ip rule add prio 32764 from 2.2.2.2 table eth1
up ip rule add prio 32765 fwmark 1 lookup eth1
Собственно проблема в том, что полиси-роутинг не работает, пакеты на порт 53 отправляются все равно с дефолтного интерфейса, несмотря на то, что маркировка работает и правила для полиси-роутинга вроде бы составлены правильно (игрался с ip rule prio, сначала правило для eth0 имело приоритет 32765, а для fwmark - 32763, т.е. наоборот), также игрался с числами в /etc/iproute2/rt_tables (ставил 200 для eth1 и 201 для eth0). Ничего не помогает, пакеты на порт 53 упорно шлются через default interface, и с ip 1.1.1.2. route cache естественно чистил, более того, он у меня вообще выключен. rp_filter выключен, arp - включен. других настроек, которые могли бы повлиять на эту ситуацию - не знаю. uname -a:
Linux server 3.2.0-4-amd64 #1 SMP Debian 3.2.57-3+deb7u1 x86_64 GNU/Linux
Игрался также с ip_forward в sysctl, результатов нет. Буду благодарен за помощь!



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

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

Разумеется в мангле. Спасибо за помощь, но как я сказал, маркировка работает, что я выяснил с помощью LOG. Проблема именно по части роутинга.

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

правило с fwmark должно быть до from 1.1.1.2 и до from 2.2.2.2

0:      from all lookup local
32762:  from all fwmark 0x1 lookup eth1
32763:  from 1.1.1.2 lookup eth0
32764:  from 2.2.2.2 lookup eth1

т.к. у пакета есть локальный адрес, то он обязательно попадет в правило «from 1.1.1.1» или «from 2.2.2.2» и не дойдет до правила с меткой

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

ip ru есть выше. таблицы:

root@server:/# ip route show table eth0
default via 1.1.1.1 dev eth0
1.1.1.0/24 dev eth0  scope link  src 1.1.1.2
root@server:/# ip route show table eth1
default via 2.2.2.1 dev eth1
2.2.2.0/26 dev eth1  scope link  src 2.2.2.2
root@server:/# ip route show table main
default via 1.1.1.1 dev eth0
1.1.1.0/24 dev eth0  proto kernel  scope link  src 1.1.1.2
2.2.2.0/26 dev eth1  proto kernel  scope link  src 2.2.2.2

правило с fwmark должно быть до from 1.1.1.2 и до from 2.2.2.2

from 1.1.1.2 fwmark 0x1 lookup eth1 не помогает

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

извиняюсь, не сразу понял эту

правило с fwmark должно быть до from 1.1.1.2 и до from 2.2.2.2

цитату. Я ставил так, тоже не помогает. По идее число (3276*) является приоритетом правила, чем оно выше, тем приоритет выше. По умолчанию оно было так, как Вы сказали, уже я модифицировал ее, изменив приоритет. Не помогает.

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

не надо добавлять условие «from 1.1.1.2» к «fwmark»

Я бы убрал строку «ip ru from 1.1.1.2 ...» - она лишняя, т.к. дальше все уйдет в main.

PS А как ты отключил кеширование маршрутов и зачем? А вот делать «ip ro flush table cache»

rp_filter должен быть не 0, а 2 в таком случае.

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

А как ты отключил кеширование маршрутов и зачем

Как: net.ipv4.rt_cache_rebuild_count = -1 Зачем: для производительности. Сервак де факто роутингом не занимается, а вот при интенсивном трафике кеш роутинга начинает засираться и наблюдается деградация производительности. Есть конечно возможность подтюнить соответствующие буфера , но необходимости нет - это мне не сильно надо.

Я бы убрал строку «ip ru from 1.1.1.2 ...» - она лишняя, т.к. дальше все уйдет в main.

В принципе согласен, но не думаю что это повлияет на мою проблему. Вы думаете иначе?

rp_filter должен быть не 0, а 2 в таком случае

Ставлю в 2. Не помогло, пакеты по-прежнему идут через дефолтный аплинк. ip ro flush table cache делаю, да.

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

Ага!!! Картина начинает проясняться. обращаемся к днс, слушаем tcpdump -i eth0 -nv port 53: ничего нет. слушаем tcpdump -i eth1 -nv port 53: ПАКЕТЫ ЕСТЬ, но с ip-адресом от eth0. Т.е. роут прогоняется действительно через карту eth1, но почему ip от основного аплинка? И как это возможно, если на eth1 совсем другой шлюз?

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

SNAT в помощь. Другого способа через iptables я не знаю.

Раньше существовала опция ядра CONFIG_IP_ROUTE_FWMARK с которой можно было вытворять то, что тебе нужно.

Есть другой способ - прибиндить dns-сервер к 2.2.2.2, а локальные запросы направлять на локальный сервер.

rt_cache_rebuild_count выпилили из новых ядер

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

rt_cache_rebuild_count выпилили из новых ядер

Не знаю, но после установки этой директивы в -1 роуты больше не кешируются. К сожалению с натом не вариант, его использование в моем случае недопустимо. А насчет бинда можно подробнее? Что это даст и каким образом это можно сделать? Но меня больше интересует вопрос, почему то, что я сделал, не работает как нужно. (Как нужно == как в факах). Т.е. пакеты действительно посылаются через интерфейс eth1, но имеют адрес интерфейса eth0. Хотелось бы, чтобы они имели адрес интерфейса eth1, как подобает. Имею подозрение, что данные пакеты попадают под несколько правил, что и создает суматоху: mark направляет их на интерфейс eth1, вернее в таблицу роутинга eth1, что мне и нужно, но что-то еще присваивает им все равно ип-адрес по умолчанию а не eth1, что — хотелось бы узнать и исправить.

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

Раньше существовала опция ядра CONFIG_IP_ROUTE_FWMARK с которой можно было вытворять то, что тебе нужно

Уважаемый vel, по всей видимости данная опция присутствует и сейчас, более того она сконфигурирована по умолчанию. Как интерфейс mark, так и взаимодействие route с mark работает прекрасно. Пакеты маркируются и route узнает маркировку пакетов. Но у меня именно затяжка с непосредственно route - хотелось бы узнать, почему он подставляет маркированным пакетам ип-адрес основного (default) роута, несмотря на то что пакеты заворачиваются в таблицу eth1 - со своим IP и адресом шлюза. Хочу выявить конфликт правил, или еще что-то, что стопорит нормальную работу.

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

На сколько я помню, ip адрес источника пакета (если он не задан явно) определяется при первом поиске маршрута по http://inai.de/images/nf-packet-flow.png и потом при «reroute check» он уже не меняется.

Приложение может само отмечать пакеты через setsockopt(fd,SOL_SOCKET,SO_MARK,...) и тогда все будет так как ты хотел. Или в явном виде делать bind() на нужный адрес.

А с днс все просто: в isc-bind есть опции «query-source address» и «transfer-source». Указанные адреса будут использоваться в качестве адреса источника запросов и трансфера зон. У unbound-а «outgoing-interface:»

У меня живет 2 копии бинда привязанные к своим адресам. разница в опциях dump-file, pid-file, statistics-file и в *source

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

Вот это уже возможно более близко к проблеме:

ip адрес источника пакета (если он не задан явно) определяется при первом поиске маршрута по http://inai.de/images/nf-packet-flow.png и потом при «reroute check» он уже не меняется

Каким образом можно его задать явно?

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

И у меня на сервере нет бинд. Необходимость в прибивании запросов на порт 53 в мир связана с тем, что когда мой основной аплинк ддосят dns-amp методом, то я не могу никого продиговать в это время (ограничение в 500 mbps inbound DNS traffic per dest IP), и хорошо бы было прибить мои реальные DNS запросы к другому аплинку, имеющему ip с другой подсети.

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

man 2 bind

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

например у wget есть "--bind-address", у программы dig есть опция "-b", а у host - нету

Есть разные костыли в виде LD_PRELOAD, которые позволяют сделать bind() на нужный адрес после открытия сокета :)

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

Да, добавил и про udp сразу. Ну как сказать, почему я так говорил. Дело в том, что в факе описывался способ роутинга пакетов через резервный интерфейс, но не было ни слова о том, что пакет должен иметь IP этого интерфейса; я же считал это само собой понятным и поэтому считал, что все завестись должно и без ната. Оказалось, что условия о том, что IP должен быть второго аплинка, в faq не предусматривалось; там вообще не предусматривалось наличие у него отдельного ip, о чем говорит отсутствие соответствующих правил и таблиц для роутинга на в FAQ.

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

Хотя нет, брежу. Отдельный IP предусматривался. Но почему-то в ip rule правил для заворота пакетов, приходящих на IP второго интерфейса там нет, значит они будут все идти через первый, такую проблему я также имел. Либо для чистоты примера не добавили данные правила, либо фиг знает как оно у них вообще работало. :-)

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