Пользователь
–2,5
рейтинг
12 января 2010 в 15:04

Администрирование → По просьбам трудящихся: Dual ISP на маршрутизаторах cisco без BGP

Типичная задача, которая тем не менее, продолжает вызывать массу вопросов.

Попробую вкратце описать суть технологии и подводные камни.

Итак, пусть у нас есть один пограничный маршрутизатор cisco с одним внутренним портом (g0/0) и двумя внешними (f0/0, f0/1). Есть подключение к двум провайдерам, каждый из которых выдал свой пул адресов Pool(ISP1) и Pool(ISP2) (это некоторые сети, принадлежащие конкретному провайдеру). Пусть для простоты адреса интерфейсов f0/0 и f0/1 из этих же пулов. И адреса шлюзов из этих же пулов (Gate(ISP1) и Gate(ISP2) соответственно).
Так как у нас нет возможности поднять BGP, значит мы должны на каждого из провайдеров прописать маршрут по умолчанию. И вот тут возникает первый вопрос: какую задачу мы хотим решить? Резервирование или одновременная работа с двумя провайдерами?


Резервирование.

В этой топологии одновременно работает только один провайдер. То есть мы должны организовать проверку провайдера ISP1 и в случае если он живой – ходить через него, а если «мертв», то переключаться на запасного провайдера ISP2. Здесь есть подводный камень: NAT. Мы можем написать несколько правил трансляции, но надо как то указать, что при выходе через ISP1 мы используем Pool(ISP1), а при выходе через ISP2 – Pool(ISP2), иначе маршрутизатор всегда будет использовать трансляцию, которая первой написана в конфигурации. Понятно, что если идти через ISP2, а адреса источника будут из Pool(ISP1), то в лучшем случае мы получим несимметричную маршрутизацию, в худшем пакеты вообще никуда не дойдут, например потому, что провайдеры выполняют предписание использовать фильтрацию по RFC2827, что означает не принимать пакеты с адресами источника не из своей сети.
Итак, у нас 2 подзадачи: проверка провайдера (маршрута) на «живость» и трансляция адресов с учётом выходного интерфейса.

Проверка на «живость».

Маршрутизаторы cisco обладают замечательной технологией, называемой SLA. При помощи неё можно не только проверять пингом некий адрес, но также проверять живость определенных сервисов (ftp-connect, tcp-connect) или параметра канала связи (icmp-jitter, udp-jitter). Здесь рассмотрим самый простой и распространенный способ – пинг определенного хоста. Для простоты будем пинговать адрес шлюза провайдера Gate(ISPX). Если надо пинговать другой адрес, то необходимо явно прописать маршрут до этого адреса через конкретного провайдера, которого мы проверяем.

! Задаем параметры «пинговалики»
ip sla {#}
  icmp-echo {ip} [source-interface {int}]
!
! Запускаем пинговалку
ip sla schedule {#} start now life forever
!
! Настраиваем «переключатель» (track), от которого будет зависеть маршрут
track {#} ip sla {#} reachability
!
! Настраиваем маршрут по умолчанию с трекингом
ip route 0.0.0.0 0.0.0.0 {next-hop} track {#}


Примечание: в старых IOS команда привязки track к sla выгдялела так

track {#} rtr {sla#} reachability

Если хост пингуется, то track будет в состоянии UP и маршрут будет в таблице маршрутизации. А
если пинг пропадет, то через настроенный промежуток времени (по умолчанию 3*10 секунд) track
поменяет состояние на DOWN и маршрут будет удален до тех пор, пока track вновь не изменит
состояние.

Пример:
ip sla 1
  icmp-echo Gate(ISP1)
ip sla schedule 1 start now life forever
track 11 ip sla 1 reachability
ip route 0.0.0.0 0.0.0.0 Gate(ISP1) track 11

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

Задание правил трансляции адресов с учетом исходящего интерфейса.


Тут на самом деле тоже 2 задачи: динамическая трансляция и статическая трансляция адресов. Первая нам нужна для выхода наружу, а вторая – для анонса сервисов. И в том и в другом случае нам понадобится конструкция, называющаяся route-map (создать надо будет по route-map на каждого провайдера)

! Создаем route-map
route-map ISPX permit {#}
  ! Указываем критерий попадания в этот абзац route-map  
  match interface {исходящий интерфейс}


Тут есть тонкость: при указании слова interface в подсказке пишется

  interface         Match first hop interface of route

Т.е. вообще говоря, не понятно, что это за параметр. Плюс в зависимости от того, что написано на самом интерфейсе, этот критерий может означать как входящий интерфейс, так и исходящий! А зависит это от того, что написано в команде ip nat на интерфейсе:

ip nat inside – критерий будет означать входящий интерфейс
ip nat outside – критерий будет означать исходящий интерфейс

Далее, нам понадобится пул адресов от каждого провайдера

  ip nat pool PoolX {start-ip(ISPX)}  {end-ip(ISPX)}

И можно уже писать правила NAT на каждого провайдера

  ip nat inside source route-map ISPX poolX overload

overload – ключевое слово, означающее использовать PAT (Port Address Translation, трансляцию с учётом порта источника)
Если к надо добавить статические трансляции, то делаем почти так же (пусть серверу мы зарезервировали адрес Srv(ISPX) от каждого провайдера, а локальный адрес у сервера – Srv(LAN).)

  ip nat inside source static Srv(ISPX) Srv(LAN) route-map ISPX


____________
UPD ВНИМАНИЕ: ВВЕРХУ ОПЕЧАТКА!
Должно быть
  ip nat inside source static Srv(LAN) Srv(ISPX) route-map ISPX 

____________

При этом конечно надо озаботиться, чтобы оба адреса (Srv(ISP1) и Srv(ISP2)) на ДНС серверах были прописаны и указывали на одно и то же имя.

Итого, у нас получилось:

! 
! интерфейсы
int g0/0
  ip address [LAN]
  ip nat inside
!
int f0/0
  ip address Address(ISP1)
  ip nat outside
!
int f0/1
  ip address Address(ISP2)
  ip nat outside
!
! Маршрутизация
ip sla 1
  icmp-echo Gate(ISP1)
ip sla schedule 1 start now life forever
track 11 ip sla 1 reachability
ip route 0.0.0.0 0.0.0.0 Gate(ISP1) track 11
ip route 0.0.0.0 0.0.0.0 Gate(ISP2) 50
!
! Пулы для NAT
ip nat pool POOL1 {start-ip(ISP1)}  {end-ip(ISP1)}
ip nat pool POOL2 {start-ip(ISP2)}  {end-ip(ISP2)}
!
! route-map для NATa
route-map ISP1 permit 10
  match interface f0/0
!
route-map ISP2 permit 10
  match interface f0/1
!
! Правила NATa
ip nat inside source route-map ISP1 POOL1 overload
ip nat inside source route-map ISP2 POOL2 overload
ip nat inside source static Srv(LAN) Srv(ISP1) route-map ISP1
ip nat inside source static Srv(LAN) Srv(ISP2) route-map ISP2


Одновременное использование двух провайдеров

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

Интересна ли эта тема? Какие мысли и проблемы есть?
Пишите: скомпилирую со своими мыслями и выложу, если захотите.
Сергей Фёдоров @Fedia
карма
232,0
рейтинг –2,5
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Администрирование

Комментарии (35)

  • 0
    Пинговать шлюз ненадо, часто бывает отпадает внешка но гейт доступен
    • +2
      Я не ставил себе задачу описать ВСЕ возможности. Да, часто бывает так, что надо пинговать дальше. Для этого в статье есть ремарка, что ежли надо пинговать что то другое, то необходимо явно туда прописать маршрут.

      Я попробовал взять самый простой случай и по возможности подробно его описать
    • 0
      ОФФ тебе: ценник в твоей визитке актуальный?
      Похоже тоже придётся переквалифицироваться в «поденщики» — надо учиться.
  • 0
    Да, очень интересно и актуально именно для случая балансировки между провайдерами.
  • 0
    Так что и куда прописать для не гейта провайдеровского?
    А вариант для лоадбалансинга тоже интересен
    • 0
      В одной сети у моего клиента такая топология: рутер, смотрит езернетом на «железяку» провайдера, которая дальше обеспечивает радиоканал. До «железяки» 30 см езернета в серверной, а дальше — полкилометра воздуха и ненадежное оборудование.

      Но при этом моим шлюзом для рутера является «железяка». Соответсвенно, чтобы исключить «стремный» кусок я пингую хост за радиоканалом. Пусть это некий HOST1. Тогда понятно, что этот хост не из присоединенной сети и поэтому может быть доступен как через одного, так и через второго прова.

      Но проверяем то мы линк именно первого прова, поэтому пишу так

        ip route HOST1 255.255.255.255 Gate(ISP1)
      

      Чтобы заведомо ходить на HOST1 через первого прова.

      По поводу одновременного использования: кое что требует проверки. Пока не оттестирую на новом IOS писать не буду. Но сторонний опыт может ускорить этот процесс.
      • 0
        Извините, пост ниже был к Вам вопрос…
  • 0
    Я правильно понял, что если я в sla напишу, ну, например, icmp-echo 4.2.2.2, чтобы быть уверенным, что у моего основного провайдера не отвалилась внешка, то я должен написать ещё ip route 4.2.2.2 255.255.255.255 Gate(ISP1)?
    И ещё: если не писать sla и track для второго канала, то оно всё равно восстановится, когда поднимется первый?
    • 0
      Тоже любите этот ДНС :) Самый короткий адрес + легко запоминается :)

      Да, если вы хотите проверить первого провайдера то и пакет надо запускать через интерфейс первого.

      Не совсем понял, что поднимется. Там так — пинг пытается идти постоянно. Если доходит, то трек в апе, если нет — в дауне. Если трек в дауне маршрут из таблицы удаляется. КАк только трек поднимается — маршрут снова добавляется. Я ответил на вопрос или не попал? :)
      • 0
        да, именно это я и спрашивал.
        спасибо!
  • 0
    Если в первом случае все понятно и однозначно, то в случае с одновременным использованием двух провайдеров возникают проблемы.
    Абсолютно никаких проблем — Policy Based Routing (PBR) нам всем в помощь :)
    • 0
      Если бы все было так просто — не было бы никаких проблем :)

      Я тут начал описывать эту задачу: у себя на сайте положил чуток дописанный файл (здесь этой части нет пока — сегодня буду полностью дописывать и тестировать). Там проблема возникает, когда циске все равно, куда отправить ответный пакет от сервера.

      Если интересно:
      www.anticisco.ru
      Закладка «Почитать», 3 пункт.
      • 0
        Прочитал.
        Есть у меня Exchange сервер. Есть 2 MX записи привязанные соответственно к ISP1 (pri) и ISP2 (sec).
        Задача: ответ на пакет пришедший на ISP2, отправить через ISP2.
        Решение: На сервере Exchange накручиваем еще один адрес. А на рутере прописываем PBR согласно которого все пакеты от этого адреса отправляем только в ISP2.
        • 0
          Да, так сделать легко. И это полностью укладывается в пример, где на внутреннем интерфейсе живет route-map STRELKA
          Там как раз в 20 абзац надо было бы прописать в качестве интересного трафик от конкретного адреса.

          Но есть 2 проблемы:
          1. Если сервер имеет адреса из одной подсети, он часто получив запрос на вторичный адрес, отвечает с первичного :(
          2. Если на сервере 2 адреса из разных подсетей, то дефолтный маршрут все равно только один для корректной работы.

          Это можно обойти, но не красиво.
          • 0
            Вопрос стоял о пакете пришедшем снаружи. В моем примере откуда пришел туда и ушел. Можно, конечно, подумать о более изящном решении :)
          • 0
            Был у меня такой случай. Повесили SMTP-сервис на Exchange на два порта — 25 и 26. 26-й натился на второго провайдера. Все работало, клиент не жаловался.
            • 0
              Да, так можно сделать, если только один порт надо транслировать.
              В принципе похожий подход можно применить и для разных адресов: статически НАТить порт, а исходящие (инициированные сервером) соединения РАТить в этот же адрес, но динамически и в то, что сейчас живо.

              ЗЫ ВОпрос Вам: когда Exch жил на 2 портах одновременно, как осуществлялась балансировка между этими портами?
              • 0
                К сожалению, ничего не могу сказать — конфигурацией Exchange занимался специалист по серверным приложениям Windows. А я отвечал только за конфигурацию Cisco.
  • 0
    Извините, может я чего-то недопонял, но:
    зачем здесь танцы с SLA? Почему нельзя сделать 2 маршрута с разными AD? На Master — меньше, на Backup — больше. Зачем тут SLA?
    По-моему, SLA нужно использовать исключительно в случае если падает не гейт, а что-то выше — тобишь маршрут остается, но его как-то нужно убить.
    Может я конечно что-то не дочитал в Вашем посте, но лучше уж спрошу :)

    Как вариант, можно еще BFD заюзать, но не знаю, умеет ли такое циска, а тем более, есть ли поддержка BFD на другом конце.
    • 0
      Можно, конечно. Но что вы будете делать, если у вас маршрутизатор воткнут в свитч (АДСЛ-модем, ещё куда) езернетом и сам езернет до свитча (модема) живее всех живых, а вот дальше — проблема с каналом?

      Мне казалось, я довольно подробно описал, зачем SLA :) Ошибся значит.

      BFD = Backup Forward Delay?
      • 0
        Ок, теперь понятно. Мое вИдение именно этой задачи ограничивалось прямым п2п линком в гейт, просто не подумал :)
        Спасибо за ответ.

        NB. BFD == Bidirectional Forwarding Detection
  • 0
    Собственно про одновременное использование двух провайдеров и ожидал почитать в топике о_О
    • 0
      Для вас — вторая часть. Следующий топик в этом блоге. Просто писал в разное время: решил общее начало опубликовать раньше, а более сложную часть — после проверки.
  • 0
    Какова будет минимальная стоимость железки, которая это умеет? И что это за железка? (№)
    • 0
      Практически любой рутер (начиная с 8хх серии думаю, но надо уточнить). 18хх серия уже точно может и далее — все: 28хх,38хх,72хх (и новые 19хх,29хх,39хх)
    • 0
      у нас пикс 515 в таком режиме работает
      • 0
        В таком — это в режиме резервирования? В таком режиме любой пикс/аса даже удобнее — не надо танцев с бубнами (роут-мапами). Однако, как толко встанет задача одновременного использования каналов — увы, ни пикс, ни аса не справится :( (см топик про АСА и чего она не умеет)
        • 0
          а нам не надо одновременного использования, только резервирование на случай падения основного канала.
          да и одновременное использование нескольких каналов совсем не задача асы/пикса на мой взгляд.
          • 0
            Да это понятно. Но ИМХО это надо знать. Я много раз разгребал чужие грабли — всё в итоге выливали на меня, а не на продавца :)

            Это и сподвигло меня на написание вступительной части про АСА.
  • 0
    Тут есть проблема в чем. При переключении на запасного провайдера надо почистить таблицу трансляций. Иначе пользовательские сессии подвиснут.
    Делается примерно так

    event manager applet ISP_SWITCHED_20
    event track 30 state any
    action 1.0 cli command «enable»
    action 2.0 cli command «clear ip nat trans forced»

    Еще. Я при icmp-echo обязательно пишу source
    Вот так
    p sla 30
    icmp-echo x.x.x.33 source-interface GigabitEthernet0/1

    А то кто его знает с какого адреса будет пинговаться дальний адрес.

    Еще. В правилах трансляции я пишу вот так (без пула):
    ip nat inside source route-map via-gi01 interface GigabitEthernet0/1 overload
    Чаще все же провайдер не дает пула адресов.

    В route-map часто пишу вот так
    route-map via-gi01 permit 10
    match ip address nat_enabled
    match interface GigabitEthernet0/1

    Чтобы транслировать только адреса которые должны иметь доступ к внешней сети.

    • 0
      Большое спасибо за дополнения!

      Действительно, часто бывает так, что сессии «подвисают», т.е. в кэше сессий сохраняются старые записи. На старых ИОСах боролся с этим таймаутами. Чаще всего этим грешат статический НАТ трансляции. Для PAT (по портам) трансляций больших проблем на новых ИОСах не замечал. Обычно до падения трека проходит существенное время (30 секунд, например), и большая часть сессий падает и сессии пытаются переустановиться сами. С UDP засада, но только потоковым.

      Но в любом случае, с ЕЕМ будет работать надежно и прогнозируемо. Тоже его советую пользовать для чистки сессий при падении канала. И ещё тогда таймаут на SLA ставить поменьше.

      А вот про source-int не согласен: ИМХО правильнее указать именно маршрут явный на пингуемый хост с маской /32 (его никто не перебьет) через необходимый интерфейс. AFAIK source-int задает, какой адрес источника ставить пакету, а не с какого интерфейса его посылать.
      • 0
        source-int — это для того, чтобы провайдер не зарезал исходящий icmp с адресом не из его пула. Как у тебя в статье написано. по RFC какому-то.
        А статику я в своем ответе даже не упомянул ;) Она остается
        • 0
          Стоп. Адресом источника циска подставит по умолчанию адрес того интерфейса, который ближе к сети назначения. ПОэтому статики достаточно.

          source-int нужен когда наоборот, надо с какого-нить лупбека посылать.
    • 0
      Пулы провайдеры дают часто. На моей (московской) практике. Транслировать в интерфейс всегда просто, поэтому в примере привёл пул :)

      А route-map с двумя критериями (интерфейс и список доступа) я рассмотрел в следующей части.
  • 0
    А почему «в случае с одновременным использованием двух провайдеров возникают проблемы». Я сейчас на sla делаю почти аналогичную задачу: есть 2 серых сети и 2 шлюза. Одна сеть должна идти через первый, вторая через второй. В случае падения одного из них — обе через один. Настраиваем sla, tracking, а в route-map-ах пишет 2 set ip next-hop verify-availability с треком и разными AD. Для каждой сети свой роут мап и зеркальные AD и next-hop.
    п.с.: оба сервера в одном vlan, на удаленном коммутаторе.

    п.с.: set ip next-hop verify-availability with optional arguments to support object tracking using Internet Control Message Protocol (ICMP) ping or an HTTP GET request to verify if a remote device is reachable.
    :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.