Привет 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-ответ от маршрутизатора.
Из представленного дапма видно, что сперва маршрутизатор отправляет 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 вопросов нет. В случае трансляции в адрес, отличный от адреса интерфейса, действуют следующие правила:
- Если внутренний глобальный адрес находится в той же IP-подсети, что и адрес интерфейса маршрутизатора, маршрутизатор будет отвечать на ARP-запросы к этому адресу. При этом в собственной arp-таблице маршрутизатора создаётся статическая запись для внутреннего глобального адреса.
- Если внутренний глобальный адрес находится в 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-адресов? Есть четыре варианта:
- Попросить провайдера прописать статические ARP-записи для каждого IP-адреса из нового диапазона. Это не очень удобно, если выдаётся широкий диапазон как в нашем примере.
- Попросить провайдера прописать статический маршрут. Часто, чтобы выдать дополнительный диапазон белых IP-адресов, провайдер прописывает на интерфейсе своего оборудования secondary IP-адрес. Вместо этого мы можем попросить провайдера прописать статический маршрут к новой IP-подсети через IP-адрес внешнего интерфейса маршрутизатора. В этом случае оборудование провайдера будет знать, что новая подсеть доступна через IP-адрес интерфейса маршрутизатора, а маршрутизатор, в свою очередь, будет отвечать на ARP-запросы, отправленные к собственному интерфейсу.
- Прописать secondary IP-адрес из нового диапазона на внешнем интерфейсе маршрутизатора. В этом случае любой IP-адрес нового диапазона будет принадлежать той же подсети, что и IP-адрес (пусть и secondary) интерфейса маршрутизатора. Маршрутизатор автоматически добавит статические записи в свою ARP-таблицу, будет слать Gratuitous ARP и отвечать на ARP-запросы.
- Использовать механизм Proxy Arp на маршрутизаторе. На этом варианте остановимся чуть более подробно.
Proxy ARP на маршрутизаторах Cisco
Функциональность Proxy ARP позволяет маршрутизатору отвечать на ARP-запросы при выполнении трёх следующих условий:
- Целевой IP-адрес ARP-запроса находится в IP-подсети, отличной от IP-подсети, в которой ARP-запрос получен;
- Маршрутизатор имеет один или несколько маршрутов к целевому IP-адресу ARP-запроса;
- Маршруты к целевому 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 также можно использовать при необходимости трансляции адресов в новый пул.
Итоги
Попробую тезисно обобщить основные моменты первой части статьи:
- Сетевое оборудование Cisco добавляет ARP-запись о новом удалённом устройстве в ARP-таблицу сразу по приходу ARP-запроса от удалённого устройства. Данное поведение позволяет сократить ARP-трафик в сети.
- Маршрутизатор Cisco будет отвечать на ARP-запросы к внутреннему глобальному IP-адресу правила NAT, если данный IP-адрес принадлежит той же IP-подсети, что и интерфейс маршрутизатора. Дополнительные настройки для работы ARP не требуются.
- Если внутренний глобальный IP-адрес правила NAT маршрутизатора не принадлежит IP-подсети интерфейса маршрутизатора, требуются дополнительные настройки. Существуют четыре варианта:
- Статические ARP-записи на внешнем оборудовании;
- Статический маршрут на внешнем оборудовании;
- Настройка secondary IP-адреса на интерфейсе маршрутизатора;
- Использование Proxy ARP.
Первый и второй вариант подразумевают изменение настроек на «чужом» сетевом оборудовании и не всегда может быть приемлем.
Третий вариант является наиболее предпочтительным.
Четвёртый вариант может быть использован, но открывает уязвимость с точки зрения сетевой безопасности.
- Статические ARP-записи на внешнем оборудовании;
- Функциональность Proxy ARP включена на интерфейсах маршрутизатора по умолчанию. Рекомендуется отключать Proxy ARP как минимум на интерфейсах, подключаемых к Интернет-провайдерам.