В следующих нескольких статьях я буду разбирать протокол DHCP: как он работает и как настроить DHCP-клиент и DHCP-сервер, используя FreeBSD. Если вы имеете постоянное подключение компьютера к сети, вы, вероятно, слышали о DHCP (Dynamic Host Configuration Protocol). Как видно из имени, данный протокол разрабатывался для динамического конфигурирования узлов, и вместе с TCP/IP информацией он необходим для организации сообщения в сети. Альтернативой динамической адресации является статическая. Статическая адресация - это когда вы жестко указываете IP-адрес, маску подсети и шлюз, используемый по умолчанию. FreeBSD поддерживает как статическую, так и динамическую адресацию. Как правило, вы применяете статическую адресацию для построения небольшой домашней сети и динамическую - когда подключаетесь к Internet.
Получаем сведения о ваших интерфейсах
Прежде чем использовать какуй либо тип адресации, не помешает узнать имена интерфейсов FreeBSD для ваших сетевых карт. Для этого используйте команду ifconfig примерно так:
% ifconfig -a
rl0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
ether 00:05:5d:d2:19:b7
media: Ethernet autoselect
ed0: flags=8843<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
ether 00:50:ba:de:36:33
media: Ethernet autoselect
lp0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> mtu 1500
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet 127.0.0.1 netmask 0xff000000
Команда ifconfig выводит сведения как о физических, так и о виртуальных устройствах. вы можете распознать карты Ethernet по наличию "ether" или, как его еще называют, MAC адреса. В FreeBSD имена сетевых адаптеров состоят из 2 или 3 символов, за которыми следует номер. В данном примере присутствует два Ethernet устройства: одно названо rl0, а другое ed0. Также представлено два псевдоустройства, lp0 и lo0. вы можете распознать 127.0.0.1 как "адрес loopback", это означает что lo0 - это имя псевдоустройства loopback.
Многие интерфейсы имеют точки входа в секцию 4 страниц руководства. В моем случае, я могу вызвать man 4 rl, man 4 ed, man 4 lp, и man 4 lo для получения дополнительной информации о каждом интерфейсе. Замечу, что вы не включаете число в описание имени интерфейса, когда вызываете функцию man. Вместо этого, номер интерфейса указывает на то, как много устройств данного типа установлено; счет ведется с 0. Например, если вы имеете 2 сетевые карты realtek, они будут названы rl0 и rl1. (Это читается как "эр-эль", а не "эр-один").
Статическая адресация
Для установки статического IP адреса и маски подсети, необходимо зарегестрироваться в качестве суперпользователя и использовать команду ifconfig следующим образом:
% ifconfig rl0 192.168.10.1 255.255.255.0
Когда вы выполняете данную команду, не забудьте указать имя устройства, существующего в вашей системе, или вы получите сообщение об ошибке. Чтобы увидеть, что ваша команда завершилась удачно, вызовите команду ifconfig, ограничив ее вывод информацией об отдельно взятом устройстве, это удобнее, чем использовать параметр a и видеть информацию о всех устройствах:
% ifconfig rl0
rl0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
inet 192.168.10.1 netmask 0xffffff00 broadcast 255.255.255.0
ether 00:05:5d:d2:19:b7
Если необходимо также указать используемый по умолчанию шлюз, используйте команду route:
# route add default 192.168.10.25
Чтобы увериться в принятии изменений:
% netstat -rn |grep G
DestinationGatewayFlagsRefsUseNetifExpire
default192.168.10.25UGSc50rl0
192.168.10.1127.0.0.1UGHS02lo0
вы заметили, что я использовала grep чтобы найти в таблице роутинга флаг G, то есть флаг шлюза. Другой флаг, заслуживающий упоминания - это U, он показывает, что шлюз в рабочем состоянии. Неплохая вешь для шлюза, не так ли?
В данный момент машина настроена, но изменения не сохранятся при перезагрузке. Не слишком удобно вводить эту статическую информацию каждый раз после перезагрузки. К счастью, вы можете сказать FreeBSD восстанавливать эту информацию, включив ее в сценарии запуска. На данной машине я включила следующие строки в файл /etc/rc.conf:
ifconfig_rl0="inet 192.168.10.1 netmask 255.255.255.0"
defaultrouter="192.168.10.25"
Внося изменения в этот файл, будьте осторожны, прежды чем сделать запись, требуется закоменнтировать правильный вариант. Чтобы проверить ваши изменения, дайте следующую команду, она не должна выдавать какие-либо ошибки:
% /etc/netstart
Динамическая адресация
Не большой труд отредактировать несколько файлов, если у вас только одна машина или небольшая сеть с несколькими компьютерами. Однако если вы администратор большой сети, более подходящим является использование DHCP - по двум причинам. Во-первых, по мере того, как увеличивается количество файлов, отредактированных вами, возрастает возможность ошибочного присвоения двум машинам одного IP адреса. Во-вторых, чем больше компьютеров вы имеете, тем более это неудобно, так как вы должны сесть за каждый компьютер и внести информацию о его IP адресе вручную.
Если ваша система подключена к сети, которая использует DHCP - к Интернет, например - вы можете воспользоваться DHCP-клиентом, встроенным в FreeBSD. В моем примере, ко второй сетевой карте (ed0) подключен кабельный модем. Для получения IP адреса от моего DHCP-сервера, я могу испольозовать следующую команду:
% dhclient ed0
А чтобы проверить работает ли это:
% ifconfig ed0
ed0: flags=8843<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
inet 2.2.2.2 netmask 0xffffff00 broadcast 255.255.255.255
ether 00:50:ba:de:36:33
Для настройки этой системы на постоянное использование динамической адресации, я могу добавить следующую строку к файлу/etc/rc.conf:
ifconfig_ed0="DHCP"
Если вы собираетесь настраивать dhclient или создавать свой собственный DHCP-сервер для использования в вашей сети, вам необходимо знать основы терминологии DHCP.
Когда DHCP-клиент получает сведения о конфигурации от DHCP-сервера, он получает их как бы "в аренду". Это означает, что конфигурация клиента остается в силе в течение ограниченного периода времени, длина которого определяется DHCP-сервером. Информация, содержащаяся в "сообщении - аренде", также зависит от сервера. DHCP-сервер может дать гораздо больше информации, чем просто IP адресс, маску подсети и шлюз по умолчанию. Он также может информировать клиента о IP адресах серверов сети следующих типов:
cookie серверы;
серверы DNS;
finger серверы;
серверы шрифтов;
impress серверы;
IRC серверы;
log серверы;
серверы печати;
NDS серверы;
WINS серверы;
NIS серверы;
NIS+ серверы;
NNTP серверы;
NTP серверы;
POP серверы;
resource location серверы;
SMTP серверы;
streettalks серверы;
swap серверы;
серверы имен TFTP;
time серверы;
uap серверы;
www серверы.
Уау, это большинство серверов. Кроме того, DHCP может также присвоить клиенту MTU, TTL, символьное имя и добрую дюжину других параметров. Весь список огласит вывод команды man dhcp-options.
Раз DHCP-клиент получил "аренду", он сохраняет ее в /var/db/dhclient.leases. Вот пример этого файла:
lease { interface "ed0";
fixed-address 2.2.2.2;
option subnet-mask 255.255.240.0;
option routers 2.2.2.1;
option domain-name-servers 2.2.2.94,2.2.2.93,2.2.2.46;
option broadcast-address 255.255.255.255;
option dhcp-server-identifier 2.2.2.21;
option host-name "thishost";
option domain-name "thisdomain.com";
renew 3 2003/4/2 00:22:38;
rebind 6 2003/4/5 02:50:06;
expire 6 2003/4/5 23:50:06; }
Если вы запускали dhclient на некоторое время, вы заметите, что ваш файл "аренды" содержит много таких секций, которые начинаются с lease { и завершаются фигурной закрывающей скобкой }. Информация между фигурными скобками - это и есть аренда. Так как аренды не вечны, каждая новая аренда, полученная DHCP-клиентом, добавляется в конец файла. ваша текущая аренда расположена в самом конце файла. Если файл становится слишком большим, он переименовывается и создается новый файл /var/db/dhclient.leases.
Как процесс аренды работает в целом? Представьте на минутку, что кто-либо в вашей сети правильно настроил DHCP-сервер. Этот сервер непрерывно прослушивает 67-ой UDP порт, ожидая от DHCP-клиентов запрос на "аренду". Представьте также, что вы имеете совершенно новый DHCP-клиент, с пустым файлом /var/db/dhclient.leases. Помните, вы сделали этот узел DHCP-клиентом, добавив следующую строку к /etc/rc.conf:
ifconfig_ed0="DHCP"
В этой строке нет ничего, что указывало бы на IP адрес DHCP-сервера. Так и должно быть, потому что в данный момент ed0 не имеет IP адреса; если же он есть, нет необходимости связываться с DHCP-сервером.
В порядке обращения к DHCP-серверу, данный узел отправляет специальный пакет, известный как DHCPDISCOVER. Поскольку узлу не известен IP адрес данного DHCP-сервера, он отправляет пакет на широковещательный адрес, 255.255.255.255, в надежде, что DHCP-сервер увидит его и отзовется. Если вы хорошо знакомы с работой сети, вам известно, что широковещательные пакеты обрабатываются всеми узлами, способными увидеть пакет. Однако, только DHCP-сервер может понять сообщение, так как пакет предназначен для 67-го UDP порта.
вы также можете быть осведомлены о том, что маршрутизаторы блокируют широковещательные пакеты. Это одновременно и удобно, и неудобно для организации DHCP: если в вашей подсети или сегменте нет DHCP-сервера, DHCP-сервер другой подсети никогда не получит такие широковещательные сообщения. Неужели это означает, что необходимо иметь DHCP-сервер в каждом сегменте вашей сети? К счастью, нет. Вместо этого вы используете нечто, известное как "агент ретрансляции bootp" для пересылки соответствующих сообщений DHCP-серверу. Я подробнее остановлюсь на этих агентах ретрансляции в следующих статьях.
В идеале DHCP-сервер получает сообщение DHCPDISCOVER. Когда это происходит, он просматривает свою базу данных в поисках свободных адресов, отбрасывая те, которые ожидают подтверждение получения от других узлов. Затем отправляет DHCPOFFER сообщение, содержащее детали аренды. Это сообщение предназначено для 68 UDP порта DHCP-клиента. вы должны знать, что DHCP использует два различных номера портов, один для клиента и один для сервера. Оба эти номера понадобятся вам, если между клиентом и сервером имеет место быть брандмауэр.
Как только клиент получает DHCPOFFER, он подтверждает аренду отправлением DHCPREQUEST. Опять таки, это сообщение отправляется как широковещательное. Это позволяет всем серверам увидеть, какой адрес клиент собирается присвоить, и в случае ошибки остановить владение арендой клиентом. Сервер, в случае успешного завершения, помечает адрес как занятый. После чего отправляет еще DHCPACK, который указывает клиенту, что он теперь имеет адрес и может использовать данные конфигурационные параметры.
Как только клиент получает DHCPACK, он записывает детали аренды в /var/db/dhclient.leases и использует полученную информацию для работы в сети TCP/IP.
Временные периоды DHCP
Клиент знает о том, что он не может использовать эту конфигурацию постоянно. Срок завершения использования адреса явно указан в аренде. Взгляните на 3 последние строки перед } в моем примере:
renew 3 2003/4/2 00:22:38;
rebind 6 2003/4/5 02:50:06;
expire 6 2003/4/5 23:50:06;
Фактически, вы видите три временных периода: обновления, повторного получения и смерти. Синтаксис каждой строки следующий:
day year/month/day hour:minute:second
где 0 обозначает Воскресенье. В данном примере аренда готова к "обновлению" в Среду, 2 апреля 2003 года в 12:22:38, утром.
Какие существуют различия между обновлением, повторным получением и смертью? Обновление также известно как T1, то есть когда время аренды достигает 50%. Когда имеет место T1, DHCP-клиент отправляет DHCPREQUEST DHCP-серверу, связанному с арендой. Заметьте, что аренда непосредственно указывает адрес DHCP-сервера в данной строке:
option dhcp-server-identifier 2.2.2.21
Поскольку клиент знает адрес сервера, ему не нужно отправлять широковещательное сообщение. Если все проходит хорошо, сервер получает DHCPREQUEST и дает клиенту разрешение на обновление аренды. Чаще всего клиенту разрешается повторно использовать конфигурацию в течение стандартного времени аренды и все три периода отодвигаются в соответствии с новым периодом аренды.
Если клиент не получил ответ от DHCP-сервера, он ожидает T2, то есть когда истечет 87.5% аренды. Это также известно как период повторного получения аренды. Клиент снова отправляет DHCPREQUEST, но теперь уже как широковещательное сообщение. Как правило, клиент высказывает желание получить в аренду этот же адрес прежде, чем истечет ее срок действия. Возможно, некий DHCP-сервер откликнется и снова все три периода отодвинутся в соответствии с новым периодом аренды.
Если что-то пойдет не так, несчастный DHCP-клиент не получит отклика от какого-либо DHCP-сервера. Когда придет время "смерти", клиент больше не сможет использовать настройки и вернется к честному одиночеству. Единственный путь вновь получить адрес - начать прочесывать окрестности широковещательным DHCPDISCOVER.
Все это работает немного по другому, если вы перезагружаете свою машину прежде, чем какой-либо из трех периодов истечет. При загрузке FreeBSD смотрит адрес DHCP-сервера в /var/db/dhclient.leases. Затем пытается связаться с сервером в порядке обновления аренды. Однако, если DHCP-сервер случайно окажется недоступен, клиент проверит, не истек ли срок аренды. Если не истек, он будет пинговать маршрутизатор, чтобы узнать, находится ли он в том же рабочем окружении. Если маршрутизатор откликается, клиент запускается со старым адресом и пытается связаться с DHCP-сервером через 5 минут в порядке проверки верности аренды.
Кроме перечисленных, существуют еще два DHCP сообщения, которые вы можете встретить. Первое - это DHCPNACK или отрицательный отклик. Это сообщение DHCP-сервер отправляет, если клиент запрашивает адрес, не являющийся верным. Обычно это присходит, когда вы физически перемещаете компьютер между подсетями.
Чтобы избежать данного сообщения, вы должны отправить от клиента DHCPRELEASE прежде, чем физически переместить компьютер в другую подсеть. Чтобы сделать это в FreeBSD, дайте команду:
% dhclient -r ed0
Как правило, вы должны выполнить эту команду непосредственно перед выключением питания и перемещением машины. Если вы намерены оставить компьютер включенным после нее, вы не сможете получить новый адрес, так как параметр -r также убивает процесс dhclient. Если вы хотите обновить аренду, просто перезапустите процесс:
% dhclient ed0