Создание point-to-multipoint тоннелей на базе инкапсуляции GRE в Linux 2.6

    В ОС Linux встроена поддержка двух типов тоннелей: ipip и gre. В том виде, в котором тоннели традиционно используются в системе, без разницы, какой из них использовать: они оба дают в точности одинаковые накладные расходы к пакетам, посылаемым в тоннель IPv4-in-IPv4 (специально проверял), одинаково защищаются средствами IPsec и занимают одинаковое процессорное время для обработки. Однако, это разные типы тоннелей, и возможности gre значительно более широкие.
    К сожалению, нигде в интернете не описывается очень удобная и замечательная особенность gre-тоннелей, и большинство (если не все) администраторов Linux не знают о такой возможности, как mGRE-тоннели. К счастью, мы намереваемся восполнить этот недостаток :-)



    Итак, имеем три машины, все три имеют запущенный Linux версии 2.6 (я не уверен, возможно, и 2.4 тоже поддерживает). Также нам потребуется пакет iproute2 — это стандарт для современных Linux-систем (кстати, давно уже пора забыть про морально устаревшие утилиты ifconfig, route и прочие). Внешние ip-адреса систем: 1.1.1.1, 2.2.2.2 и 3.3.3.3; между ними есть маршрутизация.

    Обойдёмся пока без шифрования и аутеникации пакетов — это всё несложно к нашему примеру добавить, «просто» настроив IPsec между нашими хостами в транспортном режиме. Это тема за рамками темы ;)

    1. Создаём GRE-тоннель:
    (на всех трёх)
    ip tunnel add mgre0 mode gre key 0xfffffffe ttl 255

    Заметьте, мы не указали здесь адрес пира. Это значит, что в принципе он может быть расположен по любому адресу. key в данном случае идентифицирует конкретную mGRE-сеть — это 32-битное число, одинаковое для всех нод.

    2. Назначаем ему адрес:
    (на 1.1.1.1)
    ip addr add 10.0.0.1/24 dev mgre0

    (на 2.2.2.2)
    ip addr add 10.0.0.2/24 dev mgre0

    (на 3.3.3.3)
    ip addr add 10.0.0.3/24 dev mgre0


    Для интерфейсов Ethernet этого было бы достаточно. В Ethernet есть Adress Resolution Protocol (ARP), который позволяет системам самостоятельно найти MAC-адрес, зная IP-адрес хоста назначения. Ethernet является средой Broadcast Multiple Access, и протокол ARP заключается в создании запроса ко всем станциям сети (по MAC-адресу FF:FF:FF:FF:FF:FF): «Эй, кто из вас имеет IP-адрес x.x.x.x?». Если станция с таким IP-адресом имеется, она уже в приватном порядке сообщает, что «x.x.x.x расположен по адресу yy:yy:yy:yy:yy:yy».

    В нашей сети (Internet) нет такого средства, как ARP, а роль адресов «второго уровня», которые в случае Ethernet — MAC-адреса, здесь исполняют… внешние IP-адреса систем. Мы работаем со средой Non-Broadcast Multiple Access (NBMA), мы не можем крикнуть на весь интернет, как сделал бы ARP: «Эй, кто в GRE-сети 0xfffffffe имеет адрес 10.0.0.2?».

    Для разрешения этой проблемы адресов предназначен протокол Next Hop Resolution Protocol (NHRP, аналог ARP для NBMA-сред), но мы на на первый раз сделаем работу за него — заодно разберёмся, как вообще сеть в Linux работает :)

    3. Итак, сообщим вручную каждой станции, где искать соседей. Для этого выполним следующие команды:
    (на 1.1.1.1)
    ip neigh add 10.0.0.2 lladdr 2.2.2.2 dev mgre0
    ip neigh add 10.0.0.3 lladdr 3.3.3.3 dev mgre0

    (на 2.2.2.2)
    ip neigh add 10.0.0.1 lladdr 1.1.1.1 dev mgre0
    ip neigh add 10.0.0.3 lladdr 3.3.3.3 dev mgre0

    (на 3.3.3.3)
    ip neigh add 10.0.0.1 lladdr 1.1.1.1 dev mgre0
    ip neigh add 10.0.0.2 lladdr 2.2.2.2 dev mgre0


    Здесь каждая команда говорит: «соседняя станция с адресом сетевого уровня IP x.x.x.x имеет физический адрес (link layer address, lladdr) y.y.y.y, который доступен через устройство M». Если бы мы настраивали статический Ethernet (без ARP), вместо y.y.y.y стоял бы MAC-адрес соответствующей станции. (Кстати, если посмотреть ip neigh show dev ethN в работающей Ethernet-сети, мы увидим результаты работы ARP — динамически полученные адреса соседей).

    Всё. На этом наш тоннель заработает: каждая из станций сможет пинговать любую другую. Если ядро собрано с поддержкой GRE multicast, то мы вообще получаем полнофункциональную «локалку» — в нашей вирутальной сети будут работать в полную силу протоколы динамической маршрутиации, типа RIP и OSPF!

    Вот так это выглядит со второй станции (2.2.2.2):
    linux2 # ping 10.0.0.1
    PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
    64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=4.41 ms
    64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.429 ms
    ^C
    --- 10.0.0.1 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1013ms
    rtt min/avg/max/mdev = 0.429/2.419/4.410/1.991 ms
    linux2 # ping 10.0.0.2
    PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
    64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.027 ms
    64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.020 ms
    ^C
    --- 10.0.0.2 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 999ms
    rtt min/avg/max/mdev = 0.020/0.023/0.027/0.006 ms
    linux2 # ping 10.0.0.3
    PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
    64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=8.47 ms
    64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.164 ms
    ^C
    --- 10.0.0.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1018ms
    rtt min/avg/max/mdev = 0.164/4.318/8.472/4.154 ms
    linux2 # ip addr show dev mgre0
    5: mgre0@NONE: <UP,LOWER_UP> mtu 1472 qdisc noqueue
        link/gre 0.0.0.0 brd 0.0.0.0
        inet 10.0.0.2/24 brd 10.0.0.255 scope global mgre0
    linux2 # ip neigh show dev mgre0
    10.0.0.1 lladdr 1.1.1.1 PERMANENT
    10.0.0.3 lladdr 3.3.3.3 PERMANENT


    Конечно, если станций много, такой подход не годится — не прописывать же на каждой станции всех соседей! Но вполне понятно, как решать этй проблему. Но об этом как-нибудь потом.
    • +15
    • 7,1k
    • 6
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

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

      0
      Спасибо, интересная информация.
        0
        напишите пожалуста способы применения этих самых тунелей, а то мне валенку непонятно зачем они нужны
          +2
          Не знаете, зачем — значит они вам и не нужны. Но на всякий случай загляните в теги — там есть подсказка.
            0
            VPN это нешифрованный.
            GRE на ru.wikipedia
              +3
              Просто добавь IPsec…
            0
            Еще нужно на каждом узле выполнить
            ip link set mgre0 up


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

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

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