Ubuntu, KVM и proxy_arp — как обмануть злого провайдера

    Одна фирма расположила на колокейшне серверочек для внутренних нужд и сразу купила /30 адреса для соих потребностей. Сконфигурено это было как алиасы (eth0:0, eth0:1 и т.п.). Все работало великолепно, пока по прошествии некоторого времени появилась здравая идея разнести разные сервисы на разные виртуальные машины. Поскольку в качестве хоста использовался Ubuntu Server, то выбор KVM в качестве виртуализатора произошел сам собой. И здесь, и в остальном нете уже немало умных слов было написано по установку и настройку KVM и сетевого окружения, не буду на этом останавливаться, расскажу лишь про маленькие детские грабельки, удобно подложенные со стороны провайдера.
    Прежде всего надо отметить, что все происходило на живой активно используемой технологической машине, где перерывы в предоставлении сервиса были нежелательны, потому все переконфигурации производились по ночам с соответствующим состоянием мозгов;)
    Итак, оставив eth0 нетронутым (дабы не прерывались важные производственные сервисы), гасим все алиасы, создаем бридж br0, втыкаем в него eth0 и запускаем виртуальные машины, точно так же, как во всех KVM-букварях написано, втыкая tapX в тот же бридж.
    Вуаля — айпишники видны, машины друг друга пингают, время открывать шампань, когда обнаруживается, что из инета доступен только хост. Опуская тонкости поисков проблемы, сразу перехожу к сути — у провайдера, где стоял на колокейшне сервер, свич сконфигурирован с port security, т.е. выпускал наружу только прибитый гвоздями при установке MAC. Пропускать маки виртуальных машин провайдер отказался, за что я его не виню, и это его право устанавливать внутреннюю техническую политику. В ответ на растеряный вопрос: «А как же нам быть?» был дан ответ опять-таки из KVM-букваря: оставляйте на интерфейсе алиасы, на виртуалках указать десятую сетку и дальше «iptables -j DNAT bla-bla-bla»
    Погрустив слегка по поводу некоторой корявости подобного решения и вдумчиво покурив гугль, был найден альтернативный вариант с ключевым словом proxy_arp.
    Перво-наперво делаем apt-get install uml-utilities
    В /etc/network/interfaces прописываем:
    auto eth0
    iface eth0 inet static
    address 1.2.3.1
    netmask 255.255.255.0
    network 1.2.3.0
    broadcast 1.2.3.255
    gateway 1.2.3.254
    post-up sysctl -w net.ipv4.ip_forward=1
    post-up sysctl -w net.ipv4.conf.eth0.proxy_arp=1
    pre-down sysctl -w net.ipv4.ip_forward=0

    auto qtap1
    iface qtap1 inet manual
    tunctl_user root
    uml_proxy_arp 1.2.3.2
    uml_proxy_ether eth0
    up ip link set qtap1 up
    down ip link set qtap1 down

    auto qtap2
    iface qtap2 inet manual
    tunctl_user root
    uml_proxy_arp 1.2.3.3
    uml_proxy_ether eth0
    up ip link set qtap2 up
    down ip link set qtap2 down

    Стартуем виртуальные машины:

    kvm -m 512 -hda image.img -net nic,macaddr=00:01:02:03:04:05 -net tap,ifname=qtap1,macaddr=00:01:02:03:04:05,script=no -daemonize -vnc :1 и т.д.

    Далее в виртуальных машинах в качестве gw прописываем адрес хоста 1.2.3.1 и получаем работающую гроздь виртуалок, заныкавшуюся от провайдера за МАКом хост-машины.

    Для тех, кто пока не относит себя к network guru, пару слов о proxy_arp и отличии его от bridge.

    По-умолчанию, обычный мост просто передает пакеты с одного интерфейса на другой в неизменном виде. Он рассматривает только аппаратный адрес пакета, чтобы определить — в каком направлении нужно передать пакет. Это означает, что Linux может переправлять любой вид трафика, даже тот, который ему не известен, если пакеты имеют аппаратный адрес.

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

    Еще одно преимущество псевдо-моста состоит в том, что он не может передавать пакеты протоколов, которые «не понимает» — что предохраняет сеть от заполнения всяким «мусором».

    В данной схеме когда провайдерский свич желает установить связь с виртуальной машиной, находящейся позади хоста, то он отсылает хосту пакет ARP-запроса, который, в переводе на человеческий язык, может звучать примерно так: «У кого установлен адрес 1.2.3.2? Сообщите по адресу 1.2.3.254». В ответ на запрос, 1.2.3.1 ответит коротким пакетом «Я здесь! Мой аппаратный адрес xx:xx:xx:xx:xx:xx».

    Когда 1.2.3.254 получит ответ, он запомнит аппаратный адрес 1.2.3.2 и будет хранить его в кэше некоторое время.

    При настройке proxy_arp мы указали интерфейсу eth0 на необходимость отвечать на ARP-запросы. Это вынудит роутер посылать пакеты мосту, который затем обработает их и передаст на соответствующую виртуальную машину.

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

    При подготовке статьи были использованы материалы «Linux Advanced Routing & Traffic Control HOWTO».
    Поделиться публикацией

    Похожие публикации

    Комментарии 33

    • НЛО прилетело и опубликовало эту надпись здесь
        0
        ай спасибо!

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

        как только появится необходимость тут же достану из меморизов ваш «рецепт» :)
          0
          Я мало в чём понимаю, но что мешает просто назначить два IP на один интерфейс (и MAC соответсвенно)? И будет на оба адреса выдваться один ARP-ответ.
            –17
            На один интерфейс два ip нельзя.
              +2
              Это и называется алиасы, так и было настроено до виртуализации.
              0
              Мне совершенна не понятна логика провайдера, может кто разъяснить? Клиент берет 30 ip, а можно светить только одним маком.
                +1
                не 30, а /30, т.е. 4 адреса :)
                  0
                  ам, ссори. Невнимательность. Но все же, в чем смысл ограничения?
                    +1
                    Было сказано, что это «для безопасности, во избежание...» и прочая. Ну, провайдера можно понять, иногда на колокейшн такие клоуны приходят…
                    В любом случае, port security это стандартная фишка всяких каталистов.
                      +3
                      Смысл ограничения — избежание SYN/FIN flood DDoS атак от сервера пользователя Датацентра. Суть атак в том что из сервера где нет привязки ip к mac-адресу можно генерировать пакеты с фейковых ip.
                        –2
                        Кстати, вот интересный момент — а чем с точки зрения SYN flood отличаются ситуация портсекурити плюс проксиарп от ситуации, когда нету ни того, ни другого? Или это из разряда «на каждую хитрую жопу...»?
                      +5
                      вообще-то, в /30 всего два рабочих адреса, два других — это идентификатор зоны и броадкастовый адрес.
                        0
                        Я думаю у автора имеет место быть опечатка/непонятка по поводу /30. Иначе разговор про алиасы и про виртуальные машины во множественном числе не имел бы смысла.
                        Много — это как минимум больше двух :)
                    0
                    Такую задачу, можно решить используя статические маршруты iproute2. У вас проблема была не в том, что пинговался один хост, а в том, что к второму ip(нарабочему) пакеты прилетали, но не могли улететь обратно. Провайдер тут ни причем.
                      0
                      маршрутизация тут не катит, фактически — это бридж.
                      сами столкнулись с отказом хостера (агава) маршрутизировать подсети меньше /24, а башлять им тучу бабок за ненужные адреса, за их двухминутную работу и ежегодно за аренду AS/PI и bgp-соседа.
                        0
                        Если ip жили на алиасах и нормально пингались до того как автор настроил, КVM который начал выплевывать свои mac'и. То в чем проблема было послушать провайдера и использовать соурс раутинг по IP-интерфейсах? Бриджинг для виртуализации — не секюрно.
                        Разве в KVM нельзя задать просто ip для guest системы? Cогласно KVM документации ip можно получить даже по DHCP.
                        Наверно проблема в том, что в мануале для Ubunt предложено только вариант с бриджом.
                          0
                          В моем решении бриджа и рядом не валялось. Тут на трейсрауте ты честно видишь еще один хоп — хостовую тачку. А как раз iptablesы порождают кучу возможностей наделать всяких косяков.
                          Впрочем, они же дают любителям секса возможность потрахаться вдоволь ;) — так что тут смотря кто чего ищет :)

                          А бриджинг — да, согласен, не наш метод.
                            0
                            У меня похожая задача была, решил DNATом, убил 1.5 месяца чтобы все работало как мне надо…
                            +1
                            если ip пинговались, будучи алиасами одного интерфейса, то нет тут никакой маршрутизации и не будет, пока хостера не убедите настроить маршрутизацию определенной подсети через уже работающий на интерфейсе.
                              0
                              на Воле (dc.volia.com) убедить не удалось. :(
                              сапорт отправил в отдел продаж, в продажах сказали что не могут :/
                              обидно, ведь в остальном они меня полностью устраивают
                        0
                        тема! будим знать как «Творить чудеса»!!! примного благодарен!
                          0
                          Спасибо за полезную информацию :-)
                            0
                            Спасибо. Узнал новый для себя вариант решения.
                              0
                              А маки на виртуалках поменять нет?
                              И, кстати, почему именно kvm?
                                0
                                На что маки менять, на водку? «Скажи наркотикам — иногда»? ;)
                                Есть 3 популярных варианта бесплатной виртуализации — XEN, KVM и OpenVZ. Последняя — это просто chroot на том же ядре, а от первого убунтоводы сейчас отказались в пользу второго. Так что «при всем богатстве выбора другой альтернативы нет»(с) :)
                                  0
                                  Может быть прочитать man по ifconfig и прочитать там как поменять MAC-адрес?
                                  И чем так плох OVZ?
                                    0
                                    1. Что даст замена мак-адреса?
                                    2. Мне не нужен chroot
                                      0
                                      > у провайдера, где стоял на колокейшне сервер, свич сконфигурирован с port security, т.е.
                                      > выпускал наружу только прибитый гвоздями при установке MAC
                                      > «Скажи наркотикам — иногда»? ;)
                                        0
                                        Согласен, я бы именно так и сделал, а так получился огород!
                                0
                                а какие мак-адреса ты прописываешь для виртуалок? просто с потолка или это адрес интерфейса хоста?
                                  0
                                  Ответил ниже

                                    0
                                    я настроил себе сеть точно также и переодически вылезает проблема. после очередной перезагрузки виртуалки в ней теряется сеть, при этом на хосте, при запуске виртаулки, не поднимается ее qtap интерфейс. вручную поднимается, но проблему не решает. тоже самое после этого проявляется на всех остальных машинах, то есть сеть остается до первой перезагрузки. после чего приходится ребутить хост. в чем может быть проблема? может это быть из-за того, что я не прописывал маки виртуалкам?

                                    и еще хотел спросить зачем нужна строчка down ip link set qtap1 down, когда ее указываю, то интерфейс qtap не поднимается, без нее все работает. может моя проблема быть как-то связана с этой строкой?
                                  0
                                  Нет, хостовый мак нужен только снаружи. Какие будут маки внутри — совершенно монопенисуально

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

                                  Самое читаемое