The OpenNET Project / Index page

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

Linux маршрутизатор с несколькими внешними интерфейсами. (debian ubuntu linux route iproute iptables nat)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: debian, ubuntu, linux, route, iproute, iptables, nat,  (найти похожие документы)
From: Трифонов Евгений aka ieroglif aka Sart <astahe@mail.ru.> Date: Mon, 6 Mar 2008 14:31:37 +0000 (UTC) Subject: Linux маршрутизатор с несколькими внешними интерфейсами. Настройка линукс маршрутизатора через iptables + iproute2 на два (и больше) внешних интерфейса. Предполагается: - то вы уже знакомы с понятием маршрутизации и ната. - теоретически понимаете как работает нат, что такое маршрутизация и файрвол, но не знаете как это реализовать на вашей системе. Имеется: - две входящие сетевые соски от двух разных провайдеров. - локальная сеть - три сетевых интерфейса на маршрутизаторе. Задача: Объеденить всех пользователей в одну локальную сеть и пускать одних пользователей в интернет через одного провайдера, других - через другого. В рассматриваемом примере, все пользователи в локальной сети будут находиться в сети 172.16.0.0/16, при этом пользователей из подсети 172.16.0.0/24 надо пропускать в интернет через первого провайдера, а пользователей 172.16.1.0/24 - через второго. Будем использовать iproute2 для таблиц маршуризации и iptables для ната. Обозначим: $IP_LOCAL="172.16.0.1" - адрес нашего маршрутизатора в локальной сети. $IP_INET1="1.1.1.2" - адрес нашего маршрутизатора в сети первого провайдера. $IP_INET2="2.2.2.2" - адрес нашего марщрутизатора в сети второго провайдера. $IF_LOCAL="eth0" - имя интерфейса на локальную сеть $IF_INET1="eth1" - имя интерфейса на первого провайдера. $IF_INET2="eth2" - имя интерфейса на второго провайдера. $NET_LOCAL="172.16.0.0/16" - локальная сеть. $NET_INET1="1.1.1.0/24" - адрес сети в которой гейт нашего первого провайдера. $NET_INET2="2.2.2.0/24" - адрес сети в которой гейт нашего второго провайдера. $NET_SUB1="172.16.0.0/24" - подсеть пользователей на первого провайдера $NET_SUB2="172.16.1.0/24" - подсеть пользователей на второго провайдера $GW1="1.1.1.1" - гейт первого провайдера. $GW2="2.2.2.1" - гейт второго провайдера. Настраиваем статические адреса на сетевые карты. Debian (ubuntu) хранит настройки в файле /etc/network/interfaces. пишем: auto lo iface lo inet loopback #local auto eth0 iface eth0 inet static address 172.16.0.1 netmask 255.255.0.0 network 172.15.0.0 broadcast 172.16.255.255 #inet 1 auto eth1 iface eth1 inet static address 1.1.1.2 netmask 255.255.255.0 gateway 1.1.1.1 network 1.1.1.0 broadcast 1.1.1.255 #inet 2 auto eth2 iface eth2 inet static #если надо - меняем мак адреса # pre-up ifconfig eth2 hw ether aa:bb:cc:cc:bb:aa address 2.2.2.2 netmask 2.2.2.0 # себе я второй гейт не прописываю, в следствии чего сам маршрутизатор ходит в инет через первый инет # gateway 2.2.2.1 network 2.2.2.0 broadcast 2.2.2.255 тем самым мы сказали, что все сетвые у нас имеют статические адреса, и указали их. Настаиваем маршрутизацию с утилитой ip. Утилита route позволяет нам обратиться к таблице маршртизации. Сила утилиты ip в том, что она позволяет создать большое количество таблиц для самых разных потребностей, а так же, способна считывать флаги, которые расставляет файрвол iptables (об этом ниже) и на их основе тоже делать какие-то действия. Основа маршрутизации через разные таблицы - правила (rule) А сила различных таблиц в том, что мы можем хранить огромное количество различных таблиц маршрутизации, через которые и будем пропускать пакеты. Просмотреть список уже имеющихся таблиц можно командой ip rule list 0: from all lookup 255 32766: from all lookup main 32767: from all lookup default Мы видим, что у нас есть три правила: таблица 255, main и default. То, что выдает нам route - хранится в таблице main, что можно увидеть командой ip route list table main В качестве номеров таблиц можно использовать цифры, ( пример: 0: from all lookup 255 ), а можно прописать на эти цифры какие-то более понятные простым смертным имена ( пример: 32766: from all lookup main ). Так что обозначим свои таблицы: Редактируем файл /etc/iproute2/rt_tables и добавляем туда записи вида: # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep 10 T1 20 T2 номер - это то самое число, которое мы можем использовать если не именовать таблицы, а строковое значение - то, что мы в действительности будем использовать. (кстати, тут же мы видим и уже встречавшиеся нам в списке правил таблицы) Теперь создаем некий скрипт, который в последствии будет все нам прописывать при старте системы. Понятное дело, что каждый использует свой любимый редактор =) /etc/init.d/route #!/bin/sh IP_LOCAL="172.16.0.1" # адрес нашего маршрутизатора в локальной сети. IP_INET1="1.1.1.2" # адрес нашего маршрутизатора в сети первого провайдера. IP_INET2="2.2.2.2" # адрес нашего марщрутизатора в сети второго провайдера. IF_LOCAL="eth0" # имя интерфейса на локальную сеть IF_INET1="eth1" # имя интерфейса на первого провайдера. IF_INET2="eth2" # имя интерфейса на второго провайдера. NET_LOCAL="172.16.0.0/16" # локальная сеть. NET_INET1="1.1.1.0/24" # адрес сети в которой гейт нашего первого провайдера. NET_INET2="2.2.2.0/24" # адрес сети в которой гейт нашего второго провайдера. GW1="1.1.1.1" # гейт первого провайдера. GW2="2.2.2.1" # гейт второго провайдера. ip route flush table T1 #обнуляем первую таблицу маршрутов ip route flush table T2 #обнуляем вторую таблицу маршрутов ip route add $NET_INET1 dev $IF_INET1 src $IP_INET1 table T1 #закидываем в первую таблицу инфу о сети первого провайдера ip route add $NET_LOCAL dev $IF_LOCAL table T1 #закидываем в первую таблицу инфу о том, что у нас существует локальная сеть ip route add $NET_INET2 dev $IF_INET2 table T1 #закидываем в первую таблицу инфу о том, что у нас существует еще одна сеть ip route add 127.0.0.0/8 dev lo table T1 #закидываем в первую таблицу инфу о существовании лупбека ip route add default via $GW_INET1 table T1 #закидываем в первую таблицу дефолтный гейт на первого провайдера ip route add $NET_INET2 dev $IF_INET2 src $IP_INET2 table T2 #закидываем во вторую таблицу инфу о сети второго провайдера ip route add $NET_LOCAL dev $IF_LOCAL table T2 #закидываем во вторую таблицу инфу о том, что у нас существует локальная сеть. ip route add $NET_INET1 dev $IF_INET1 table T2 #закидываем во вторую таблицу инфу о том, что у нас существует еще одна сеть. ip route add 127.0.0.0/8 dev lo table T2 #закидываем во вторую таблицу инфу о существовании лупбека. ip route add default via $GW_INET2 table T2 #закидываем во вторую таблицу дефолтный гейт на второго провайдера ip route add $NET_INET1 dev $IF_INET1 src $IP_INET1 #заполняем основную таблицу адресов. сеть на первого провайдера ip route add $NET_INET2 dev $IF_INET2 src $IP_INET2 #заполняем основную таблицу адресов. сеть на второго провайдера ip route add default via $GW_INET1 #заполняем основную таблицу адресов. дефолтный гейт. ip rule delete table T1 #удаляем наши таблицы, если они присутсвуют в текущей конфигурации (вдруг мы просто перезапускаем скрипт?) ip rule delete table T2 #аналогично для второй. ip rule delete table T1 #и делаем это два раза, так как у нас два правила на каждую таблицу. ip rule delete table T2 #аналогично для второй. #а вот это важно для понимая! если понять что происходит в следующих строчках - то можно настраивать любые правила маршрутизации. ip rule add from $IP_INET1 table T1 #все пакеты от ip адреса первого провайдера маршрутизировать по таблице T1 ip rule add from $IP_INET2 table T2 #все пакеты от ip адреса второго провайдера маршрутизировать по таблице T2 ip rule add fwmark 10 table T1 #все пакеты, которые имеют метку 10 маршрутизировать по таблице T1 ip rule add fwmark 11 table T2 #все пакеты, которые имеют метку 11 маршрутизировать по таблицу T2 ip route flush cache #ну и на последок очистить кеш exit 0 В целом, понятно все, за исключением одного вопроса - что же это за метка такая в последних строчках? Тут мы обращаемся к утилите iptables. Краткая теория. (полную и на русском языке можно, а вообще-то, даже нужно, читать тут http://www.opennet.ru/docs/RUS/iptables/ ) Утилита iptables так же основана на таблицах. только таблиц в ней фиксированно - три. mangles - таблица используется для изменений заголовков пакетов. filter - самая наша основаная таблица для файрвола - тут мы производим все блокировки, разрешения. nat - таблица, как понятно из названия для ната. Каждая таблица уже имеет некоторые предлопределенные цепочки, в которые можно добавлять правила, а так же поддерживает создание пользовательские цепочки. Когда паркт попадает на интерфейс, и, его ловит iptables, то он проходит следующие таблицы и цепочки, важные для нас: 1. таблица mangle цепочка PREROUTING 2. обработка маршрутизации. 3. таблица nat цепочка POSTROUTING (в действительно пакет проходит еще и через другие таблицы и цепочки, но, для планируемой маршрутизации они нафик не сдались - изучение этого вопроса уже полностью на вашей совести =) ). Скрипт для маршрутизации: /etc/init.d/iptables #!/bin/sh IP_LOCAL="172.16.0.1" # адрес нашего маршрутизатора в локальной сети. IP_INET1="1.1.1.2" # адрес нашего маршрутизатора в сети первого провайдера. IP_INET2="2.2.2.2" # адрес нашего марщрутизатора в сети второго провайдера. IF_LOCAL="eth0" # имя интерфейса на локальную сеть IF_INET1="eth1" # имя интерфейса на первого провайдера. IF_INET2="eth2" # имя интерфейса на второго провайдера. NET_LOCAL="172.16.0.0/16" # локальная сеть. NET_INET1="1.1.1.0/24" # адрес сети в которой гейт нашего первого провайдера. NET_INET2="2.2.2.0/24" # адрес сети в которой гейт нашего второго провайдера. NET_SUB1="172.16.0.0/24" # подсеть пользователей на первого провайдера NET_SUB2="172.16.1.0/24" # подсеть пользователей на второго провайдера GW1="1.1.1.1" # гейт первого провайдера. GW2="2.2.2.1" # гейт второго провайдера. IPT="/sbin/iptables" $IPT -t nat -F #очищаем таблицу nat $IPT -t mangle -F #очищаем таблицу mangle #все пакеты, которые попали в цепочку PREROUTING таблицы mangle обрабатываем по двум правилам: $IPT -t mangle -A PREROUTING -s $NET_SUB1 -d ! $NET_LOCAL -j MARK --set-mark 10 # все пакеты которые идут от $NET_SUB1 и не в $NET_LOCAL маркируем меткой 10 $IPT -t mangle -A PREROUTING -s $NET_SUB2 -d ! $NET_LOCAL -j MARK --set-mark 11 # все пакеты которые идут от $NET_SUB1 и не в $NET_LOCAL маркируем меткой 10 #все пакеты, которые попали в цепочку POSTROUTING таблицы nat обрабатываем по двум правилам: $IPT -t nat -A POTROUTING -m mark --mark 10 -j MASQUERADE # натим все пакеты которые имеют метку 10 $IPT -t nat -A POTROUTING -m mark --mark 11 -j MASQUERADE # натим все пакеты которые имеют метку 11 exit 0 И так, что же происходит. Пусть адрес пользователя 172.16.0.2 У пользователя прописан дефолтный гейт 172.16.0.1 - т.е. все пакеты которые направлены не в локальную сеть пойдут туда. На наш маршрутизатор приходит пакет от 172.16.0.2 и на адрес (к примеру) 4.4.4.4 1. пакет попадает в таблицу mangle в цепоку PREROUTING и там по правилу "все пакеты от $NET_SUB1 и не в $NET_LOCAL" маркируется меткой 10 и попускается дальше. 2. пакет попадает в правила маршрутизации и обрабатывается по правилу "все пакеты, которые имеют метку 10 маршрутизировать по таблице T1". попав в эту таблицу маршрутизатор отправляет пакет в дефолтный гейт для этой таблицы, т.к. адрес 4.4.4.4 не подходит ни под одну сеть, которые есть в этой таблице. 3. пакет попадает в таблицу nat в цепочку POSTROUTING и там по правилу "натим все пакеты которые имеют метку 10" натится наружу. Важный момент: метка пакета существует только внутри нашего марщрутизатора. выходящий пакет уже не имеет меток. Сам факт подобной реализации маршрутизации возможен только из-за того, что когда пакет обрабатывается правилами маршрутизации метка существует, так как после пакет возвращается на обработку в таблицы iptables. В целом, все =) Осталось только сделать наши скрипты исполняемыми и закинуть их на автозагрузку. Важно обратить внимание, что данный маршрутизатор будет маршрутизировать пакеты в обе стороны, так что если кто-то из внешних сетей пропишет себе ip нашей локальной сети, и укажет в качестве маршрутизатора ip нашего маршрутизатора - он спокойно попадет к нам. Но настройка файрвола - это уже второй вопрос, который в эту статью не входит.

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Обсуждение [ Линейный режим | Показать все | RSS ]
 
  • 1.1, demon, 16:27, 11/03/2008 [ответить] [смотреть все]
  • +/
    В очередной раз повторюсь, что использование SNAT в данном случае лучше чем MASQUERADE.
    Использование MASQUERADE вообще оправданно только в случае динамического IP на внешнем интерфейсе.

    Не очень понимаю зачем нужно маркировать пакеты, если прямо в POSTROUTING можно задавать условие -d



     
     
  • 2.2, ieroglif, 12:17, 12/03/2008 [^] [ответить] [смотреть все]
  • +/
    еще раз -
    1. изучение iptables - полностью на вашей совести. пусть люди сами изучают
    2. если понять фишку с маркировкой пакетов, то потом можно ее использовать при создании других правил как маршрутизации, так и фильтрации. считаю, что этот момент полезен и не столь очевиден при самостоятельном изучении как SNAT и MASQUERADE
     
  • 2.5, AnatolZ, 23:21, 14/07/2008 [^] [ответить] [смотреть все]
  • +/
    >В очередной раз повторюсь, что использование SNAT в данном случае лучше чем
    >MASQUERADE.
    >Использование MASQUERADE вообще оправданно только в случае динамического IP на внешнем интерфейсе.
    >
    >
    >Не очень понимаю зачем нужно маркировать пакеты, если прямо в POSTROUTING можно
    >задавать условие -d

    Уважаемый demon не могли бы вы привести кусок примера ?? просто получилось у меня только с использованием меток.. но он мешают при написании скрипта с шейпеньем...
    кстати неукого не завалялся скриптик :) Т.З. дано два канала 1)eth1-унлим 2)eth2-обычный ну и мега сеть 10.x.x.x с внутренней маршрутизацией OSPF(L3 коммутаторы) где дефолтный гетвей наш линукс сервер... билинг создает правило 10.1.1.1 на первый интерфейси ограничиваем его 128к, а на второй интерфейс  10.1.1.2 и на скорость наплевать...
    сделал пока только первое... а вот с двумя интерфейсами уже нет так как метка уже стоит...

     
  • 1.3, rusya, 16:40, 22/04/2008 [ответить] [смотреть все]
  • +/
    а какой айпишник указать в качестве гейта во второй локальной подсети?
    Или поднимать виртуальный интерфейс? Или что?
     
  • 1.4, Аноним, 09:23, 30/04/2008 [ответить] [смотреть все]
  • +/
    "-A POTROUTING" ?
     
  • 1.6, skyer, 09:56, 31/07/2008 [ответить] [смотреть все]  
  • +/
    Странный пример в статье. На мой взгляд SNAT превосходит по производительности MASQUERADE, метки тоже не очень оправданы в принципи. Любую маршрутизацию которую надо сделать можно загнать в соответсвующие таблицы и не напрягать ядро левой работой с разбором меток. год назад делал объединение 5 каналов из одной подсети. К стати если случайно забанится один ипшник, то часть конектов будет попадать в мертвое соединение.

     
  • 1.7, oleg, 12:45, 22/08/2008 [ответить] [смотреть все]  
  • +/
    $IPT -t nat -A POTROUTING -s $NET_SUB1 -o NET_INET1 -j SNAT 1.1.1.0/24
    $IPT -t nat -A POTROUTING -s $NET_SUB2 -o NET_INET2 -j SNAT 2.2.2.0/24

    И ненадо меток и уж тем более утилиты ip, достаточно трансляции адресов

     
     
  • 2.8, oleg, 12:47, 22/08/2008 [^] [ответить] [смотреть все]  
  • +/
    POSTROUTING естественно)). копипаста чтоб ее
     
  • 1.9, DeMarco, 11:47, 14/05/2009 [ответить] [смотреть все]  
  • +/
    хм! а если надо одну и туже сеть например 192.168.0.0/24 пускать в инет по разному например 80 8080 и т.д. порты через одного прова а фтп почту и т.д. через другого как быть? и как интересно резолвится днс в данном случае если дефолтный маршрут только один у него и днс свой соответственно а второго прова свой днс который уже не резолвится если есть основной маршрут
     
  • 1.10, agg, 15:06, 28/05/2009 [ответить] [смотреть все]  
  • +/
    сразу после строки ip route add $NET_INET1 dev $IF_INET1 src $IP_INET1 table T1
    пишет:
    RTNETLINK answers: Invalid argument
    и
    Error: an inet adress is expected rather than "table"
     
  • 1.11, spoilt21, 00:35, 13/06/2009 [ответить] [смотреть все]  
  • +/
    >agg

    у меня такая же проблема

     
  • 1.12, spoilt21, 00:37, 13/06/2009 [ответить] [смотреть все]  
  • +/
    забыл уточнить, у меня 2 ипа от 1 провайдера и все одинаково кроме ip
     
  • 1.13, spoilt21, 19:44, 14/06/2009 [ответить] [смотреть все]  
  • +/
    Разобрался с проблемами, у вас есть ошибки:


    #все пакеты, которые попали в цепочку POSTROUTING таблицы nat обрабатываем по двум правилам:
    $IPT -t nat -A POTROUTING -m mark --mark 10 -j MASQUERADE # натим все пакеты которые имеют метку 10
    $IPT -t nat -A POTROUTING -m mark --mark 11 -j MASQUERADE # натим все пакеты которые имеют метку 11


    POTROUTING заменить на POsTROUTING


    далее в файле роутинг
    GW1="1.1.1.1" # гейт первого провайдера.
    GW2="2.2.2.1" # гейт второго провайдера.


    заменить GW на GW_INET


    кажется по мелочевке всё, это глупые ошибки, остальные ошибки можно увидеть тут сравнив ваш оригинал с моей рабочей версией:
    http://www.opennet.ru/openforum/vsluhforumID6/19056.html#0


     
     
  • 2.14, дурак, 13:54, 11/03/2012 [^] [ответить] [смотреть все]  
  • +/
    объясните дураку как сделать доступным сервер в локалке по 2 провайдерам я уже ... весь текст скрыт [показать]
     
     
  • 3.15, skyer, 14:47, 11/03/2012 [^] [ответить] [смотреть все]  
  • +/
    > объясните дураку как сделать доступным сервер в локалке по 2 провайдерам?

    Третий набор для сети сделай. Тут описано два, тебе надо 3. Сделай по аналогии для внутренней сети.

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

     
  • 1.16, zatorax, 12:26, 31/05/2012 [ответить] [смотреть все]  
  • +/
    хм навороченное решение, наверное есть какие то плюсы, я решил ту же проблему ... весь текст скрыт [показать]
     
  • 1.17, nikman, 23:26, 13/02/2014 [ответить] [смотреть все]  
  • +/
    Огромное спасибо автору, именно благодаря меткам я сделал невозможное возможным.
    Два провайдера + OpenVPN тунель

    Раздал так:

    Диапазон 192.168.4.2-200 клиенты имеют бесперебойный инет
    Диапазон 192.168.4.200-240 клиенты имеют бесперебойную сеть вывернутую через OpenVpn
    Еще раз спасибо ,просто супер :)

     

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





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