9.2 Процесс получения IP-адреса по DHCP. DHCP-клиент и DHCP-сервер
Привет, посетитель сайта ZametkiNaPolyah.ru! Продолжаем изучать основы работы компьютерных сетей. Продолжаем разбираться с протоколом DHCP в рамках подготовки к CCNA. На этот раз мы посмотрим на процесс получения IP-адреса по DHCP, а также разберемся с тем как и при помощи каких сообщений происходит взаимодействие между DHCP-сервером и DHCP-клиентом.
Содержание статьи:
9.2.1 Введение
Протокол DHCP, как и любой порядочный протокол, очень просто включается на устройствах, но внутри происходят довольно интересные процессы, о которых нужно знать и которые необходимо понимать на тот случай, если где-то что-то сломается, чтобы это что-то быстро починить. Давайте рассмотрим процесс получения IP-адреса по DHCP, а заодно разберемся со структурой DHCP сообщений и поговорим про алгоритм взаимодействия между клиентом и сервером по DHCP.
9.2.2 Упрощенный алгоритм взаимодействия DHCP-сервера и DHCP-клиента.
Сразу скажу, что сейчас мы разберем упрощенный алгоритм взаимодействия между DHCP-сервером и клиентом, мы не будем рассматривать специфичные случаи, а прикинемся, что работаем в идеальной сети, где нет никаких конфликтов, дублирований и проблем. В дальнейшем этот алгоритм мы будем расширять.
Первое и важное условие нормальной работы DHCP-сервера заключается в том, что он должен находиться в одной подсети/канальной среде с клиентом, иначе ничего работать не будет. В дальнейшем мы убедимся, что это не всегда так и если сервер и клиент находятся в разных подсетях, то им необходим посредник, который называется DHCP Relay Agent. Ну а теперь перейдем к алгоритму взаимодействия между клиентом и сервером по DHCP.
- Как и в любой порядочной схеме клиент-сервер, взаимодействие по DHCP инициирует клиент. Когда клиент просыпается и осознает, что сетевые настройки нужно получить по DHCP, он формирует специальное широковещательное сообщение, называемое DHCPDISCOVER, этим сообщением он пытается найти DHCP-сервер в своей сети. Вы же помните, что широковещательные сообщения в протоколе Ethernet не выходят за пределы канальной среды?
- Если в канальной среде с клиентом находится сервер, то он получит DHCPDISCOVER, если сервера нет, то, возможно, это сообщение получит DHCP Relay Agent и перешлет его серверу, если нет и его, то клиент обломится.
- Но представим, что сервер есть и сообщение он получил. В ответ на DHCPDISCOVER сервер сформирует сообщение, называемое DHCP-предложением или на древнерусском DHCPOFFER. В сообщение DHCPOFFER содержится IP-адрес, который сервер хочет предложить клиенту и другая информация, которая может пригодиться. Сообщение DHCPOFFER может быть отправлено сервером как broadcast, так и unicast, ведь мак-адрес клиента сервер уже изучил. От чего это зависит мы увидим чуть позже.
- В нашей сети может быть несколько DHCP-серверов, и они все могут получить DHCPDISCOVER от клиента и направить ему DHCPOFFER. Естественно, клиент их все получит и обычно выберет первое неконфликтное предложение от одного единственного сервера. В ответ на выбранный DHCPOFFER клиент сформирует сообщение DHCPREQUEST, из которого будет понятно, с каким сервером он станет дальше дружить. DHCPREQUEST – широковещательное сообщение, это сделано специально, чтобы все сервера в сети видели, какие параметры выбрал клиент и с кем он дальше решил работать.
- Все серверы получают DHCPREQUEST, но только выбранный сервер продолжит взаимодействие с клиентом, на DHCPREQUEST сервер ответит сообщением DHCPACK, которое служит подтверждением или, если хотите, официальным разрешением от сервера на использование клиентом выбранного IP-адреса.
- Как только клиент получил сообщение DHCPACK, он переходит в рабочее состояние и смело пользуется IP-адресом.
Схема действительно очень упрощена, здесь мы даже не рассмотрели ситуацию, когда предложенный IP-адрес уже занят другим устройством или то, как проверяется занятость IP-адреса перед тем как он будет предложен клиенту, но об этом речь пойдет ниже. Сейчас же предлагаю посмотреть на схему обмена сообщениями DHCP в тот момент, когда клиент пытается получить IP-адрес от сервера.
На этой схеме показаны DHCP пакеты, которыми будут обмениваться устройство в тот момент, когда клиент пытается получить IP-адрес от сервера в первый раз, на схеме не показаны сообщения, которые могут возникать при различного рода конфликтах. В общем, это идеальный случай, его вы будете встречать чаще всего.
9.2.3 DHCP-клиент и DHCP-сервер, базовая настройка.
Теперь нам нужно закрепить полученные знания о взаимодействие между DHCP-сервером и DHCP-клиентом на практике, для этого мы расчехлим Cisco Packet Tracer и соберем простую схему, которая показана ниже.
Вокруг этой схемы мы и будем плясать, в центре схемы находится обычный L2 коммутатор, в его настройки мы не лезем, поэтому можно смело утверждать, что все устройства в нашей сети находятся в одной канальной среде. К коммутатору подключен роутер, который будет выпускать наших клиентов в Интернет, его мы безбожно обозвали основной шлюз (про разницу между хабами, коммутаторами и роутерами можно почитать здесь). Также на схеме есть два DHCP-сервера, которые уже подключены к коммутатору и три клиента, из которых пока подключен только один.
Перед началом настройки схемы не забудьте переключить Cisco Packet Tracer в режим симуляции. Роутеру и двум серверам нужно будет назначить статический IP-адрес, так как здесь адреса ни при каких сбоях не должны измениться, роутер для клиентов является основным шлюзом, а DHCP-сервера источником настроек. Клиент должен получать настройки динамически.
9.2.3.1 Настройка протокола DHCP на сервере и клиенте в Cisco Packet Tracer
Покажу настройку только одного DHCP-сервера, на втором настройки должны быть идентичны, за исключением IP-адреса. Для начала назначим серверу IP-адрес вручную, сам себе сервер выдавать IP-адреса не умеет.
Серверу я не стал давать адрес шлюза по умолчанию, так как серверу не нужен доступ в Интернет, где найти IP настройки для устройств в Cisco Packet Tracer, вы уже должны знать, показывал и не один раз. Следующим пунктом нашей программы будет настройка DHCP на сервере. Для этого перейдите на вкладку Services и в левом меню выберете DHCP.
Обратите внимание, здесь уже заполнены поля Start IP Address и Subnet Mask, мы же еще помним, что и клиент, и сервер должны находиться в одной канальной среде, чтобы было всё гуд. Когда мы назначили IP-адрес на интерфейс сервера, Cisco Packet Tracer сам назначил значения в эти поля за нас, если IP-адрес не назначать, то в этих полях будут унылые нули.
Предлагаю пока не трогать эти поля, а изменить значения у полей Pool Name и Default Gateway. Мои настройки показаны ниже.
Все изменения я выделил, для начала был включен DHCP при помощи чекбокса, затем я дал имя новому пулу IP-адресов, который сервер будет использовать для выдачи клиентам, а также была указана дополнительная опция в виде адреса шлюза по умолчанию. Чтобы пул был добавлен, следует нажать кнопку Add, после чего внизу у нас появится два пула IP-адресов: один – этот тот, что создали мы, второй – это тот, что был создан Cisco Packet Tracer автоматически. Чтобы не было проблем, удалите второй, для этого его нужно выделить и нажать на кнопку Remove, если не получится удалить автоматический пул, настройте его так, как я показал и удалите свой собственный. На втором сервере настройки нужно сделать аналогичными, разница будет только в IP-адресе, который вы назначите серверу.
Итак, что мы сделали, чтобы настроить DHCP-сервер, а сделали мы следующее:
- Настроили IP-адрес на интерфейсе сервера.
- Создали пул IP-адресов, из которого сервер будет выдавать настройки клиенту.
- Дали этому пулу имя, так как пулов у DHCP-сервера может быть несколько.
- Указали начальный IP-адрес пула (поле Start IP Address), это означает, что сервер будет пытаться выдавать IP-адреса, начиная с 192.168.0.1 (а не с 192.168.0.0, ведь сервер понимает, что это номер сети, а также он немного в курсе о том, что в 21 веке мы все используем маску подсети переменной длины, а про классовые сети мы все уже забыли).
- Также мы дали указание серверу выдавать две опции: маску подсети и IP-адрес шлюза по умолчанию.
Собственно, это всё, что нам сейчас необходимо. Сейчас мы сконфигурировали DHCP-сервер в режиме автоматической выдачи динамических IP-адресов, для нас этот режим самый интересный.
9.2.3.2 Настройки DHCP на клиенте
Настройка DHCP на клиенте гораздо проще, нужно только поставить галочку напротив «Получать IP-адрес по DHCP» и забыть про утомительный ручной труд.
Фразы «Гибкая настройка» и Cisco Packet Tracer плохо совместимы, в реальных операционных системах вы сможете задать: какие параметры рабочая станция должна получить по DHCP, а какие параметры вы можете ввести своими руками. Но это нам сейчас не интересно, нам важно разобраться с тем, как клиент получает IP-адрес от DHCP сервера и это мы сделаем. Настройка протокола DHCP на клиенте на этом закончена.
9.2.4 Как клиент получает IP-адрес по DHCP
Схема собрана и настроена, теперь нам надо понять, как клиент получает IP-адрес по DHCP от сервера. В тот момент, когда вы завершите настройку DHCP на клиенте, машина поймет, что она не имеет IP-адрес, а также увидеть указание о том, что она должна получить этот IP-адрес по DHCP. Поэтому первое, что сделает DHCP-клиент – это сформирует запрос DHCPDISCOVER, которым попытается найти сервер.
На зеленый пакет, сформированный сервером, не обращайте внимание. Нас интересует желтый пакет, который сформировал клиент, это и есть DHCPDISCOVER, давайте на него посмотрим.
Здесь сразу видно, что пртокол DHCP работает на прикладном уровне моделей OSI 7 и TCP/IP. Также тут видно, что клиент еще не разу не получал IP-адрес от сервера и даже не знает, где этот сервер находится. На транспортном уровне протокол DHCP инкапсулируется в UDP дейтаграммы, когда клиент делает запрос серверу, то в качестве порта источника он выбирает 68 порт, а в качестве порта назначения используется 67 порт.
Клиент не знает IP-адрес сервера, да и своего у него еще нет, поэтому на сетевом уровне в качестве IP-адреса источника он использует IP-адрес 0.0.0.0, а в качестве IP-адреса назначения используется 255.255.255.255. Мы видим, что это широковещательный запрос.
На канальном уровне клиент указывает свой мак-адрес в качестве источника и широковещательный мак-адрес в качестве назначения. Ниже показана структура пакета DHCPDISCOVER, но с ней мы будем разбираться на примере дампа Wireshark.
А сейчас продолжим разбираться и посмотрим, что будет, когда запрос DHCPDISCOVER дойдет до серверов.
Здесь мы видим, что DHCPDISCOVER, посланный клиентом, дошел до всех участников канальной среды, что и не мудрено, ведь он широковещательный, но этот запрос оказался интересным только двум нашим DHCP-серверам. Когда сервер получил DHCPDISCOVER он понял, что в сети появился клиент, которому нужно выдать IP-адрес, сервер смотрит на пул IP-адресов, который у него есть и ищет свободный адрес, обычно это процесс упорядоченный и клиенту будет выдан первый свободный адрес из пула.
Но тут всё не так просто, дело в том, что компьютерная сеть – это то место, где изменения происходят очень быстро, поэтому прежде чем сформировать DHCPOFFER, сервер должен убедиться, что в сети еще не появился какой-нибудь негодяй, который уже начал использовать IP-адрес, который сервер решил выдать этому клиенту, а может случиться так, что другой сервер выдал выбранный адрес клиенту чуть раньше, это надо проверить.
Поскольку у нас канальная среда Ethernet, то для проверки будет идеальным протокол ARP, он позволяет опросить все устройства в канальной среде. Вы же знаете, что при помощи ARP-запроса машины узнают мак-адреса по известному IP-адресу. И дело тут в том, что серверу известен IP-адрес, который он хочет выдать клиенту, он его и использует в ARP-запросе и кричит на всю канальную среду: кто использует IP-адрес такой-то?
ARP-запрос – это зеленый пакет, на котором нет значка паузы. Наши сервера настроены одинаково, базы данных у них сейчас одинаковые, поэтому и ARP-запросы они делают одинаковые, сам запрос показан ниже.
Тут мы видим, что наш первый сервер спрашивает всех соседей по канальной среде: у кого IP-адрес 192.168.0.1, я сервер с IP-адресом 192.168.0.2? Но, как мы помним, адрес 192.168.0.1 мы настроили на роутере, он уже занят. И ничего страшного, что этот адрес занят нашим маршрутизатором, маршрутизатор получит ARP-запрос и любезно на него ответит своим ARP-ответом, получив ответ, наши сервера поймут, что адрес 192.168.0.1 занят и нужно искать следующий адрес для выдачи.
В зависимости от реализации, после ARP-запроса, сервер может еще попробовать и попинговать IP-адрес 192.168.0.1, чтобы окончательно убедиться в том, что он занят. Такие проверки будут продолжаться до тех пор, пока DHCP-сервера не доберутся до IP-адрес 192.168.0.4 в своем пуле, ведь это первый адрес, который еще не используется в нашей сети, для этого адреса будет сформирован ARP-запрос, на который никто не ответит.
Тут опять же, всё зависит от конкретного DHCP-сервера, ARP-запрос может быть повторен, а после него сервер может еще и попробовать опросить адрес по ICMP, все это нужно, чтобы убедиться, что адрес еще никто не занял, а только после этого формировать сообщение DHCPOFFER.
На рисунке показано ниже, что сообщение DHCPOFFER широковещательное, хотя это бывает и не всегда так, тут учитывается два момента:
- Клиент может сообщить DHCP-серверу о том, как он хочет получать ответ: broadcast или unicast.
- Выбор способа доставки сообщения DHCPOFFER может зависеть от реализации самого сервера и некоторых значений в DHCP пакете.
В любом случае, для доставки DHCPOFFER у сервера есть возможность использовать на канальном уровне как broadcast, так и unicast, ведь мак-адрес клиента он уже изучил, когда получил сообщение DHCPDISCOVER. На рисунке показано, что клиент получил DHCPOFFER от первого сервера. DHCPOFFER второго сервера находится еще в буфере коммутатора, оба сервера предлагают клиенту адрес 192.168.0.4.
Рисунок выше показывает, что при первом получении IP-адреса по DHCP в своем пакете сервер указывает свой IP-адрес, а в качестве адреса клиента используется 0.0.0.0. Поскольку это сообщение сформировано сервером, то порт источника 67, а порт назначения 68. Если сейчас заглянуть во внутренности пакета DHCPOFFER, то без всяких пояснений можно увидеть несколько интересных моментов.
Во-первых, сервер понимает, что у клиента еще нет IP-адреса, понимает сервер это потому, что в его базе данных еще нет мак-адреса клиента и нет сопоставления этого мак-адреса с IP-адресом, который был выдан. Во-вторых, мы видим, что сервер предлагает клиенту получить IP-адрес 192.168.0.4. В-третьих, в пакете DHCPOFFER сервер указывает свой IP-адрес, чтобы клиент знал, кто ему это всё предложил.
Получив DHCPOFFER клиент не забирает себе IP-адрес, сперва он должен убедиться, что этот адрес еще никто не использует, для этого он делает ARP-запрос в сеть, в данном случае ему был предложен адрес 192.168.0.4, значит и спрашивать клиент будет: кто в сети использует адрес 192.168.0.4? Клиенты не используют ICMP для проверки, им это не надо, а вот серверам надо, в дальнейшем мы поймем – в каких ситуациях это действительно необходимо.
Если клиент не получит ARP-ответ на свой запрос, то он может смело соглашаться на предложение DHCP-сервера, при этом соглашаться он будет на предложение того сервера, от которого был получен первый DHCPOFFER. Если клиент получит ARP-ответ на свой запрос, то он отправит серверу сообщение DHCPDECLINE, в котором сообщит о том, что он отказывается от его предложения, если же ARP-ответа не будет, то клиент сформирует широковещательное сообщение DHCPREQUEST и отправит его. Таким образом все сервера поймут две вещи:
- С каким сервером клиент захотел работать.
- На какой IP-адрес клиент согласился.
В процессе написания я столкнулся с еще одной странностью в Cisco Packet Tracer: после ARP-запроса клиент получил IP-адрес и на этом всё закончилось. Поэтому дальше только словесное описание, а потом мы его дополним дампами из Wireshark.
DHCP сервер, с которым клиент решил сотрудничать, тоже получит DHCPREQUEST и на этот REQUEST сервер должен будет выслать подтверждение в виде DHCPACK. Так сервер сообщает клиенту: пользуйся адресом на здоровье, я внес в свою базу данных информацию о том, что IP-адрес 192.168.0.4 закреплен за тобой. Сообщение DHCPACK может быть отправлено как адресно, так и широковещательно, чаще всего оно отправляется адресно.
Если в командной строке клиента сейчас выполнить команду ipconfig, то можно будет увидеть настройки, которые клиент получил от сервера.
[php]
C:\>ipconfig
FastEthernet0 Connection:(default port)
Link-local IPv6 Address.........: FE80::202:17FF:FE54:C07B
IP Address......................: 192.168.0.4
Subnet Mask.....................: 255.255.255.0
Default Gateway.................: 192.168.0.1
[/php]
Чтобы окончательно убедиться в том, что все работает, можете попробовать пропинговать адрес шлюза по умолчанию.
[php]
C:\>ping 192.168.0.1
Pinging 192.168.0.1 with 32 bytes of data:
Reply from 192.168.0.1: bytes=32 time=1ms TTL=255
Reply from 192.168.0.1: bytes=32 time<1ms TTL=255
Reply from 192.168.0.1: bytes=32 time<1ms TTL=255
Reply from 192.168.0.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.0.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms
[/php]
Итак, у нас всё хорошо, клиент получил IP-адрес и ряд опций от DHCP-сервера и стал полноценным участником нашей компьютерной сети. Мы пробежались по общему принципу получения IP-адреса по DHCP, далее мы рассмотрим этот процесс изнутри. Для детального разбора я буду использовать свой компьютер, роутер и Wireshark. Компьютер получает IP-адрес от роутера по DHCP, то есть роутер выполняет роль DHCP-сервера.
9.2.5 Выводы
Итак, мы рассмотрели базовый принцип работы протокола DHCP, разобрались с тем, как клиент получает IP-адрес по DHCP и сформировали для себя схему взаимодействия между DHCP-клиентом и DHCP-сервером. Конечно, сейчас мы не разобрали случаи с проблема, например, ситуацию, при которой во время получения IP-адреса клиент или сервер обнаруживают, что этот адрес уже занят, такие ситуации мы рассмотрим позже, когда будем превращать маршрутизатор Cisco в DHCP-сервер.
Спасибо за очень полезную статью.
Но вот тут не понятно немного:
«Поскольку это сообщение сформировано сервером, то порт источника 68, а порт назначения 67.»
А разве не с 67 порта сервер должен отвечать на 68, так как 68 это же порт клиента?
Да, вы правы, порт 67 использует сервер, 68 клиент. Поправил в записи.