Вопрос из заголовка порой вводит в тупик даже коллег, имеющих сертификаты уровня CCNA. Давайте рассмотрим, как выглядят фреймы (кадры) на каждом этапе передачи от клиента коммутатору, роутеру, межсетевому экрану и серверу и какие поля при этом в них меняются.
Буду исходить из того, что читатель знаком с базовым курсом TCP/IP, и касаться только нужных для статьи моментов.
Как введение рекомендую прочитать статью "Путешествие картинки сакуры от Японии до России через TCP/IP. Фреймы, сегменты, пакеты, файлы: анатомия сетевой передачи"
Проведем эксперимент
Давайте подключимся браузером от клиента к веб-серверу и посмотрим на IP- и MAC-адреса источника и получателя во всех фреймах в каждом канале (на картинке ниже). Самый простой способ увидеть это самим — подключить в каждый канал сниффер.
Предлагаю внимательно посмотреть на схему подключения сетевого оборудования ниже:
![Схема подключения клиента к серверу через промежуточное оборудования с IP и MAC адресами. Схема подключения клиента к серверу через промежуточное оборудования с IP и MAC адресами.](https://habrastorage.org/getpro/habr/upload_files/22f/8d0/9d9/22f8d09d955acf0d675861d456257ef0.png)
Клиент с IP адресом 10.1.1.11/24 и MAC адресом 0000.0001.1111 подключается к серверу с IP адресом 10.1.3.33/24 и MAC адресом 0000.0008.8888. Маска /24 (255.255.255.0) выбрана для примера.
Стуктура фреймов Ethernet при передаче по сети
Напомню как выглядит структура фрейма (кадра) Ethernet при передаче в сеть: все заголовки и данные вышестоящих протоколов стека TCP/IP объединяются в единый блок данных для передачи. Ваши файлы, голос и видео в виде нарезанных кусочков перемещаются в поле Payload. Подробнее тут. Внутри Ethernet заголовка находятся MAC адреса источника и получателя, и внутри IP заголовка находятся IP адреса источника и получателя. Эта структура данных в наших сетях используется коммутаторами и маршрутизаторами для передачи фреймов друг другу. Например, ниже внутри фрейма отображены заголовки IP протокола 4 версии и TCP протокола (могут быть помещены и другие протоколы, например ICMP или UDP):
![Пример фрейма (кадра) Ethernet Ethernet MTU – максимальный размер фрейма для данной среды передачи. Обычно 1500 байт. TCP MSS – максимальный размер сегмента данных TCP. Обычно MSS = MTU-40 = 1460 В сумме длина фрейма 1518 байт. Пример фрейма (кадра) Ethernet Ethernet MTU – максимальный размер фрейма для данной среды передачи. Обычно 1500 байт. TCP MSS – максимальный размер сегмента данных TCP. Обычно MSS = MTU-40 = 1460 В сумме длина фрейма 1518 байт.](https://habrastorage.org/r/w1560/getpro/habr/upload_files/b75/e2a/e95/b75e2ae95ec4b3ed0c05bd42eb5dc0e5.png)
Хорошая визуализация схемы передачи фреймов (кадров) по сети есть статье Артема Санникова, вот демонстрация как производится пересылка фрейма через коммутатор:
![Интересно, что в заголовке фрейма первым идет адрес назначения, а в IP заголовке первым идет адрес источника. Интересно, что в заголовке фрейма первым идет адрес назначения, а в IP заголовке первым идет адрес источника.](https://habrastorage.org/getpro/habr/upload_files/118/d78/099/118d780998ff5048db7027142e2daec0.gif)
Изучим первый фрейм, между клиентом и свитчом.
Итак, какими будут Source IP и Source MAC, Destination IP и Destination MAC в первом фрейме от клиентского компьютера? Попробуйте написать эти адреса во фреймах сами: просмотрите названия полей заголовков на рисунке ниже, запишите ваши ответы и только затем читайте дальше. Проверьте себя.
Source MAC Address = ???
Destination MAC Address = ???
Source IP Address = ???
Destination IP Address = ???
Попробуйте написать эти адреса во фреймах сами: просмотрите названия полей заголовков на рисунке ниже, запишите ваши ответы и только затем читайте дальше. Проверьте себя.
Лучше сначала заполнить самому
Если вы преподаватель, то дайте такое задание своим студентам: попросите их заполнить все эти карточки на картинке ниже.
![Заполните сами данные поля заголовков фреймов перед тем как продолжить читать ответы Заполните сами данные поля заголовков фреймов перед тем как продолжить читать ответы](https://habrastorage.org/getpro/habr/upload_files/989/490/466/989490466d672f1a5aa66c83bc0c984d.png)
Будем исходить из того, что клиент и сервер уже передавали друг другу данные, и поэтому все нужные ARP-таблицы и таблицы маршрутизации настроены на всем пути от клиента к серверу. У клиента маршрутизатором по умолчанию является 10.1.1.1/24. Соответственно, MAC-адрес у этого IP-адреса уже был запрошен в одном из ранее отправленных ARP-запросов, и в ARP-таблице клиента есть информация о MAC-адресе для IP-адреса 10.1.1.1. Маска сети везде /24.
Заполняем первый фрейм данными IP- и MAC-адресов.
![Фрейм от клиента Src MAC - MAC-адрес отправителя Dst MAC - MAC-адрес получателя Src IP - IP-адрес отправителя Dst IP - IP-адрес получателя Фрейм от клиента Src MAC - MAC-адрес отправителя Dst MAC - MAC-адрес получателя Src IP - IP-адрес отправителя Dst IP - IP-адрес получателя](https://habrastorage.org/getpro/habr/upload_files/f5e/343/a73/f5e343a73ec02cde3b925069f91d999d.png)
Полагаю, что вы понимаете, какие во фрейме от клиента будут IP-адреса источника и получателя, — ведь они даны в условии задачи: мы хотим отправить данные с IP-адреса 10.1.1.11 на IP-адрес 10.1.3.33. Поэтому эти адреса вписываем в IP-заголовок.
Я встречал студентов, которые вписывали в поле с IP-адресом получателя IP-адрес следующего маршрутизатора (в примере — 10.1.1.1): это ошибка. Всегда во фреймах при движении по сетям в поле IP-заголовка будут только IP-адреса источника и получателя.
Если вы отправите другой адрес, то маршрутизатору будет недоступен настоящий адрес получателя и в таблице маршрутизации не будет информации о том, куда направлять пакеты.
Если вы напишете другой IP-адрес источника, то маршрутизатор не определит, куда возвращать ошибки доставки пакетов.
При этом IP-адреса во фреймах могут меняться, если по пути движения кадров появится устройство с включенным Source NAT или Destination NAT. Но в нашей задаче такое устройство, выполняющее трансляцию адресов, не указано.
Кроме того, легко понять, каким будет MAC-адрес отправителя: это MAC-адрес клиента — 0000.0001.1111.
Какой MAC-адрес получателя написать
Поскольку это самая важная часть текста, я выделил ее в отдельную главу.
![Какой MAC-адрес получателя написать во фрейме, исходящем с интерфейса Client Какой MAC-адрес получателя написать во фрейме, исходящем с интерфейса Client](https://habrastorage.org/getpro/habr/upload_files/73c/af7/3bd/73caf73bdf44490984453602cf29c938.png)
Иногда люди думают, что им будет MAC-адрес сервера, а именно 0000.00008.8888. Если вы создадите такой фрейм и отправите его с интерфейса компьютера клиента в сторону свитча, то кадр реально попадет в широковещательный домен, доступный через коммутатор (в левой части картинки). Коммутатор получит этот фрейм, проверит по своей таблице MAC-адресов, что такого адреса в ней нет, и отправит кадр сразу на все свои порты. В итоге он дойдет до роутера (в левой части картинки сверху), на котором MAC-адрес другой (0000.0003.3333), и роутер просто отбросит этот фрейм, потому что он пришел не по адресу. Такой кадр просто не достигнет сервера.
MAC-адресом получателя также не может быть MAC-адрес свитча. Когда свитч получит фрейм, то определит, что кадр отправлен именно ему, и, скорее всего, просто «убьет» его (зависит от производителя устройства), ведь фрейм уже дошел и непонятно, что с ним делать. И еще мне интересно: как вы на компьютере Client узнаете MAC-адрес коммутатора? Ведь устройство никаким образом не сообщает его подключенным клиентам.
Правильный ответ
Нужно указывать MAC-адрес роутера, который является вашим маршрутизатором по умолчанию. IP-адрес маршрутизатора задается в таблице маршрутизации при настройке компьютера или может быть получен от DHCP-сервера. С компьютера Client заранее сделан ARP-запрос, благодаря которому мы узнаем MAC-адрес, соответствующий IP-адресу роутера. Именно его и надо подставлять в поле Destination MAC address.
![](https://habrastorage.org/getpro/habr/upload_files/61b/eb7/a68/61beb7a685d9ac63da0f78d086770202.png)
В результате этот фрейм от клиента попадает на свитч. Ключевым здесь является то, что коммутатор не меняет ни MAC-адреса, ни IP-адреса. При этом свитч хранит таблицу с описанием того, на каком интерфейсе какие MAC-адреса подключены, и определяет интерфейс, на котором находится нужный нам следующий маршрутизатор 0000.0003.3333. От коммутатора фрейм отправляется на маршрутизатор (неизмененным), где благополучно принимается, ведь получатель указал правильный MAC-адрес.
Я специально нарисовал на схеме коммутатор, потому что хотел сообщить читателям важную информацию: ни MAC-адреса, ни IP-адреса в заголовках фреймов на свитчах не меняются. Кроме того, важно заметить, что адрес коммутатора не надо указывать в поле Destination MAC address.
Иногда студенты спрашивают: почему на картинке не указан MAC-адрес интерфейса верхнего коммутатора слева? И вы уже знаете ответ: потому что это неважно. В поле Source MAC address будет указан MAC-адрес интерфейса клиентского компьютера, а не интерфейса коммутатора: коммутатор не меняет ни Destination MAC address, ни Source MAC address в заголовках фреймов. Три раза повторил, да? :)
Решение задачи
Окончательная картинка будет выглядеть следующим образом: IP-адреса в заголовке внутри фрейма всегда одинаковые, а вот MAC-адреса меняются на MAC-адреса всех интерфейсов, имеющих IP-адрес. Именно так работает сеть на основе Ethernet. По пути между маршрутизаторами могут быть и другие порты: серийные, frame relay, ATM. Нужно понимать, что MAC-адрес применим только к протоколу Ethernet. Протоколы канального уровня используют разные схемы адресации: например, frame relay использует номер DLCI, а протокол ATM — VPI или VCI. Сегодня мы говорим только про Ethernet.
В настоящей сети вы можете посмотреть все фреймы сниффером, подключившись к SPAN-порту любого из устройств, или воспользоваться TAP-устройствами или даже сетевыми брокерами. Если это виртуализация, то используйте vTAP или vBroker.
![Схема передачи фреймов по сети от клиента серверу. Синим помечены адреса клиента, красным — адреса сервера Схема передачи фреймов по сети от клиента серверу. Синим помечены адреса клиента, красным — адреса сервера](https://habrastorage.org/getpro/habr/upload_files/932/7d3/129/9327d31299c271eb19894f1c6271cafd.png)
А что будет, если я добавлю в эту сеть NGFW
Давайте поместим в схему NGFW, который защищает подключения от клиентов к серверу. Нужно понимать, что NGFW будет являться маршрутизатором для сети. На его интерфейсах есть IP-адреса и MAC-адреса, и тогда схема прохождения фреймов аналогична схеме с роутером..
![Схема передачи фреймов в сети с NGFW с включенной маршрутизацией Схема передачи фреймов в сети с NGFW с включенной маршрутизацией](https://habrastorage.org/getpro/habr/upload_files/8f1/f42/fc1/8f1f42fc171e26139da127b4cb8ad138.png)
Меня озадачивают запросы коллег-безопасников установить им межсетевой экран с правилами на проверку MAC-адресов источника и получателя с помощью NGFW. Откуда NGFW будет узнавать MAC адреса в сети с роутерами? Внимательно посмотрите на картинку: NGFW видит только MAC-адреса ближайших роутеров. Вы никогда не сможете получить фрейм с MAC-адресом клиента или сервера, поскольку роутеры перезаписывают MAC-адреса по пути, да, собственно и сам NGFW тоже. Проверки по MAC-адресам сделать можно, но в поле будет либо any, либо MAC-адрес вашего роутера или роутера провайдера.
А что, если я хочу фильтрующий мост
Если изменить картинку выше и подключить NGFW не как роутер (устройство layer 3), а как коммутатор (устройство layer 2) или как виртуальную линию (устройство layer 1), то NGFW на самом деле будет фильтрующим мостом согласно типовой классификации межсетевых экранов. И мы все равно понимаем, что фильтровать можно будет только устройства, которые подключены к NGFW или напрямую, или через коммутатор. Такое в принципе бывает в SCADA-сетях, но в интернете все устройства L3, и по MAC-адресам их фильтровать не получится. В сети SCADA логичнее сделать VLAN insertion, разделить один broadcast domain на несколько разных VLAN и заменить теги VLAN на самом NGFW. Пример описан в моей видеолекции на YouTube.
![Схема передачи фреймов в сети с межсетевым экраном L2 (прозрачным для L3) Схема передачи фреймов в сети с межсетевым экраном L2 (прозрачным для L3)](https://habrastorage.org/getpro/habr/upload_files/aeb/925/712/aeb925712a696a169a1cc4163bd08178.png)
Выводы
Мне бы хотелось, чтобы теперь все знали, что:
При перемещении IP-пакетов по сети MAC-адреса коммутаторов не подставляются во фреймы Ethernet.
При перемещении IP-пакетов по сети каждый маршрутизатор подставляет свои MAC-адреса, и наши снифферы или анализаторы трафика (например, системы NTA) определяют MAC-адрес ближайшего маршрутизатора, а не реального узла.
Нет смысла в фильтрации по MAC-адресам. Она нужна только для одной локальной сети или одного широковещательного домена.
Еще будут меняться поле TTL и контрольные суммы, но это нужно обсуждать отдельно.
Update 08.02.2023. Записал видео по этой же теме: