Хитрый пингвин. Нестандартные трюки, которые помогут настроить сеть в Linux

Большую часть времени мы используем только самые простые возможности сетевого стека Linux. Маршрут по умолчанию, SNAT, несколько правил netfilter — все, что нужно среднему маршрутизатору. Однако существует множество функций для менее распространенных и даже весьма нестандартных ситуаций.

Например, возможность использовать нестандартный широковещательный адрес IPv4 sudo ip addr add 192.0.2.1/24 broadcast 192.0.2.2 dev eth0. Технически ни один RFC этого не запрещает. Я этой возможностью не воспользовался ни разу, но почти уверен, что кто-то нашел ей осмысленное применение.

Dummy interfaces

В отличие от Cisco IOS и систем семейства BSD, в Linux может быть только один loopback interface, который всегда называется lo и несет на себе тот самый адрес 127.0.0.1/8. Если нужно просто несколько адресов для разных демонов, можно присвоить их на тот же интерфейс lo.

Но что делать, если нужно несколько независимых локальных интерфейсов?

Кто-то советует решать эту проблему использованием не по назначению интерфейсов других типов, вроде мостов. Не верь им. Правильное решение — использовать интерфейсы типа dummy, которые аналогичны loopback во всем, кроме названия. Исторически так сложилось, что loopback — это уникальный интерфейс lo, и для совместимости сделали отдельный тип.

$ ip link add name dum0 type dummy
$ ip link set dum0 up
$ ip address add 192.0.2.10/32 dev dum0

А зачем мне несколько интерфейсов loopback?

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

Гораздо чаще эта возможность применяется на маршрутизаторах. У каждого маршрутизатора обычно несколько адресов, в связи с чем возникает проблема выбора основного адреса для управления и для сессий протоколов вроде BGP, которые не используют multicast.

Какой выбрать? Любой интерфейс маршрутизатора потенциально может уйти в down, но сессии BGP и SSH должны работать. Поскольку loopback или dummy самопроизвольно не уйдет в down никогда, можно присвоить ему отдельный адрес и анонсировать его остальной сети через протокол OSPF (Open Shortest Path First), который использует multicast и не зависит от конкретных адресов интерфейсов. В этом случае адрес на loopback останется доступным, если у маршрутизатора есть хотя бы один живой канал в остальную сеть.

MACVLAN

У любого интерфейса L2 может быть один и только один MAC-адрес. Что делать, если хочется отправлять кадры с разным MAC-адресом с одного физического интерфейса?

У ядра Linux на это есть ответ, и тип таких интерфейсов называется macvlan. Создать и поднять его можно следующими командами:

$ sudo ip link add name macvlan0 link eth0 type macvlan
$ sudo ip link macvlan0 up

В опции link мы указываем родительский физический интерфейс. По умолчанию используется случайный MAC-адрес, но ничто не мешает присвоить любой другой командой ip link set dev macvlan0 address <some MAC>.

Посмотрим на статус нового интерфейса:

$ ip li sh macvlan0
3: macvlan0@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 8a:01:12:8f:1f:7c brd ff:ff:ff:ff:ff:ff

Если присвоить нашему виртуальному интерфейсу адрес из сети 203.0.113.0/24, можно увидеть, что весь трафик в эту сеть отправляется с MAC-адреса от macvlan0, а не родительского eth0.

$ ip address add 203.0.113.90/25 dev macvlan0
$ tcpdump -eni eth0 dst 203.0.113.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:49:21.988045 8a:01:12:8f:1f:7c > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 203.0.113.1 tell 203.0.113.90, length 28

Зеркалирование трафика

Зеркалирование и перенаправление обычно организуют на коммутаторах. Но если нужно сделать это на сервере или маршрутизаторе с Linux, никто не запретит.

Правила зеркалирования создаются с помощью tc. Мы рассмотрим только простейший случай: готовый рецепт для зеркалирования с dum0 на dum1 (интерфейсы можно подставить любые):

$ tc qdisc add dev dum0 ingress
$ tc filter add dev dum0 parent ffff: protocol all u32 match u8 0 0 action mirred egress mirror dev dum1

$ tc qdisc add dev dum0 handle 1: root prio
$ tc filter add dev dum0 parent 1: protocol all u32 match u8 0 0 action mirred egress mirror dev dum1

Опция mirred позволяет как копировать, так и перенаправлять пакеты с одного интерфейса на другой. В сочетании с классификаторами трафика из tc можно настроить самые разные сценарии, от зеркалирования только определенного трафика до отправки трафика сверх определенной полосы пропускания на другой интерфейс.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Даниил Батурин: @dmbaturin Координатор проекта VyOS (https://vyos.io), «языковед», функциональщик, иногда сетевой администратор.

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

  • Автор статьи - молодец!
    Было интересно.
    С нетерпением буду ждать новых публикаций.

    • Я помню такой же щенячий(детский) восторг когда узнавал от гуру DOS синтаксис команд command.com(командный процессор, теперь это "cmd"). Похоже теперь x-nix-апологеты переживают тот же оргазм. )))))