The OpenNET Project / Index page

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

Маршрутизация IP сервисов в DMZ через два провайдера
На форуме часто задается вопрос, по поводу маршрутизации сети, подключенной к двум провайдерам.
В частном случае проблема расширяется тем, что нужно осуществлять проброс соединений к сервисам, 
расположенным в локальной сети. Это делается с помощью DNAT, и при этом снова возникает 
проблема - по каналу какого провайдера отправлять ответ.  Проблема усугубляется тем, 
что обратное преобразование адресов выполняется уже после принятия 
решения о маршрутизации, 
т.е. примерно в районе цепочки POSTROUTING, но скрытно от пользователя.

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

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


В нижеописанном примере обеспечение доступности сервиса по двум каналам/провайдерам 
делалось для локального сервиса маршрутизатора. В связи с этим маркировка исходящих 
пакетов делается в цепочке OUTPUT таблицы mangle. Для проброса порта к  серверу в локальной сети
(в DMZ) проверку и восстановление маркера надо делать в цепочке PREROUTING. 
Таким образом, "обратный DNAT" будет происходить когда пакет уже будет идти по нужному маршруту.

Все не маркированные пакеты будут идти по маршруту по умолчанию. В моем случае это первый 
провайдер first и айпи интерфейса first_ip. Входящие пакеты/соединения с порта второго провайдера 
(destination <second_ip>) будут помечены маркером и к ним будет применен DNAT.
Все исходящие (обратные) пакеты  будут промаркированы значением маркера соединения 
в цепочке OUTPUT таблицы mangle.

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


   [root@test z]# iptables -t nat -nvL PREROUTING

   Chain PREROUTING (policy ACCEPT 144M packets, 9659M bytes)
    pkts bytes target     prot opt in     out     source               destination
       1    52 CONNMARK   tcp  --  *      *       0.0.0.0/0            <second_ip>      tcp    dpt:<port> CONNMARK set 0x1
       1    52 DNAT       tcp  --  *      *       0.0.0.0/0            <second_ip>      tcp    dpt:<port> to:<first_ip>:<port>


   [root@test z]# iptables -t mangle -nvL OUTPUT

   Chain OUTPUT (policy ACCEPT 6745M packets, 7048G bytes)
    pkts bytes target     prot opt in     out     source               destination
   65915 8600K CONNMARK   tcp  --  *      *       <first_ip>            0.0.0.0/0           tcp    spt:<port> CONNMARK restore


   [root@test z]# ip ru sh

   0:      from all lookup local
   1000:   from all lookup main
   3300:   from all fwmark 0x1 lookup <second>
   5000:   from <first_ip> lookup <first>
   5500:   from <second_ip> lookup <second>
   10000:  from all lookup default
   32766:  from all lookup main
   32767:  from all lookup default
 
02.07.2008 , Автор: Pavel V. Rochnyack
Ключи: route, iptables, linux, nat / Лицензия: CC-BY
Раздел:    Корень / Администратору / Сетевая подсистема, маршрутизация / Policy routing

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, dry (?), 12:51, 02/07/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    плавали, проблема интересная.
    но есть более правильный способ.
    если есть желание, пиши на мыло, пообщаемся.
     
     
  • 2.2, deepwalker (ok), 13:36, 02/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Можете прямо тут описать интересное решение, с интересом же почитаю Ваш вариант.
     
  • 2.3, PavelR (??), 06:02, 03/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Мыло в подписи под статьей,если сильно хочется. Но в принципе, можно и в комменты описание задвинуть, если оно уже вылизано и не требует обсуждения. В общем - интересно, рассказывай.


    PS: я уже и забыл когда отправлял текстовочку-то....

     
     
  • 3.4, dry (?), 12:07, 03/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Ок, вечерком постараюсь отписать.
    Есть рабочее решение, описание еще предстоит накидать.
    В кратце - идея в том, что на каждый канал провайдера создается своя подсеть DMZ (в идеале - vlan, но это не обязательно). Соответственно на обратном пути по подсети источника можно опознать пакет (с какого из внешних каналов он пришел) и применить к нему соответствующую таблицу роутинга.
     
     
  • 4.6, PavelR (??), 17:16, 03/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >Ок, вечерком постараюсь отписать.
    >Есть рабочее решение, описание еще предстоит накидать.
    >В кратце - идея в том, что на каждый канал провайдера создается
    >своя подсеть DMZ (в идеале - vlan, но это не обязательно).
    >Соответственно на обратном пути по подсети источника можно опознать пакет (с
    >какого из внешних каналов он пришел) и применить к нему соответствующую
    >таблицу роутинга.

    Понятно, в общем-то известное решение - позволяет обходиться без маркировки пакетов...

     

  • 1.5, borin (?), 12:17, 03/07/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Можно через xinetd

    например:

    service rdp
    {
    disable = no
    port = 3389
    socket_type = stream
    protocol = tcp
    user = root
    redirect = 192.168.2.8 3389
    type = UNLISTED
    wait = no
    }

    ну и разрешающее правило iptables
    iptables -A INPUT -p tcp --dport 3389 -m state --state NEW -m recent --name CITRIX --set
    iptables -A INPUT -p tcp --dport 3389 -m state --state NEW -m recent --name CITRIX --update --seconds 60 --hitcount 5 -j LOG
    iptables -A INPUT -p tcp --dport 3389 -m state --state NEW -m recent --name CITRIX --update --seconds 60 --hitcount 5 -j DROP
    iptables -A INPUT -p tcp --dport 3389 -m state --state NEW -j ACCEPT


    При условии, что маршрутизация настроена вот так http://gazette.linux.ru.net/rus/articles/lartc/x348.html

    Так и не получилось у меня мапнуть порт через маркировку пакетов через DNAT, чет видимо не до понимаю чутка, если можно выложить конкретный пример с правилами iptables как пробросить порт в локалку и чтоб он был доступен на 2-x интерфейсах буду признателен.

     
     
  • 2.7, PavelR (??), 17:17, 03/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >[оверквотинг удален]
    >iptables -A INPUT -p tcp --dport 3389 -m state --state NEW -j
    >ACCEPT
    >
    >
    >При условии, что маршрутизация настроена вот так http://gazette.linux.ru.net/rus/articles/lartc/x348.html
    >
    >Так и не получилось у меня мапнуть порт через маркировку пакетов через
    >DNAT, чет видимо не до понимаю чутка, если можно выложить конкретный
    >пример с правилами iptables как пробросить порт в локалку и чтоб
    >он был доступен на 2-x интерфейсах буду признателен.

    То что описано в "статье" - это и есть реальные примеры. Не забудьте добавить разрешающие правила в FORWARD и всё, всё остальное есть в статье.

     

  • 1.8, muhlik (??), 09:20, 08/07/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Есть один неприятный момент в решениях предложенных автором и dry. Если у меня есть сервис на который должны попадать люди из-вне значит я должен прописать на 2 ip от разных провайдеров одно имя, нет ну конечно я могу и разные имена прописать, но для пользаков это не удобно ИМХО. Так вот если при этом один пров падает то половина народа попасть ко мне не смогут :-(. В общем как мне кажется нет тут нормальных решений кроме как AS получать :-(. А конторым типа моей, которой не более 10 ИП белых надо это не очень по карману :-(.
     
     
  • 2.9, PavelR (??), 07:07, 09/07/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >Есть один неприятный момент в решениях предложенных автором и dry. Если у
    >меня есть сервис на который должны попадать люди из-вне значит я
    >должен прописать на 2 ip от разных провайдеров одно имя, нет
    >ну конечно я могу и разные имена прописать, но для пользаков
    >это не удобно ИМХО. Так вот если при этом один пров
    >падает то половина народа попасть ко мне не смогут :-(. В
    >общем как мне кажется нет тут нормальных решений кроме как AS
    >получать :-(. А конторым типа моей, которой не более 10 ИП
    >белых надо это не очень по карману :-(.

    Это вообще не относится к обсуждаемой теме. Обсуждаемая тема называется _маршрутизация_, и решение может иметь кучу применений. Так например тот же самый openvpn, smtp умеют балансироваться на два адреса штатно, и "никаких неприятных моментов".


     

  • 1.10, Артем (??), 13:04, 10/05/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Статья в точности описывает мою проблему, да вот только пример непонятный и неполный.
    В нем смешался доступ к локальному сервису и проброс DNAT, получился неслыханный бред.
    Пакет, приходящий со второго инета, почему то пробрасывается на первый инет, причем вовнутрь ! Ладно, фиг с ним, далее еще лучше, метка восстанавливается в цепочке OUTPUT ! Как "оно" там окажется ??? Значит это относится к локальному сервису ? А где тогда восстанавливается метка для пробрасываемого порта ?
    Еще интересна цепочка маршрутизации, таблица main присутствует в ней дважды. Разъясните, пожалуйста, сей хитрый трюк и зачем он ? :)
     
     
  • 2.12, PavelR (??), 09:53, 23/07/2009 [^] [^^] [^^^] [ответить]  
  • +/
    [root@test z]# ip ru sh
       0:      from all lookup local
       1000:   from all lookup main
       3300:   from all fwmark 0x1 lookup <second>
       5000:   from <first_ip> lookup <first>
       5500:   from <second_ip> lookup <second>
       10000:  from all lookup default
       32766:  from all lookup main
       32767:  from all lookup default

    Там еще два раза default присутствует :)
    В общем случае, достаточно конечно же такого варианта:

    [root@test z]# ip ru sh
       0:      from all lookup local
       1000:   from all lookup main
       3300:   from all fwmark 0x1 lookup <second>
       5000:   from <first_ip> lookup <first>
       5500:   from <second_ip> lookup <second>
       32767:  from all lookup default

    Но таблица правил по умолчанию выглядит так:

    0:      from all lookup local
    32766:  from all lookup main
    32767:  from all lookup default


    и я удалять из неё правило 32766 не рискнул.

    -----------

    Правило   "1000:   from all lookup main" требуется чтобы напрямую присоединенные к маршрутизатору подсети маршрутизировались через локальные линки, а не через проход через провайдерские шлюзы.  Более подробно можно почитать тут: http://www.opennet.dev/tips/info/2009.shtml

     

  • 1.11, SVLD (?), 02:54, 21/06/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    mangle/OUTPUT нужна для отработки пакетов роутер-инет, для ДНАТов все танцы чисто в цепочке mangle/PREROUTING:
    1. -i ifINET1 -m state --state NEW -j CONNMARK --set-mark 0x1
    -i ifINET2 -m state --state NEW -j CONNMARK --set-mark -0x2
    2. после этих правил надо делать -j CONNMARK --restore-mark, НО! при условии что пакет из локалки в инет! я для этого заводил отдельную цепочку в mangle, в которую заворачивал все пакеты из локалок, а в самой цепочке поставил три правила:
    -d 10.0.0.0/8 -j RETURN
    -d 192.168.0.0/16 -j RETURN
    -j CONNMARK --restore-mark
     
     
  • 2.13, Виктор (??), 11:31, 30/07/2009 [^] [^^] [^^^] [ответить]  
  • –1 +/
    А как во фрибсд это сделать?
     

  • 1.14, анон (?), 22:36, 08/12/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    "Для проброса порта к  серверу в локальной сети
    (в DMZ) проверку и восстановление маркера надо делать в цепочке PREROUTING.
    Таким образом, "обратный DNAT" будет происходить когда пакет уже будет идти по нужному маршруту."

    А разве не в POSTROUTING?

     

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




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру