Привет habr! Каждый будущий инженер в процессе изучения сетевых технологий знакомится с протоколом ARP (Address Resolution Protocol, далее ARP). Основная задача протокола – получить L2 адрес устройства при известном L3 адресе устройства. На заре профессиональной карьеры начинающий специалист, как мне кажется, редко сталкивается с ситуациями, когда нужно вспомнить про существование ARP. Создаётся впечатление, что ARP – это некоторый автономный сервис, не требующий никакого вмешательства в свою работу, и при появлении каких-либо проблем со связью многие по неопытности могут забыть проверить работу ARP.

Я помню свой порядок мыслей, когда я начинал работать сетевым инженером: «Так, интерфейс поднялся, ошибок по физике вроде как не видно. Маршрут, куда слать пакеты, я прописал. Списков доступа никаких нет. Так почему же не идёт трафик? Что маршрутизатору ещё не хватает?» Рано или поздно каждый сетевой инженер столкнётся с проблемой, причина которой будет лежать именно в особенностях работы/настройки ARP на сетевом оборудовании. Простейший пример: смена шлюза на границе сети (например, вместо сервера MS TMG устанавливаем маршрутизатор). При этом конфигурация маршрутизатора была проверена заранее в лабораторных условиях. А тут, при подключении к провайдеру никакая связь не работает. Возвращаем MS TMG — всё работает. Куда смотреть после проверки канального и физического уровня? Наиболее вероятный ответ – проверить работу ARP.

В данной заметке я не буду подробно описывать принципы работы ARP и протоколов этого семейства (RARP, InARP, UnARP и т.д.). На эту тему уже существует уйма статей в Интернете (например, здесь не плохо описаны разновидности ARP). Единственный теоретический момент, на котором я заострю чуть больше внимания, – механизм Gratuitous ARP (GARP).

Статья будет состоять из двух частей. В первой части будет немного теории и особенности работы ARP на маршрутизаторах Cisco, связанные с правилами NAT и с функцией Proxy ARP. Во второй части опишу отличия в работе ARP между маршрутизаторами Cisco и межсетевыми экранами Cisco ASA, а также поделюсь несколькими интересными случаями из практики, связанными с работой ARP.

Чуть-чуть теории

ARP-запрос/ARP-ответ

Ниже представлен пример обмена ARP-запросом/ARP-ответом в программе-сниффере Wireshark:





ARP-запрос отправляется на широковещательный MAC-адрес ff:ff:ff:ff:ff:ff. В теле ARP-запроса поле с неизвестным значением Target MAC Address заполняется нулями.

ARP-ответ отправляется на MAC-адрес получателя, отправившего ARP-запрос. В поле Sender MAC Address указывается запрашиваемый MAC-адрес устройства.

Поле opcode в заголовке ARP может принимает значение 1 для ARP-запроса и значение 2 для ARP-ответа.

Чтобы два устройства могли начать передавать трафика между собой, в их ARP-таблицах должна существовать соответствующая запись о соседнем устройстве. Логично предположить, чтобы ARP-запись появилась в таблицах, для каждого устройства должна отработать процедура ARP-запрос/ARP-ответ. То есть перед передачей трафика в сети должны пройти по два ARP-запроса и два ARP-ответа (ARP-запрос/ARP-ответ для первого компьютера и ARP-запрос/ARP-ответ для второго компьютера). Однако, данное предположение верно не для всех случаев. Сетевое оборудование Cisco добавляет новую запись в ARP-таблицу сразу по приходу ARP-запроса от удалённого устройства.

Рассмотрим пример. В широковещательный домен добавляется новое устройство с адресом 198.18.0.200. Запустим пинг с нового устройства и посмотрим debug arp на маршрутизаторе Cisco:

019383: Feb  4 10:38:55 UTC: IP ARP: rcvd req src 198.18.0.200 64e9.50c8.d6cd, dst 198.18.0.1 GigabitEthernet0/0/1.7
019384: Feb  4 10:38:55 UTC: IP ARP: creating entry for IP address: 198.18.0.200, hw: 64e9.50c8.d6cd
019385: Feb  4 10:38:55 UTC: IP ARP: sent rep src 198.18.0.1 d8b1.902e.e741,
                 dst 198.18.0.200 64e9.50c8.d6cd GigabitEthernet0/0/1.7

Как видно, сразу по пришествии ARP-запроса от неизвестного IP-адреса (rcvd req src 198.18.0.200), маршрутизатор создаёт соответствующую запись в своей ARP-таблице (creating entry for IP address: 198.18.0.200, hw: 64e9.50c8.d6cd).

Для текущей статьи я не проводил подробного исследования по вопросу, какое именно сетевое оборудование добавляет ARP-запись по пришествии ARP-запроса. Однако, предполагаю, описанное поведение присуще не только сетевому оборудованию Cisco, но и сетевому оборудованию других производителей, так как данный механизм позволяет существенно сократить ARP-трафик в сети.

ARP-запрос/ARP-ответ для конечного оборудования
Описанное поведение присуще сетевому оборудованию. Конечное оборудование в большинстве случаев, получает запись в ARP-таблицу только после полноценной процедуры ARP-запрос/ARP-ответ. Для примера, я проверил процедуру на компьютере с операционной системой Windows 7. Ниже представлен дамп ARP-пакетов. В данном примере был очищен arp-cache на маршрутизаторе Cisco и на Windows-компьютере. После этого был запущен пинг от маршрутизатора к компьютеру.



Из представленного дапма видно, что сперва маршрутизатор отправляет ARP-запрос и получает ARP-ответ. Но ARP-запрос от маршрутизатора не приводит к появлению требуемой записи в ARP-таблице Windows-компьютера, поэтому, в свою очередь, компьютер отправляет ARP-запрос и получает ARP-ответ от маршрутизатора.

Gratuitous ARP

Механизм Gratuitous ARP используется для оповещения устройств в рамках широковещательного домена о появлении новой привязки IP-адреса и MAC-адреса. Когда сетевой интерфейс устройства получает настройки IP (вручную или по DHCP), устройство отправляет Gratuitous ARP сообщение, чтобы уведомить соседей о своём присутствии. Gratuitous ARP сообщение представляет собой особый вид ARP-ответа. Поле opcode принимает значение 2 (ARP-ответ). MAC-адрес получается как в заголовке Ethernet, так и в теле ARP-ответа является широковещательным (ff:ff:ff:ff:ff:ff). Поле Target IP Address в теле ARP-ответа совпадает с полем Sender IP Address.

Механизм Gratuitous ARP используется для многих целей. Например, с помощью Gratuitous ARP можно уведомить о смене MAC-адреса или обнаружить конфликты IP-адресов. Другой пример — использование протоколов резервирования первого перехода (First Hop Redundancy Protocols), например, HSRP у Cisco. Напомню, HSRP позволяет иметь виртуальный IP-адрес, разделённый между двумя или более сетевыми устройствами. В нормальном режиме работы обслуживание виртуального IP-адреса (ответы на ARP-запросы и т.д.) обеспечивает основное устройство. При отказе основного устройства обслуживание виртуального IP-адреса переходит ко второму устройству. Чтобы уведомить о смене MAC-адреса ответственного устройства, как раз отправляется Gratuitous ARP-сообщения.

В примере ниже представлено Gratuitous ARP сообщение при включении сетевого интерфейса маршрутизатора с настроенным IP-адресов 198.18.0.1.



Если на маршрутизаторе настроен secondary IP-адрес, при переходе интерфейса в состояние UP будут отправлены Gratuitous ARP уведомления для каждого IP-адреса интерфейса. В примере ниже представлены Gratuitous ARP сообщения, отправляемые при включении интерфейса маршрутизатора с основным IP-адресом 198.18.0.1 и secondary IP-адресом 198.18.2.1.



Безусловно, маршрутизатор будет отвечать на ARP-запросы как для основного, так и для secondary IP-адреса.

Логично предположить, что как только устройство получает Gratuitous ARP, сразу добавляется новая запись в ARP-таблицу. Однако это не так. Если в таблице устройства отсутствовала ARP-запись, связанная с IP-адресом из Gratuitous ARP сообщения, новая запись добавлена не будет. При необходимости отправить трафик будет сформирован ARP-запрос и получен ARP-ответ. Только после этой процедуры новая запись добавится в ARP-таблицу.

Пример на маршрутизаторе Cisco. Включим debug arp и подключим в широковещательный домен новое устройство с адресом 198.18.0.200. До подключения нового устройства ARP-таблица маршрутизатора выглядит следующим образом:
cisco#sh arp | inc 198.18.0.200
<вывод пуст>

Включаем новое устройство с адресом 198.18.0.200. Получаем debug-сообщение о приходе Gratuitous ARP:
IP ARP: rcvd rep src 198.18.0.200 64e9.50c8.d6cd, dst 198.18.0.200 GigabitEthernet0/0/1

Проверяем ARP-таблицу:
cisco#sh arp | inc 198.18.0.200
<вывод пуст>

Новая запись не появилась. Делаем пинг до нового адреса:
cisco#ping 198.18.0.200
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 198.18.0.200, timeout is 2 seconds:

019275: Feb  4 10:23:06 UTC: IP ARP: creating incomplete entry for IP address: 198.18.0.200 interface GigabitEthernet0/0/1
019276: Feb  4 10:23:06 UTC: IP ARP: sent req src 198.18.0.1 d8b1.902e.e741,
                 dst 198.18.0.200 0000.0000.0000 GigabitEthernet0/0/1
019277: Feb  4 10:23:06 UTC: IP ARP: rcvd rep src 198.18.0.200 64e9.50c8.d6cd, dst 198.18.0.1 GigabitEthernet0/0/1

.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 2/2/3 ms

Debug-сообщения показывают, что прошла процедура ARP-запрос/ARP-ответ. Проверяем ARP-таблицу:
cisoc#sh arp | i 198.18.0.200
Internet  198.18.0.200            6   64e9.50c8.d6cd  ARPA   GigabitEthernet0/0/1

Новая запись появилась.

ARP и NAT на маршрутизаторах Cisco

Теперь рассмотрим, как обстоят дела с ARP, если на маршрутизаторе используются правила трансляции сетевых адресов – NAT или PAT. В этом случае, мы можем транслировать адрес или адреса локальной сети либо в адрес интерфейса маршрутизатора, либо в какой-либо другой адрес, который будет называться в терминологии NAT внутренним глобальным адресом (inside global или inside mapped). Если трансляция происходит в адрес интерфейса, с ARP вопросов нет. В случае трансляции в адрес, отличный от адреса интерфейса, действуют следующие правила:
  1. Если внутренний глобальный адрес находится в той же IP-подсети, что и адрес интерфейса маршрутизатора, маршрутизатор будет отвечать на ARP-запросы к этому адресу. При этом в собственной arp-таблице маршрутизатора создаётся статическая запись для внутреннего глобального адреса.
  2. Если внутренний глобальный адрес находится в IP-подсети, отличной от адреса интерфейса маршрутизатора, маршрутизатор не будет отвечать на ARP-запросы к этому адресу. В собственной arp-таблице статическая запись не создаётся. Чтобы связь с таким IP-адресом заработала, требуется дополнительная настройка. Мы рассмотрим данный случай более подробно далее в статье.

Отдельно следует упомянуть поведение Gratuitous ARP. Рассматривать варианты генерации Gratuitous ARP для различных случаев (переход интерфейса в состояние UP, изменение основного IP-адреса интерфейса, изменение Secondary IP-адреса и т.д.) не буду, так как получится слишком много вариантов. Хочу указать только два момента. Первый момент: настройка нового правила NAT не приводит к генерации Gratuitous ARP уведомления. Второй момент: с помощью команды clear arp-cache можно не только очистить все динамические записи arp в таблице маршрутизатора, но и заставить маршрутизатор отправить Gratuitous ARP для всех IP-адресов, на которые маршрутизатор должен отвечать, включая внутренние глобальные адреса из правил NAT.
Рассмотрим примеры на основании следующей простейшей топологии:



Примечание: для тестов использовался маршрутизатор C4321 с программным обеспечением 15.4(3)S3 и межсетевой экран Cisco ASA5505 c программным обеспечением 9.1(6)6.

Компьютер Wireshark с адресов 198.18.0.250 в нашем случае будет обозначать подключение к внешней сети (например, к Интернет-провайдеру). С помощью сниффера Wireshark будем просматривать обмен сообщениями ARP между маршрутизатором и компьютером.

Настройки интерфейсов маршрутизатора:
interface GigabitEthernet0/0/0
 description === inside ===
 ip address 192.168.20.1 255.255.255.0
 no ip proxy-arp
 ip nat inside
!
interface GigabitEthernet0/0/1.7
 description === outside ===
 ip address 198.18.0.1 255.255.255.0
 no ip proxy-arp
 ip nat outside

Добавим правило динамического NAT, чтобы транслировать адрес компьютера из LAN (192.168.20.5) во внутренний глобальный адрес 198.18.0.5 при обращении к компьютеру во вне (Wireshark). Добавим правило статического PAT для публикации TCP порта 3389 (RDP) компьютера из LAN под глобальным адресом 198.18.0.2.



ip access-list standard acl-test-arp
 permit 192.168.20.5
ip nat pool test-pool 198.18.0.5 198.18.0.5 netmask 255.255.255.252
ip nat inside source list acl-test-arp pool test-pool overload
ip nat inside source static tcp 192.168.20.5 3389 198.18.0.2 3389 extendable 

Посмотрим ARP-таблицу на маршрутизаторе:
cisco#sh arp
Protocol  Address          Age (min)  Hardware Addr   Type   Interface
. . .
Internet  198.18.0.1              -   d8b1.902e.e741  ARPA   GigabitEthernet0/0/1.7
Internet  198.18.0.2              -   d8b1.902e.e741  ARPA   GigabitEthernet0/0/1.7
Internet  198.18.0.5              -   d8b1.902e.e741  ARPA   GigabitEthernet0/0/1.7
. . .

Видим, что в ARP-таблице присутствуют статические записи как для внешнего интерфейса маршрутизатора (198.18.0.1), так и для внутренних глобальных адресов из правил динамического и статического NAT.

Сделаем clear arp-cache на маршрутизаторе и посмотрим в Wireshark, какие Gratuitous ARP уведомления будут отправлены с внешнего интерфейса:



Как видно, маршрутизатор уведомил о готовности обслуживать адрес интерфейса, адрес из правила динамического NAT и адрес из правила статического NAT.

А теперь представим ситуацию, когда провайдер расширяет пул публичных адресов, выданных клиенту, за счёт другой подсети. Предположим, дополнительно к IP-подсети 198.18.0.0/24 на внешнем интерфейсе маршрутизатора мы получаем от провайдера новый пул 198.18.99.0/24 и хотим публиковать наши внутренние сервисы под новыми IP-адресами. Для наглядности приведу схему с провайдером:



Добавим правило статического PAT для публикации TCP порта 3389 (RDP) компьютера из LAN под новым глобальным адресом 198.18.99.2:
ip nat inside source static tcp 192.168.20.5 3389 198.18.99.2 3389 extendable 

Если снова посмотреть ARP-таблицу маршрутизатора командой show arp, увидим, что статическая запись для IP-адреса 198.18.99.2 не добавилась.

Чтобы иметь возможность отправлять ARP-запросы в новую сеть 198.18.99.0/24 с компьютера Wireshark, расширим маску его сетевых настроек до 255.255.0.0 (/16). Напомню, для нашего примера компьютер Wireshark выступает в роли маршрутизатора Интернет-провайдера.

После ввода clear arp-cache сниффер по-прежнему показывает Gratuitous ARP только для трёх IP-адресов: 198.18.0.1, 198.18.0.2, 198.18.0.5. Для нового адреса 198.18.99.2 Gratuitous ARP не срабатывает. Попробуем открыть tcp-порт 3389 адреса 198.18.99.2 и одновременно посмотреть сниффер:





Неуспех. Проверим ARP-таблицу:



ARP-запись для нового IP-адреса 198.18.99.2 не появилась. Причина – новый IP-адрес 198.18.99.2 находится в IP-подсети, отличной от адреса интерфейса маршрутизатора. Как же нам заставить работать новый пул выданных провайдером IP-адресов? Есть четыре варианта:
  1. Попросить провайдера прописать статические ARP-записи для каждого IP-адреса из нового диапазона. Это не очень удобно, если выдаётся широкий диапазон как в нашем примере.
  2. Попросить провайдера прописать статический маршрут. Часто, чтобы выдать дополнительный диапазон белых IP-адресов, провайдер прописывает на интерфейсе своего оборудования secondary IP-адрес. Вместо этого мы можем попросить провайдера прописать статический маршрут к новой IP-подсети через IP-адрес внешнего интерфейса маршрутизатора. В этом случае оборудование провайдера будет знать, что новая подсеть доступна через IP-адрес интерфейса маршрутизатора, а маршрутизатор, в свою очередь, будет отвечать на ARP-запросы, отправленные к собственному интерфейсу.
  3. Прописать secondary IP-адрес из нового диапазона на внешнем интерфейсе маршрутизатора. В этом случае любой IP-адрес нового диапазона будет принадлежать той же подсети, что и IP-адрес (пусть и secondary) интерфейса маршрутизатора. Маршрутизатор автоматически добавит статические записи в свою ARP-таблицу, будет слать Gratuitous ARP и отвечать на ARP-запросы.
  4. Использовать механизм Proxy Arp на маршрутизаторе. На этом варианте остановимся чуть более подробно.

Proxy ARP на маршрутизаторах Cisco

Функциональность Proxy ARP позволяет маршрутизатору отвечать на ARP-запросы при выполнении трёх следующих условий:
  1. Целевой IP-адрес ARP-запроса находится в IP-подсети, отличной от IP-подсети, в которой ARP-запрос получен;
  2. Маршрутизатор имеет один или несколько маршрутов к целевому IP-адресу ARP-запроса;
  3. Маршруты к целевому IP-адресу ARP-запроса указывают на исходящий интерфейс, отличный от интерфейса, на который ARP-запрос был получен.

По умолчанию Proxy ARP включен на всех интерфейсах маршрутизатора. Однако использование механизма Proxy ARP имеет несколько недостатков. В первую очередь Proxy ARP вносит потенциальную уязвимость к атакам типа Man-in-the-middle, когда злоумышленник получит возможность перехватывать сетевой трафик. Поэтому, рекомендуется отключать Proxy ARP как минимум на интерфейсах, к которым подключены внешние сети.

Настройка Proxy ARP на интерфейсе маршрутизатора:
interface GigabitEthernet0/0/1.7
 ip proxy-arp

Отключить Proxy ARP на всех интерфейсах маршрутизатора можно глобально:
ip arp proxy disable

Данная настройка имеет приоритет над настройками Proxy ARP, применёнными на интерфейсах.
Помимо команды ip proxy arp в настройках интерфейса существует команда ip local-proxy-arp. Данная команда работает только когда ip proxy arp включён на интерфейсе и позволяет маршрутизатору отвечать на ARP-запросы, даже если целевой IP-адрес находится в той же IP-подсети, откуда ARP-запрос поступил. Пример настройки:
no ip arp proxy disable
interface GigabitEthernet0/0/1.7
 ip proxy-arp
 ip local-proxy-arp

Данная настройка может пригодится, если мы хотим, чтобы трафик в рамках одного широковещательного домена шёл через интерфейс нашего маршрутизатора. Данную задачу можно реализовать с использованием Protected port (PVLAN edge) настроек на L2-коммутаторе (switchport protected).

Включение Proxy ARP на внешнем интерфейсе маршрутизаторе позволит решить проблему с новым пулом адресов, выданных провайдером. Попробуем открыть tcp-порт 3389 адреса 198.18.99.2 после включения Proxy ARP на интерфейсе маршрутизатора и одновременно посмотреть сниффер:



Успех. Маршрутизатор отвечает на ARP-запрос и порт открывается. Таким образом, функциональность Proxy ARP также можно использовать при необходимости трансляции адресов в новый пул.

Итоги

Попробую тезисно обобщить основные моменты первой части статьи:
  1. Сетевое оборудование Cisco добавляет ARP-запись о новом удалённом устройстве в ARP-таблицу сразу по приходу ARP-запроса от удалённого устройства. Данное поведение позволяет сократить ARP-трафик в сети.
  2. Маршрутизатор Cisco будет отвечать на ARP-запросы к внутреннему глобальному IP-адресу правила NAT, если данный IP-адрес принадлежит той же IP-подсети, что и интерфейс маршрутизатора. Дополнительные настройки для работы ARP не требуются.
  3. Если внутренний глобальный IP-адрес правила NAT маршрутизатора не принадлежит IP-подсети интерфейса маршрутизатора, требуются дополнительные настройки. Существуют четыре варианта:
    1. Статические ARP-записи на внешнем оборудовании;
    2. Статический маршрут на внешнем оборудовании;
    3. Настройка secondary IP-адреса на интерфейсе маршрутизатора;
    4. Использование Proxy ARP.
      Первый и второй вариант подразумевают изменение настроек на «чужом» сетевом оборудовании и не всегда может быть приемлем.
      Третий вариант является наиболее предпочтительным.
      Четвёртый вариант может быть использован, но открывает уязвимость с точки зрения сетевой безопасности.
  4. Функциональность Proxy ARP включена на интерфейсах маршрутизатора по умолчанию. Рекомендуется отключать Proxy ARP как минимум на интерфейсах, подключаемых к Интернет-провайдерам.

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