✍️ Статья Ядерные приколы. Осваиваем необычные фичи канального уровня в Linux

The 146X Project Dublikat Web Studio Avram Lincoln AL Service Navigator Knyaz

BlackPope

Команда форума
Модератор DeepWeb ✔️
PR-Group DeepWeb 🔷
Регистрация
27.04.2020
Сообщения
230
дро Linux — основа большинства программных маршрутизаторов и файрволов, и неудивительно — количество функций сетевого уровня в нем огромно. Тем не менее в Linux есть ряд полезных и необычных функций для работы с канальным и физическими уровнями, которые часто остаются в тени. Давай попробуем компенсировать этот пробел.

Используем ethtool

Сначала рассмотрим утилиту для общения с сетевыми картами на самых низких уровнях — ethtool.

С помощью команды ip можно просмотреть и поменять почти все, что касается сетевого стека ядра, но, если речь идет об аппаратной части самой карты, тут без ethtool не обойтись.

Например, все мы знаем, что MAC-адрес сетевой карты легко поменять.

$ ip link show eth0

2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000

link/ether 00:08:a2:0a:52:cd brd ff:ff:ff:ff:ff:ff

$ sudo ip link set dev eth0 address 00:aa:bb:cc:dd:ee

$ ip link show eth0

2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000

link/ether 00:aa:bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff


С точки зрения ядра, у eth0 теперь новый адрес. Оригинальный адрес остался только в прошивке сетевой карты. В выводе ip его не найти, но ethtool способна заглянуть глубже.

$ ethtool --show-permaddr eth0

Permanent address: 00:08:a2:0a:52:cd


Многие сетевые карты поддерживают аппаратное ускорение некоторых функций, например вычисление контрольных сумм пакетов TCP и UDP. Просмотреть полный список функций и их состояние можно командой ethtool --show-features <interface>. Обычно все, что поддерживается, включено по умолчанию, но убедиться не будет лишним.

Если ты работаешь без физического доступа к оборудованию, наверняка тебе уже приходилось искать нужный порт. Традиционный метод — потушить порт (sudo ip link set <interface> down) и попросить напарника посмотреть, какой из портов потух. Но в ряде случаев найти физическое расположение порта можно без ущерба для трафика с помощью команды ethtool --identify <interface>. Она заставляет указанную карту моргать светодиодом, который отвечает за индикацию up/down. Увы, работает не со всеми моделями карт — помни, что бывает и ложноотрицательный результат.

«Скрытая» проводная сеть

ARP — фундаментальный протокол сетей Ethernet, без которого хосты не смогут автоматически найти друг друга и установить соответствие IP- и MAC-адресов. Но что, если ты специально хочешь сделать так, чтобы сторонний хост не смог подключиться к твоей сети?

Самое правильное решение этой задачи — протокол 802.1x, который обеспечивает настоящую аутентификацию клиентов. Другое, тоже вполне правильное решение — настроить политику доступа на коммутаторе по белому списку MAC-адресов.

Абсурдным и достаточно неожиданным для условного противника решением было бы отключить ARP. Как ни странно, в Linux это вполне возможно. К примеру, отключить его для интерфейса eth0 можно командой sudo ip link set eth0 arp off.

Как же хосты найдут друг друга без ARP? В Linux добавить записи в таблицу ARP можно вручную: ip neighbor add 10.0.0.1 lladdr aa:bb:cc:dd:ee:ff dev eth0.

Программные мосты в Linux

В терминологии Ethernet «коммутатор» (switch) и «мост» (bridge) — это синонимы. Термин switch придумали, чтобы отличать многопортовые коммутаторы от первых двухпортовых мостов. Программные реализации коммутатора Ethernet по традиции называют мостами, независимо от числа портов.

Вот и в Linux программный коммутатор называется мостом. Производительность таких коммутаторов невысока — ни о каких десяти гигабитах речь не идет. Кроме того, встроенная функциональность ядра Linux для этой цели достаточно ограниченна по сравнению с новыми проектами вроде Open vSwitch. Тем не менее в ряде случаев она может оказаться полезной.

Объединять два физических сетевых интерфейса в «тупой» мост имеет смысл только в качестве вынужденной меры, если на объекте нет свободных портов аппаратного коммутатора, но есть устройство с Linux и неиспользуемыми сетевыми картами.

Осмысленно применять эту фичу стоит в других направлениях. Во-первых, сетевой интерфейс не обязан быть физическим — это может быть и туннель. Некоторые приложения требуют общего широковещательного сегмента. Если тебе нужно обеспечить работу таких приложений в удаленной сети через интернет, ты можешь соединить свои сети туннелем, который способен инкапсулировать кадры Ethernet. О настройке таких туннелей в Linux я уже писал в статье «Неизвестные туннели Linux. Осваиваем новые способы строить виртуальные сети»: это GRE, L2TPv3 и VXLAN (а также OpenVPN в режиме TAP и WireGuard).

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

Но для начала вспомним, как делаются мосты.

Возводим мосты

Вернее, не вспомним, а научимся это делать с помощью iproute2. Классическая утилита brctl уже давно объявлена устаревшей, вместе с ifconfig и прочими командами из net-tools, и дистрибутивы Linux начинают их удалять, так что лучше сразу действовать по-новому.

Для примера объединим интерфейсы eth0 и eth1 в мост br0.

$ sudo ip link add name br0 type bridge
$ sudo ip link set dev eth0 master br0
$ sudo ip link set dev eth1 master br0


Удалить интерфейс из моста можно было бы командой ip link set dev eth0 nomaster.

Что в iproute2 хорошо, так это унификация разных команд. Когда-то стандартным способом просмотреть информацию об интерфейсах моста была команда brctl show.

$ sudo brctl show br0

bridge name bridge id STP enabled interfaces

br0 8000.0008a20a52cf no eth0

eth1


В iproute2 на смену множеству особых случаев пришла общая концепция ведущего интерфейса (master) и ведомых (slave). Просмотреть все ведомые интерфейсы можно командой ip link show master <interface>. Эта команда будет работать и для моста, и для транка LACP, и для всего прочего, что подразумевает отношения ведущий — ведомый. Единственный недостаток — формат вывода не заточен под конкретный тип интерфейса.

$ ip --brief link show master br0

eth0 UP 9a:a3:32:c1:d6:8b <BROADCAST,MULTICAST,UP,LOWER_UP>

eth2 UP 00:08:a2:0a:52:cf <BROADCAST,MULTICAST,UP,LOWER_UP>


Делаем прозрачный файрвол

Прежде всего нужно убедиться, что твое ядро не собрано с CONFIG_BRIDGE_NETFILTER=n. Затем — проверить, что установлены в единицу следующие опции sysctl: net.bridge.bridge-nf-call-iptables, net.bridge.bridge-nf-call-ip6tables, net.bridge.bridge-nf-call-arptables.

А теперь хорошая новость: больше ничего особенного делать не потребуется. Если в ядре есть нужный модуль и его работа не заблокирована опциями sysctl, то все правила xtables автоматически применяются не только к маршрутизируемому, но и к коммутируемому трафику. Для проверки можно заблокировать пользователям моста ICMP: sudo iptables -I FORWARD -i br0 -p icmp -j DROP.

Подменяем MAC проходящему трафику

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

Но однажды мне потребовалась совсем уж экзотическая функция и без того экзотического пакета. Как ни странно, ebtables умеет NAT канального уровня — трансляцию MAC-адресов источника и назначения.

Ситуация была следующая: мой коллега хотел отправить отзеркалированный трафик с порта коммутатора в локальный процесс для проведения некоторых тестов. Поскольку трафик приходил с чужим MAC, ядро никогда не стало бы его воспринимать как свой. Тут и пригодилась, казалось бы, абсурдная возможность.

$ sudo ebtables -t nat -I PREROUTING -i eth0 -j dnat --to-destination aa:bb:cc:dd:ee:ff --dnat-target ACCEPT

После этого оставалось только заменить IP локальным с помощью обычного NAT.

Заключение

Возможности Linux открывают большой простор для самых изощренных конфигураций на всех уровнях модели OSI. Если внимательно читать документацию, там, как правило, можно найти что-то на любой, даже самый необычный случай.
 

📌 Золотая реклама

AnonPaste

Верх