The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Тонкости настройки Linux при подключении к двум и более провайдерам
Подключение к интернет через нескольких провайдеров давно уже не редкость. 

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

Также хочется вместо термина "провайдер" использовать "канал", поскольку
некоторые люди путаются - "провайдер у меня один", а вот шлюзов (и
адресов в различных подсетях) он предоставляет несколько (ну, так бывает
нужно по разным мотивам). 

Написано на эту тему также уже довольно много. Но есть что дополнить,
поэтому приступим. 

Вводная часть. 

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

Делается это с использованием набора пользовательских таблиц
маршрутизации. Для удобства использования, им можно присваивать
admin-friendly имена, что делается прописыванием строк в файл
/etc/iproute2/rt_tables. Строки имеют вид 

примерно такой: 

   100 northtelecom 
   101 southtelecom 

Таблицы можно не именовать, а использовать во всех подкомандах команды
ip безликие цифры, в этом случае ничего в файл rt_tables прописывать не
потребуется. Также, часть документации таблицы именует именами вида
"Т1", "Т2" что тоже, на мой взгляд, слабо удобно при просмотре правил. 

Отлично, таблицы поименованы. Далее требуется указать шлюзы, на которые
требуется отправлять трафик. 

Обычно для этого прописывается пара команд в системный файл-скрипт,
который отвечает за "подъем" маршрутизатора. 

На PC-маршрутизаторе вполне можно для этих целей использовать
непосредственно /etc/rc.local. Итак, команды указания маршрутов в
интернет выглядят так: 

   ip route add default via northtelecom_gw table northtelecom 
   ip route add default via southtelecom_gw table southtelecom 

Отлично! Мы создали две таблицы маршрутизации, внесли в них значения
двух шлюзов для маршрутизации трафика. 

Теперь эти таблицы надо начать применять. Обдуманное применение таблиц
маршрутизации заключается в использовании команды "ip rule" и выглядит
это примерно так: 

   ip rule add from northtelecom_ip lookup northtelecom 
   ip rule add from southtelecom_ip lookup southtelecom 

На самом деле, это еще не совсем обдуманное применение, поскольку не
указаны приоритеты правил (забегая вперед, уточним что они указываются
использованием "ip rule add .... pref <priority>"). 

Посмотрим на получившийся результат: 

   debian:~# ip ru 
   0: from all lookup local 
   32764: from southtelecom_ip lookup southtelecom 
   32765: from northtelecom_ip lookup northtelecom 
   32766: from all lookup main 
   32767: from all lookup default 

Что означает полученный вывод ? 

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

Далее, пакет будет проверен нашими двумя правилами 32764 и 32765, на
предмет адреса отправителя, и, в случае совпадения, будет отправлен в
соответствующую таблицу маршрутизации. 

Если адрес отправителя не совпадет с southtelecom_ip или
northtelecom_ip, поиск маршрута пойдет с использованием таблицы "main",
а таблица "default" (пока еще?) дистрибутивно чиста. Как вы могли
заметить, если маршрут не будет найден в таблице, на которую поиск будет
завернут правилом, то поиски-проверки будут продолжены со следующего
правила. 

Таблица "main" - это основная таблица, используемая по-умолчанию всеми
командами-программами, связанными с маршрутизацией. При поднятии
интерфейсов в неё прописываются маршруты к подсетям интерфейсов,
стартовые скрипты также заносят в эту таблицу значение шлюза
по-умолчанию. Использование команды "route add" администратором также
может дополнить таблицу машрутами. В общем случае, таблица "main" всегда
содержит подходящий для пакета маршрут (например шлюз по-умолчанию). 

Закончим вводную часть и приступим к "первому сложному моменту". 

Некоторые источники рекомендуют использовать еще и примерно такие
команды при описании таблиц провайдеров: 

   ip route add northtelecom_net dev northtelecom_if src northtelecom_ip table northtelecom 
   ip route add southtelecom_net dev southtelecom_if src southtelecom_ip table southtelecom 

Во-первых, хочется заметить что можно упростить команду, опустив
уточнение "src northtelecom_ip", поскольку таблица будет выбираться
путем сравнения IP-адреса отправителя пакета с некоторым значением, т.е.
адрес уже будет задан. 

А во-вторых, объясню более подробно, зачем нужны соответствующие маршруты. 

Без дополнительной команды таблица northtelecom содержит следующие
маршруты (да, пока, только один маршрут): 

   debian:~# ip ro sh table northtelecom 
   default via northtelecom_gw dev northtelecom_if 

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

   ip route add northtelecom_net dev northtelecom_if table northtelecom 
   ip route add southtelecom_net dev southtelecom_if table southtelecom 

Вроде бы всё здорово, пакеты в непосредственно присоединенные сети
провайдеров идут напрямую к хостам. Но неужели у нас отсутствует
локальная сеть ? Чаще всего она у нас есть. Но что же произойдет, если
из локальной сети будет произведено обращение к одному из адресов
northtelecom_ip или southtelecom_ip ? 

Посмотрим еще раз на вывод команды "ip rule" 


   debian:~# ip ru 
   0: from all lookup local 
   32764: from southtelecom_ip lookup southtelecom 
   32765: from northtelecom_ip lookup northtelecom 
   32766: from all lookup main 
   32767: from all lookup default 

В соответствии с правилами, маршрут отправки пакетов, исходящих с
адресов northtelecom_ip или southtelecom_ip, будет производиться в
таблицах northtelecom и southtelecom, что в конечном счете приведет к
отправке пакета в сторону шлюза провайдера. Поскольку это слегка не то,
что нам нужно, придется дополнить таблицы еще парочкой маршрутов. 

   ip route add local_net dev local_if table northtelecom 
   ip route add local_net dev local_if table southtelecom 

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

   ip route add local_net2 via local_router2 table northtelecom 
   ip route add local_net3 via local_router2 table northtelecom 
   ip route add local_net2 via local_router2 table southtelecom 
   ip route add local_net3 via local_router2 table southtelecom 

Много правил, много команд, легко запутаться, потерять, забыть что-то
прописать ... Неужели нельзя проще ? 

Как показывает практика, можно, но не всегда. 

Легкий трюк, который в большинстве случаев помогает, выглядит так: 

   ip rule add lookup main pref 1000 
   ip ro add default via (northtelecom|southtelecom)_gw table default 
   ip ro delete default table main 

Что он означает? Посмотрим на таблицу правил командой "ip rule" (да, я
уже перенабрал набор правил с указанием приоритетов) 

   debian:~# ip ru 
   0: from all lookup local 
   1000: from all lookup main 
   3000: from southtelecom_ip lookup southtelecom 
   3010: from northtelecom_ip lookup northtelecom 
   32766: from all lookup main 
   32767: from all lookup default 

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

Всё, теперь локальные и присоединенные сети вносить в таблицы
"southtelecom" и "northtelecom" необходимости нет. Достаточно эти
таблицы сформировать командами 

   ip route add default via northtelecom_gw table northtelecom 
   ip route add default via southtelecom_gw table southtelecom

и получить работоспособность. Но этот легкий трюк имеет некоторый
побочный эффект, который иногда ограничивает его прямое применение. 

Допустим, что от хоста из сети southtelecom_net идет обращение к
northtelecom_ip. Поскольку теперь маршрут приоритетно ищется в таблице
main, то ответные пакеты с адреса northtelecom_ip будут отправлены через
интерфейс southtelecom_if непосредственно к обратившемуся хосту. C одной
стороны, это можеть быть здорово, пакеты пойдут кратчайшим путем, мы
можем ожидать более высокой скорости передачи ответа и массы других
полезных вещей, но с другой стороны это может оказаться не тем, чего от
нас ожидал наш провайдер southtelecom, который ограничил нас на нашем
порту коммутатора парой MAC+IP... 

В общем, вышеописаный трюк - это трюк для слегка ленивых. Оптимальным
методом решения задачи является создание третьей пользовательской
таблицы "localnets" и указание в ней части маршрутов (маршрутов к
локальным сетям) из таблицы main. В этой конфигурации, ответ при
обращении из сети southtelecom_net к адресу northtelecom_ip пойдет точно
также, как если бы второй канал в сеть southtelecom_net на
маршрутизаторе отсутствовал, т.е. через сеть провайдера northtelecom, а
не напрямую к хосту. Приведу набор команд, формирующих решение, а анализ
того, как будет определяться маршрут для пакетов оставлю пытливым умам
читателей. 

   ip route add local_net dev local_if table localnets 
   ip route add local_net2 via local_router2 table localnets 
   ip route add local_net3 via local_router2 table localnets 

   ip route add southtelecom_net dev southtelecom_if table  southtelecom 
   ip route add default via southtelecom_gw table southtelecom 

   ip route add northtelecom_net dev northtelecom_if table northtelecom 
   ip route add default via northtelecom_gw table northtelecom 

   ip rule add lookup table localnets pref 1000 
   ip rule add from southtelecom_ip lookup southtelecom pref 3000 
   ip rule add from northtelecom_ip lookup northtelecom pref 3010 

   debian:~# ip ru 
   0: from all lookup local 
   1000: from all lookup localnets 
   3000: from southtelecom_ip lookup southtelecom 
   3010: from northtelecom_ip lookup northtelecom 
   32766: from all lookup main 
   32767: from all lookup default 

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

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

Например, это делается так: 

   ip ru add from 192.168.0.100 lookup southtelecom pref 2000 
   ip ru add from 192.168.0.128/25 lookup northtelecom pref 2010 

Названия провайдеров "southtelecom" и "northtelecom" являются
вымышленными, совпадения, если таковые имеются, случайны.
 
24.03.2009 , Автор: Pavel V. Rochnyack
Ключи: policy, route, linux / Лицензия: CC-BY
Раздел:    Корень / Администратору / Сетевая подсистема, маршрутизация / Policy routing

Обсуждение [ Линейный режим | Показать все | RSS ]
 
  • 1.1, Heckfy, 19:33, 24/03/2009 [ответить] [смотреть все]
  • +/
    Тема подымалась много раз, но так хорошо описывается впервые.
    Спасибо. :)
     
     
  • 2.2, pavel_simple, 20:08, 24/03/2009 [^] [ответить] [смотреть все] [показать ветку]
  • +/
    поддерживаю... весь текст скрыт [показать] [показать ветку]
     
  • 1.3, i, 20:42, 24/03/2009 [ответить] [смотреть все]  
  • +/
    за подробность спасибо, надо будет со своим сравнить... может чего переделаю ;)
     
  • 1.5, shadow_alone, 07:29, 25/03/2009 [ответить] [смотреть все]  
  • +/
    Отлично все описано, спасибо автору.
    В свое время долго над этим бился. :)
     
  • 1.6, Сергей, 07:41, 25/03/2009 [ответить] [смотреть все]  
  • +/
    А где же roundrobin?
     
  • 1.7, lexx, 09:52, 25/03/2009 [ответить] [смотреть все]  
  • +/
    Да, долго искал такое...
    Можно еще сходить по этой ссылке
    http://web.archive.org/web/20071026131202/http://gazette.linux.ru.net/rus/articles/lartc/x348.html
     
     
  • 2.8, scan, 23:28, 25/03/2009 [^] [ответить] [смотреть все] [показать ветку]  
  • +/
    избитая тема ничего нового всё уже было описано чёрти-когда на lartc org ... весь текст скрыт [показать] [показать ветку]
     
     
  • 3.9, Zz, 09:04, 28/03/2009 [^] [ответить] [смотреть все]  
  • +/
    Видимо, вы даже не попробовали прочитать, если считаете, что в статье нет ничего... весь текст скрыт [показать]
     
  • 3.11, alexanderyt, 10:35, 30/03/2009 [^] [ответить] [смотреть все]  
  • +/
    Старческое ворчание ... весь текст скрыт [показать]
     
  • 1.10, Аноним, 10:27, 30/03/2009 [ответить] [смотреть все]  
  • +/
    TraffPro такое уже давно позволяет делать.
     
     
  • 2.12, Andrey Mitrofanov, 12:23, 30/03/2009 [^] [ответить] [смотреть все] [показать ветку]  
  • +/
    И почему _он_ не написал правильную статью B- ... весь текст скрыт [показать] [показать ветку]
     
  • 1.15, Vasya, 09:19, 15/04/2009 [ответить] [смотреть все]  
  • +/
    А как сделать, чтоб результат этих манипуляций сохранился после перезагрузки? Запихнуть все это в скрипт?
     
     
  • 2.16, Zz, 10:20, 15/04/2009 [^] [ответить] [смотреть все] [показать ветку]  
  • +/
    >А как сделать, чтоб результат этих манипуляций сохранился после перезагрузки? Запихнуть все
    >это в скрипт?

    Да, других вариантов похоже нет

     
  • 2.23, Eerie, 20:55, 22/04/2013 [^] [ответить] [смотреть все] [показать ветку]  
  • +/
    cat /etc/network/interfaces
    # Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
    # /usr/share/doc/ifupdown/examples for more information.
    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet static
    address 192.168.0.1
    netmask 255.255.255.0
    auto eth2
    iface eth2 inet static
    address X.X.X.134
    netmask 255.255.255.0
    gateway X.X.X.1
    metric 40
    post-up /sbin/ip route add default via X.X.X.1 table dsn
    post-up /sbin/ip rule add from X.X.X.134 lookup dsn

    auto eth3
    iface eth3 inet static
            address X.X.X.236
            netmask 255.255.255.0
            gateway X.X.X.1
    metric 20
    post-up /sbin/ip route add default via X.X.X.1 table cyber
            post-up /sbin/ip rule add from X.X.X.236 lookup cyber

    вот у меня статика, и можно сделать так. подсети мне не нужны, нужна доступность хоста по 2м адресам.
    для динамических ip скрипт пишется в папку ifup.d

     
  • 1.17, kvant, 06:33, 18/01/2010 [ответить] [смотреть все]  
  • +/
    Тема "разжёвана" просто на все 100%, если бы наши преподаватели так материал могли доносить до студентов, то Билли работал бы на нас. :)
     
  • 1.18, Feonik, 12:57, 04/02/2010 [ответить] [смотреть все]  
  • +/
    Судя по всему, вместо

    ip rule add lookup table localnets pref 1000

    следует читать

    ip rule add lookup localnets pref 1000

    Иначе команда вообще не работает.

     
  • 1.19, hzone, 16:00, 11/10/2010 [ответить] [смотреть все]  
  • +/
    всё очень круто описано, но нельзя ли выложить полный скрипт без размышлений вслух?
    видать я запутался :) где-то!
     
  • 1.20, Vladsky, 11:13, 05/11/2011 [ответить] [смотреть все]  
  • +/
    пример бы реализации, когда одно соединение ppp
     
  • 1.21, ufos, 02:00, 19/04/2012 [ответить] [смотреть все]  
  • +/
    Внесу поправку, автор немного не верно написал..

    ip rule add lookup table localnets pref 1000

    нужно смотреть как

    ip rule add from all lookup localnets pref 1000

    возможно в более ранних версиях Linux она и работала, но сейчас получилось именно так.

     

    Ваш комментарий
    Имя:         
    E-Mail:      
    Заголовок:
    Текст:



      Закладки на сайте
      Проследить за страницей
    Created 1996-2017 by Maxim Chirkov  
    ДобавитьРекламаВебмастеруГИД  
    Hosting by Ihor