Протокол ARP: разрешение IP-адресов в MAC-адреса, ARP-кэш, Proxy ARP, Gratuitous ARP и родственные протоколы (RARP, Inverse ARP, NDP).
Какую задачу решает протокол ARP?
Почему частые ARP-запросы создают нагрузку на сеть?
Что такое Proxy ARP и почему его использование нежелательно?
Для чего используется Gratuitous ARP?
В каких средах работает протокол ARP?
Протокол ARP: разрешение IP в MAC, ARP-кэш и разновидности — одна тема в двух курсах
NDP в IPv6 заменяет ARP — Neighbor Discovery Protocol выполняет аналогичные функции через ICMPv6
Безопасность L2 включает атаки на ARP-таблицу и подмену MAC — напрямую связано с механизмом ARP
ARP (Address Resolution Protocol) умеет преобразовывать абсолютно любые адреса в любые канальные адреса. Не обязательно это должны быть протокол IP и протокол Ethernet — адреса, которые преобразуются, могут быть любыми. ARP умеет преобразовывать IP-адреса в Ethernet, но также может работать с любым другим протоколом сетевого уровня и любым другим протоколом канального уровня.
Для того чтобы ARP работал, необходимо, чтобы протокол канального уровня поддерживал широковещательную рассылку (broadcast). То есть чтобы вы могли отправить кадр на канальном уровне, и этот кадр дошёл бы до всех получателей, а получатели могли бы отправить вам ответ.
Собственно говоря, ARP примерно так и делает: он рассылает на всю сеть сообщение — «у кого из вас такой IP, скажите свой MAC». И тот, у кого такой IP, возвращает свой MAC-адрес.
Если посмотреть на формат заголовка, в этом пакете будут поля для совершенно произвольного размера канального адреса и совершенно произвольного размера сетевого адреса. Вы не привязаны к 48 битам канального адреса и не привязаны к 32 битам IP-адреса. ARP умеет работать с адресами любого размера и преобразовывать их между собой.
Проблема, которую ARP решает, — это упаковка IP-пакета в кадр канального уровня (Ethernet-кадр). Если вы соорудили IP-пакет и хотите отправить его, например, с адреса 10.0.0.1 на адрес 10.0.0.2, вам нужно упаковать этот IP-пакет в Ethernet-кадр. Свой MAC-адрес вы, конечно, можете проставить, а вот MAC-адрес получателя нужно каким-то образом узнать. ARP как раз эту функцию и выполняет.
Принцип работы ARP очень простой:
Пока вы отправляете ARP-запрос, IP-пакет, который вы хотели отправить, лежит в буфере и ждёт своей очереди.
Но другого механизма разрешения канальных адресов из IP-адреса в Ethernet (IPv4) у нас нет. Рано или поздно IP-адрес удастся разрешить в MAC.
ARP может по определению работать только в тех средах, где работают broadcast-рассылки. Если в канальной среде broadcast есть — ARP отработает. Если broadcast нет (например, Frame Relay или DMVPN), то ARP бесполезен — он не сможет доставить один кадр до всех получателей.
Естественно, нельзя каждый раз на каждый пакет отправлять дополнительный ARP-запрос. IP-адреса и MAC-адреса меняются не так часто, поэтому можно в течение некоторого времени запоминать ответы. Разумно хранить их в промежуточной таблице — кэше ARP.
Хранить данные пожизненно нельзя: IP-адрес может смениться, MAC-адрес может поменяться. Но в течение разумного времени хранить можно.
Пополнять кэш можно при получении любого ARP-пакета. Запрос и ответ выглядят примерно одинаково — различаются лишь небольшим количеством бит, формат у них одинаковый. Каждый раз, когда вы получаете любой ARP-пакет, в нём в явном виде фигурируют IP-адрес и MAC-адрес отправителя, и вы можете занести их в кэш.
Записи хранятся в кэше не вечно — у каждой есть срок жизни. Этот срок никак не регламентирован стандартом и зависит от ОС и настроек:
| Платформа | Время жизни по умолчанию |
|---|---|
| Cisco | 4 часа |
| Windows | Несколько минут |
Можно настроить время самостоятельно:
Поскольку ARP использует broadcast, есть смысл минимизировать их количество. Broadcast — это всегда неэффективное использование сети: все узлы напрягаются, считают контрольные суммы, проверяют «а вдруг это мне». А на самом деле большая часть broadcast почти никому не нужна.
Когда вы отправляете broadcast, вы хотите доставить его до одного-двух участников, но просто не знаете, кому именно. А природа broadcast такова, что все начинают напрягаться. Минимизация broadcast позитивно влияет на всю сеть.
Если мы говорим про IP в привязке к Ethernet (подавляющее большинство случаев), формат будет следующий. Пакет выровнен по границе 32 бит (машинного слова):
| Поле | Размер | Описание | Значение для Ethernet + IPv4 |
|---|---|---|---|
| Hardware Type (H Type) | 2 байта | Тип канальной среды | 0x0001 (Ethernet) |
| Protocol Type (P Type) | 2 байта | Тип сетевого адреса | 0x0800 (IPv4) |
| HLen (Hardware Length) | 1 байт | Длина аппаратного адреса в байтах | 6 (MAC = 48 бит) |
| PLen (Protocol Length) | 1 байт | Длина сетевого адреса в байтах | 4 (IPv4 = 32 бита) |
| Operation | 2 байта | Код операции | 1 — запрос, 2 — ответ |
| Sender Hardware Address (SHA) | 6 байт | MAC-адрес отправителя | — |
| Sender Protocol Address (SPA) | 4 байта | IP-адрес отправителя | — |
| Target Hardware Address (THA) | 6 байт | MAC-адрес получателя | 000000 в запросе |
| Target Protocol Address (TPA) | 4 байта | IP-адрес получателя | — |
Когда вы задаёте вопрос «у кого такой IP, скажите свой MAC»:
1 (запрос)Когда вы отвечаете:
2 (ответ)MAC-адрес отправителя фигурирует дважды: один раз в заголовке Ethernet, другой — в заголовке ARP.
По стандарту:
Однако некоторые операционные системы нарушают это правило и ответ тоже отсылают broadcast. Логика такая: если мой IP и MAC кому-то были интересны, возможно, это будет интересно не только спрашивающему. Тогда все узлы обновят свой кэш ARP, и в будущем количество ARP-запросов уменьшится.
Кроме того, существуют расширения к протоколу ARP, при которых запрос может идти unicast, а ответ — broadcast. Жёсткой привязки нет. Но базовое правило: если вы спрашиваете — broadcast, если отвечаете — по-хорошему unicast.
Если между отправителем и получателем есть промежуточные маршрутизаторы, обычный ARP не отработает — он работает только в пределах одной широковещательной среды.
Рассмотрим ситуацию. Есть узел 10.0.1.1 и узел 10.0.2.2 — они находятся в разных канальных средах.
10.0.2.2 поддерживает бесклассовую адресацию и понимает, что живёт в сети с маской /24.10.0.1.1 поддерживает только классовую адресацию. Он видит IP из сети 10.0.0.0 класса A и считает, что маска /8. Значит, 10.0.2.2 должен быть в одной канальной среде с ним.Узел 10.0.1.1 кричит на всю сеть: «У кого IP 10.0.2.2, скажите свой MAC!» Но 10.0.2.2 находится в другом широковещательном домене и не может это услышать.
Proxy ARP — это когда вместо оригинального получателя отвечает посредник (маршрутизатор).
Маршрутизатор с IP 10.0.1.2/24 получает broadcast-кадр с ARP-запросом «у кого IP 10.0.2.2?». Он понимает, что в сети 10.0.1.0/24 такой вопрос может задать только тот, кто не поддерживает бесклассовую адресацию. И отвечает своим собственным MAC: «Шли всё, что хочешь отправить на 10.0.2.2, на мой MAC».
Узел 10.0.1.1 получает ответ и начинает слать кадры на MAC-адрес маршрутизатора. Маршрутизатор принимает такие кадры, раскрывает их, видит внутри IP-пакет, который ему не адресован, и просто маршрутизирует его дальше — как обычно.
На каждый IP-адрес, который узел воспринимает как принадлежащий своей сети, создаётся отдельная строчка в кэше ARP. Хотите отправить данные на 10.0.2.2 — получили MAC роутера. На 10.0.3.3 — снова MAC роутера. На каждый IP — одна и та же запись, но всё равно отдельная строка.
Это особенно плохо в случае со статическим маршрутом, где указан только выходной интерфейс без IP следующего шлюза. Тогда на каждый IP-пакет с уникальным адресом назначения роутер будет делать ARP-запрос. Если роутер провайдера поддерживает Proxy ARP, он ответит на все — и кэш ARP разрастётся до огромных размеров.
Представьте: 10 пользователей, каждый запустил торрент и рассылает пакеты на пару тысяч IP-адресов. Получаем 20 000 записей в кэше ARP. На маленьком роутере (Cisco 800) с 256 МБ ОЗУ это может привести к kernel panic из-за нехватки памяти.
Proxy ARP — это костыль для определённых ситуаций:
Если есть возможность не использовать Proxy ARP — не используйте. Всегда старайтесь делать правильно: один VLAN — одна IP-сеть, VPN-пользователи в отдельной подсети, шлюз по умолчанию (default gateway) настроен явно.
Если вы назначаете IP-адрес на интерфейс, перед его активацией можно запустить проверку — не занят ли адрес.
Вы отправляете специальный ARP-запрос (ARP Probe):
0.0.0.0 (вы ещё не владеете этим адресом)1 (запрос)Если кто-то ответит своим MAC — значит, адрес уже занят. Вы получите оповещение о конфликте и можете отказаться поднимать этот адрес. При этом у другого узла конфликта не будет, потому что вы адрес так и не заняли.
После того как вы заняли IP-адрес, нужно дать всем остальным знать об этом. Для этого используется Gratuitous ARP — «безвозмездный ARP». Есть два варианта:
Вариант 1 — запрос (Operation = 1):
000000По сути, вы спрашиваете сами себя: «У кого мой IP?» Если кто-то ответит — обнаружен конфликт. Если нет — все узлы обновят свой кэш.
Вариант 2 — ответ (Operation = 2):
Вы ничего не спрашиваете, а просто декларируете: «Это мой IP, вот мой MAC. Получите, распишитесь».
Оба варианта делают примерно одно и то же — обновляют кэш ARP на всех узлах сети. Какой именно режим используется — зависит от операционной системы. Можно совмещать оба: сначала ARP Probe (проверка), потом Gratuitous ARP (объявление).
RARP — предшественник DHCP (и даже предшественника DHCP — протокола BootP). Делает обратное тому, что делает ARP: кричит на всю сеть «У кого такой MAC, скажите свой IP!»
Сценарий использования: узел знает только свой MAC-адрес и хочет узнать, какой IP ему назначен. Сервер с базой MAC-IP-соответствий отвечает нужным IP-адресом. В реальном мире RARP уже не встречается — он был заменён BootP, а тот развился в DHCP.
InARP работает в средах без broadcast (например, Frame Relay). В отличие от обычного ARP, который реагирует «по запросу», InARP отрабатывает сразу при инициализации соединения.
Когда интерфейс включается и вы опознаёте доступные DLCI (канальные адреса), вы сразу рассылаете во все них сообщение: «Мой IP вот такой». Все узлы узнают, какой IP живёт за каким канальным адресом, и когда им потребуется отправить данные, они уже будут знать адрес.
Не путайте Reverse ARP и Inverse ARP:
- RARP — из MAC-адреса получить IP-адрес (предшественник DHCP).
- InARP — отправить свой IP во все известные канальные адреса при инициализации (используется в Frame Relay).
SLARP — протокол, не использующий формат пакета ARP, несмотря на название. Это подпротокол цисковской реализации HDLC (не путать со стандартным HDLC — они не похожи). Решает задачу управления базой соседей в serial-соединениях: помогает узнать и назначить IP-адрес соседу. Работает только с IP-адресами, канальные адреса в Serial Link не нужны.
NDP — это аналог ARP, но для IPv6. Более эффективен: вместо broadcast использует multicast на группу узлов, у которых последние 3 байта IP-адреса совпадают с искомым. С большой вероятностью такое сообщение дойдёт только до одного узла — того, у которого действительно нужный IP. В худшем случае 2-3 узла получат запрос — всё равно лучше, чем broadcast на всех.
Для демонстрации используются два устройства на базе Cisco IOS: роутер и L3-коммутатор, связанные по IP.
Router# show ip arp
В кэше видны две записи:
10.0.0.4 — наш собственный адрес (знаем свой MAC, не нужно орать на сеть)10.0.0.1 — адрес соседа, возраст записи 119 минут (из 240 максимальных по умолчанию)Router(config)# arp 10.0.0.5 dead.bif0.0005 arpa
После этого в show ip arp появляется запись без указания возраста (статическая) и без привязки к интерфейсу.
После команды clear arp и перезапуска интерфейса в Wireshark видны следующие события:
10.0.0.6) и MAC, Operation = 2 (ответ), Target MAC = FF:FF:FF:FF:FF:FF.10.0.0.1: запрос с нашим MAC и IP (10.0.0.6), Target IP = 10.0.0.1, Target MAC = 00:00:00:00:00:00, Operation = 1.10.0.0.1 отвечает своим MAC-адресом, Operation = 2.Первый ICMP-пакет теряется, пока ARP не успел отработать — это видно по «точке» вместо ответа.
При переназначении IP-адреса на интерфейсе отправляется ARP-запрос, где Sender IP = 0.0.0.0, а Target IP — тот адрес, который проверяется. Это механизм Address Conflict Detection.
ARP — полезный и несложный служебный протокол, без которого работа IP поверх Ethernet была бы невозможна. Без него пришлось бы прописывать все MAC-адреса статически на каждом узле.
Основные моменты:
ARP — не единственный служебный протокол. Для работы IP в Ethernet также нужны DHCP, ICMP и другие.