FreeBSD — Работа в сети

Работа в сети

FreeBSD известна своей сетевой производительностью. Сетевой протокол TCP/IP разрабатывался в BSD, и именно BSD использовала первую реализацию TCP/IP. Несмотря на жесткую конкуренцию сетевых протоколов в 80-х годах прошлого века, и благодаря удобству, гибкости и либеральным условиям лицензирования, стек протоколов TCP/ IP стал фактическим стандартом.

Многие современные системные администраторы в целом знакомы с основами работы в сетях, но при этом имеют весьма смутное представление о внутренних взаимосвязях. Однако хороший системный администратор понимает, как работает сеть. Знания об адресации IP, смысле сетевой маски и отличии номеров портов от номеров протоколов – необходимый шаг к овладению профессией. В этой главе будут рассмотрены некоторые из этих тем. Для начала вы должны разобраться в том, что такое сетевые уровни.

Сетевые уровни

Каждый уровень решает определенные задачи в сети и взаимодействует только с вышестоящим и нижестоящим уровнями. Изучающие TCP/ IP часто смеются, когда слышат, что многоуровневая организация упрощает сетевые взаимодействия, тем не менее это так. Прямо сейчас важно запомнить, что каждый уровень взаимодействует только с двумя соседними уровнями, расположенными выше и ниже.

В классической диаграмме сетевых протоколов OSI представлено семь уровней. Это полностью законченная схема, охватывающая все ситуации. Однако Интернет – это только одна из ситуаций, и эта книга не посвящена работе в сети в общем. Мы ограничимся обсуждением таких сетей TCP/IP, как Интернет и типичные корпоративные сети, поэтому будем рассматривать только четыре уровня.

Физический уровень

Самый нижний уровень – физический. Он образован сетевой картой и проводом, оптоволокном или радиоканалом. Кроме того, этот уровень включает в себя коммутатор (switch), сетевой концентратор (hub) или базовую станцию, провода, идущие к маршрутизатору, а также оптоволокно, соединяющее ваш офис с телефонной компанией. Коммутатор телефонной компании так же является частью физического уровня, как и оптоволокно и провода, соединяющие континенты. Любые каналы связи являются частью физического уровня. С этого момента мы будем называть физический уровень проводом, хотя это может быть любая другая среда распространения информации.

Этот уровень – самый простой для понимания. Если провод не поврежден и соответствует требованиям, задаваемым физическим протоколом, то дело в шляпе. Если нет, дело табак. Без физического уровня работа сети становится невозможной, точка, конец истории. Одна из функций маршрутизаторов Интернета состоит в том, чтобы преобразовывать пакеты при переходе с физического уровня одного вида на физический уровень другого вида, например из Ethernet в T1/E1. На физическом уровне отсутствует какая-либо логика, он не способен принимать решения, все, что передается через этот уровень, исходит от уровня физического протокола.

Уровень физического протокола

На уровне физического протокола дело становится интереснее. Физический протокол обеспечивает преобразование информации в фактические нули и единицы, которые передаются через физический уровень соответствующим образом. Например, Ethernet использует адреса протокола управления доступом к среде (Media Access Control, MAC) и протокол разрешения адресов (Address Resolution Protocol, ARP); для коммутируемого соединения используется протокол «точка-точка» (Point to Point Protocol, PPP). В дополнение к популярным физическим протоколам Ethernet и PPP, FreeBSD поддерживает и другие протоколы, включая асинхронную систему передачи (Asynchronous Transfer Mode, ATM), протокол высокого уровня управления каналом передачи данных (High Level Data Link Control, HDLC) и протокол межсетевого обмена пакетами (Internetwork Packet Exchange, IPX), а также такие комбинации протоколов, как PPP через Ethernet (PPPoE), который используется в широкополосных сетях. Наличие поддержки всех этих протоколов в системе FreeBSD не означает, что она поддерживает все физические протоколы, которые когда-либо использовались. Если у вас имеются какие-то нетипичные требования, обращайтесь к документации по вашей версии FreeBSD, чтобы узнать, поддерживаются ли требуемые протоколы.

Некоторые физические протоколы имеют реализации, поддерживающие самые разные физические уровни. Например, протокол Ethernet может использоваться для передачи данных по биаксиальным, коаксиальным кабелям; по витой паре CAT3, CAT5, CAT6, CAT7; по оптоволоконным линиям; через радиоэфир и посредством почтовых голубей. С незначительными изменениями в драйверах устройств физический протокол может использоваться в любых типах линий передачи данных. Это один из примеров, как многоуровневая организация позволяет упростить реализацию сетевых взаимодействий. Далее мы подробно будем обсуждать протокол Ethernet как наиболее часто используемый для организации работы систем FreeBSD в сети. Разобравшись с протоколом Ethernet в системе FreeBSD, вы сможете управлять и другими протоколами, разумеется, как только вы начнете их понимать!

Физический протокол обменивается информацией с физическим уровнем и сетевым уровнем (уровнем логического протокола).

Сетевой уровень

«Сетевой уровень? Разве это не вся сеть целиком?»

Да, но сетевой уровень более специфичен. Он отвечает за обеспечение связи между узлами сети и отвечает на такие вопросы, как: «Где искать другие узлы сети?» и «Можно ли соединиться с каким-то конкретным узлом сети?». Этот логический протокол обеспечивает непротиворечивый интерфейс для программ, использующих сетевые соединения, независимо от типа физического уровня. Сетевой уровень Интернета основан на использовании протокола IP (Internet Protocol). В соответствии с протоколом IP каждому узлу сети присваивается уникальный адрес1, который называется IPадресом, по которому он может быть обнаружен любым другим узлом в сети.

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

Да, я помню о существовании механизма трансляции сетевых адресов (Network Address Translation, NAT), который позволяет использовать неуникальные IP-адреса. NAT – это путь, полный хлопот, спросите любого, кто использует NAT в достаточно крупных масштабах. Но даже в случае использования NAT в Интернете вы все равно имеете один или несколько уникальных адресов.

Транспортный уровень

Транспортный уровень имеет дело с реальными данными для реальных приложений и, возможно даже, для реальных людей. На транспортном уровне используются три основных протокола – ICMP, TCP и UDP.

Протокол управляющих сообщений Интернета (Internet Control Message Protocol, ICMP) управляет передачей сообщений, обеспечивающих взаимодействие между узлами сети с присвоенными IP-адресами. Если протокол IP – это способ добраться до требуемого адреса, то ICMP – это своего рода светофор и дорожный знак, обозначающий выезд на магистраль. В большинстве случаев протокол ICMP работает совершенно незаметно, и вам никогда не придется вспоминать о его существовании.

Другие, широко известные транспортные протоколы, – это протокол пользовательских дейтаграмм (User Datagram Protocol, UDP) и протокол управления передачей данных (Transmission Control Protocol, TCP). Насколько широко они распространены? Скажем так, комплекс протоколов Интернета вообще называется TCP/IP. Эти протоколы предоставляют такие возможности, как мультиплексирование по номеру порта и передачу пользовательских данных. UDP – это исключительно транспортный протокол, предоставляющий минимальный объем возможностей, необходимых для передачи данных через сеть. TCP обеспечивает более широкие возможности, такие как определение заторов и проверку целостности.

Помимо этих трех, существует еще множество протоколов, работающих поверх IP. Полный перечень транспортных протоколов, основанных на механизме IP, можно найти в файле /etc/protocols. Здесь не удастся отыскать протоколы, не использующие IP, такие как LAT компании Digital, но здесь перечислено огромное число протоколов, которые могут вам встретиться в реальном мире. Например, здесь, как показано ниже, присутствуют наиболее типичные для Интернета протоколы IP и ICMP:

ip 0 IP # Internet protocol, pseudo protocol number icmp 1 ICMP # Internet control message protocol

Каждая строка в /etc/protocols состоит из трех основных полей: неофициальное название , номер протокола  и псевдонимы . Номер протокола используется в сетевых запросах для идентификации трафика. Вы увидите его, если воспользуетесь программой перехвата пакетов (sniffer) или по каким-либо причинам углубитесь в изучение своей сети. Как видно из фрагмента выше, протокол IP имеет номер 0, а протокол ICMP имеет номер 1 – если не это основа всего сущего, сложно представить, что могло бы быть ею! Протокол TCP имеет номер 6, а протокол UDP – 17. Кроме того, здесь же можно видеть комментарии , в которых приводится краткое описание каждого протокола.

Транспортный уровень взаимодействует с сетевым уровнем, лежащим ниже, и с приложениями – выше.

Приложения

Приложения также являются частью сети. Приложения посылают запросы на открытие сетевых соединений, передают данные в сеть, получают данные из сети и обрабатывают эти данные. Веб-броузеры, клиенты электронной почты, серверы JSP и т. п. – все это сетевые приложения. Приложения взаимодействуют только с сетевым уровнем и с пользователем. Проблемы на уровне пользователя и выше далеко выходят за рамки этой книги.1

Сеть на практике

Итак, вы имеете представление, как все работает в комплексе, и готовы двигаться дальше, правильно? Нет, неправильно. Давайте посмотрим, как этот комплекс работает в реальных условиях. Некоторые из последующих объяснений будут касаться материала, который будет рассматриваться в следующих главах, но раз уж вы взялись за чтение этой книги, значит, вы имеете представление о сетях, достаточное, чтобы двигаться дальше. Если что-то будет вам непонятно, перечитайте этот раздел еще раз, после прочтения этой главы. (Просто купите еще один экземпляр этой книги, вырежьте страницы с данным разделом и вклейте их в конце этой главы.)

Предположим, что пользователь, имеющий подключение к Интернету, хочет попасть на веб-сайт Yahoo! Для этого он запускает свой вебброузер и набирает адрес URL.

Веб-броузер должен знать, как взаимодействовать с транспортным уровнем, лежащим ниже. После преобразования запроса пользователя в соответствующую форму броузер просит транспортный уровень установить соединение с указанным IP-адресом, с номером порта 80. (Поборники точности могут заметить, что я пропустил этап определения IP-адреса по доменному имени, но это не такое большое отступление, которое только усложнило бы пример.)

Транспортный уровень анализирует запрос, поступивший от броузера. Поскольку приложение обратилось с запросом на установление соединения TCP, транспортный уровень выделяет для этого соответствующие системные ресурсы. Запрос разбивается на части допустимого размера, которые передаются ниже, сетевому уровню.

Сетевой уровень не думает о реальном запросе. Ему вручили блок данных, который он должен доставить по указанному адресу через Интернет. Как почтальон, доставляющий письма, ничего не зная об их содержимом, сетевой уровень просто упаковывает данные TCP в «конверт» с соответствующим адресом. Получившийся блок данных называется пакетом. Далее сетевой уровень передает пакеты на уровень физического протокола.

Уровень физического протокола совершенно не интересует содержимое пакета. Его не интересуют ни IP-адрес, ни маршрут движения пакета. Ему вручили блок нулей и единиц, и он должен выполнить задание по доставке их через сеть. Единственное, о чем он знает, – это как выполнить передачу. Уровень физического протокола может добавлять в пакет дополнительную информацию, которая будет использоваться на физическом уровне, создавая тем самым кадр (frame). Наконец, все это передается с уровня физического протокола в провода, в эфир или другую среду передачи информации.

Физический уровень полностью лишен интеллекта. Уровень физического протокола передает ему последовательность нулей и единиц, а он передает их другому физическому устройству. Он понятия не имеет, какой протокол используется или как вывести эти нули и единицы через коммутатор, концентратор или повторитель, но предполагает, что один из хостов является маршрутизатором.

Когда маршрутизатор принимает блок нулей и единиц, он передает их на уровень выше – на уровень физического протокола. На этом уровне отбрасывается информация о кадре и полученный пакет вручается сетевому уровню внутри маршрутизатора. Сетевой уровень маршрутизатора анализирует пакет и на основе имеющейся таблицы маршрутизации решает, что с ним делать дальше. После этого пакет вручается соответствующему уровню физического протокола. Это может быть другой интерфейс Ethernet или интерфейс PPP, ведущий в линию T1.

Каждый внутри другого?

Да, именно так, оригинальный веб-запрос был инкапсулирован в протокол TCP. Этот запрос в свою очередь был инкапсулирован на транспортном уровне в протокол IP и затем в физический протокол. Все эти заголовки вставлялись в начало и в конец первоначального запроса. Приходилось ли вам когда-нибудь видеть картинку, где маленькую рыбку глотает рыба побольше, которую в свою очередь пытается проглотить рыба еще большего размера и так далее? Эта картинка очень точно отражает то, что происходит в нашем случае. Или, если хотите, кадр можно сравнить с самой большой коробкой, в которую вложена серия коробок разного размера и в самой внутренней коробке спрятан подарок. Развернув один протокол, вы обнаружите другой.

На пути данных тип физического носителя может меняться. Например, линия T1 может перейти в оптоволоконную линию DS3, которая в свою очередь стыкуется с линией OC192, протянутой по всей стране. Благодаря многоуровневой организации и абстракции ни ваш компьютер, ни ваш пользователь не обязаны что-либо знать о таких вещах.

Достигнув места назначения – компьютера на другой стороне соединения, кадр начинает обратный путь по стеку протоколов. Физический уровень принимает нули и единицы и передает их на уровень физического протокола. Уровень физического протокола очищает кадры от заголовков Ethernet и передает получившиеся пакеты транспортному уровню. На транспортном уровне пакеты собираются в поток данных, который затем направляется приложению, в данном случае – веб-серверу. Приложение обрабатывает запрос и возвращает ответ, который опускается вниз по стеку протоколов и отправляется в сеть, где они, в случае необходимости, перепрыгивают через границы различных физических протоколов. Такой процесс подразумевает огромный объем работы, часто только лишь для того, чтобы вы могли получить сообщение об ошибке «404 Page Not Found» (запрошенная страница не найдена).

Этот пример наглядно демонстрирует, почему многоуровневая организация имеет такое большое значение. Каждый уровень знает лишь самое необходимое об уровнях, находящихся выше и ниже, поэтому при желании можно менять целые уровни. Когда создается новый физический протокол, другим уровням не о чем беспокоиться; сетевой протокол просто передает правильно сформированный запрос на уровень физического протокола и оставляет за ним всю внутреннюю работу. При появлении сетевой карты нового типа надо лишь написать драйвер для физического протокола; стек сетевых протоколов, включая и приложение, здесь роли не играют. Представьте себе драйвер устройства, который было бы необходимо устанавливать в веб-броузер, в клиент электронной почты и в любые другие приложения на вашем компьютере, включая ваши собственные. Это быстро привело бы вас к разочарованию и стало бы похоже на прыжок с парашютом с наковальней на шее.

Двоичные и шестнадцатеричные значения

Будучи системным администратором, вы частенько будете встречать такие термины, как 48битовый адрес или 18битовая сетевая маска. Я часто встречал системных администраторов, которые только кивают и улыбаются, когда слышат нечто подобное, и при этом думают: «Да неважно, ты прямо скажи, что я должен делать». К сожалению, математика – это неотъемлемая часть работы, и вы обязаны знать двоичное исчисление. Понимание этой области является одним из признаков, которые отличают любителей от профессионалов. Вам не нужно читать эту книгу, если вы хотите остаться любителем.

Возможно, вы уже бормочете себе под нос: «Но я знаю это!» Тогда просто пропустите этот раздел. Но не обманывайте себя, если вы этого еще не знаете.

Возможно, вы уже знаете, что компьютер интерпретирует данные как нули и единицы и что одна единица или один ноль составляют один бит. Когда протокол задает биты, он указывает это число согласно представлениям компьютера. 32-битовое число имеет 32 цифры, каждая из которых может быть представлена нулем или единицей. Возможно, вы уже имеете представление о двоичных операциях, или операциях с числами по основанию 2, которые наверняка изучались вами в средней школе и быстро забылись. Двоичная система – это просто другой способ представления чисел, с которыми люди работают каждый день.

Десятичная математика (числа с основанием 10) ежедневно используется нами при покупке пиццы или для подсчета баланса чековой книжки. В ней задействованы цифры от 0 до 9. Чтобы получить число, превышающее самую большую цифру, слева к этой цифре добавляется другая, а текущая становится равной нулю. Это правило «переноса единицы», которое вы изучили много лет назад и сейчас используете неосознанно. В двоичной математике есть только цифры 0 и 1. Чтобы получить число, превышающее самую большую цифру, слева к этой цифре добавляется другая, а текущая становится равной 0. Та же самая десятичная математика, только с восемью пропавшими пальцами. В качестве примера в табл. 6.1 показаны первые несколько десятичных чисел, преобразованные в двоичные значения.

Таблица 6.1. Десятичные и двоичные числа

Десятичные Двоичные

00 11

  • 2  10
  • 3  11
  • 4  100
  • 5  101
  • 6  110
  • 7  111
  • 8  1000

Число из 32 бит, например IP-адрес, представляет собой строку из 32 нулей и единиц. MAC-адреса, используемые протоколом Ethernet, представляют собой 48-битовые числа и состоят из 48 нулей и единиц.

Ради интереса могу заметить, что в UNIX в некоторых случаях используются шестнадцатеричные числа (например, MAC-адреса и сетевые маски). Шестнадцатеричные числа имеют длину 4 бита. Двоичное число 1111, в котором все четыре бита представлены единицами, эквивалентно десятичному числу 15, а это означает, что в шестнадцатеричной системе используются цифры от 0 до 15. Сейчас некоторые из вас, глядя на двузначное число 15, которое должно представлять единственную цифру, думают – какую травку я курю и нельзя ли организовать поставку такой замечательной травки себе. Для представления чисел от 10 до 15 в шестнадцатеричной системе счисления используются символы от A до F. Когда счет доходит до самой большой цифры и нужно добавить еще единицу, текущая цифра устанавливается равной нулю, а слева добавляется еще одна цифра. Например, последовательность чисел от 1 до 17 в шестнадцатеричной системе выглядит следующим образом: «1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11». Снимайте обувь и считайте на пальцах, пока не поймете.

Шестнадцатеричные числа обычно помечаются префиксом 0x. Например, число 0x12 – это шестнадцатеричный эквивалент десятичного числа 18, тогда как 18 – это просто число 18. Если шестнадцатеричное число не помечено префиксом 0x, значит оно находится на месте, где допустимы только шестнадцатеричные числа, например в MAC-адресе. Наличие символов от A до F однозначно говорит о том, что число шестнадцатеричное, но это не самый надежный признак, потому что шестнадцатеричные числа могут не содержать шестнадцатеричных цифр, так же как многие десятичные числа могут состоять только из двоичных цифр.

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

Биты по байтам

Компьютеры преимущественно работают с байтами, где каждый символ представлен 8-битовым числом. Единственное исключение – сетевой стек, где все сущее представлено отдельными битами. Так, например, файл размером 5 мегабайтов может находиться в компьютере, подключенном к сети со скоростью передачи данных 10 мегабитов (в секунду – прим. научн. ред). Не путайте их!

TCP/IP в деталях

Теперь, когда у вас имеется некоторое представление о том, как работает сеть, я предлагаю подробнее рассмотреть реальный сетевой протокол. Доминирующим протоколом в Интернете является TCP/IP, или

TCP/IP в деталях Transmission Control Protocol over Internet Protocol (протокол управления передачей данных, реализованный поверх межсетевого протокола). TCP – это транспортный протокол, тогда как IP – это сетевой протокол, но они настолько переплелись между собой, что обычно рассматриваются как единое целое. Мы начнем рассмотрение темы с протокола IP, а затем перейдем к TCP и UDP.

IPадреса и сетевые маски

IP-адрес – это уникальное 32-битовое число, присвоенное конкретному узлу сети. Некоторые адреса остаются более или менее постоянными, как, например, адреса серверов в Интернете. Другие изменяются в зависимости от потребностей сети, как, например, IP-адреса, которые выдаются клиентам, подключающимся к Интернету по коммутируемым линиям связи. Отдельные машины в общедоступных сетях получают IP-адреса из непрерывного диапазона адресов.

Обычно IP-адреса рассматриваются не как 32-битовое число, а делятся на четыре группы по 8 бит в каждой, и записываются в виде десятичных чисел, разделенных точками. Хотя запись 192.168.1.1 – это то же самое, что и 11000000.10101000.00000001.00000001, или число 11000000101010000000000100000001, тем не менее запись в виде четырех чисел воспринимать проще.

При подключении компании к Интернету провайдер выделяет ей блок IP-адресов. Как правило, этот блок невелик, скажем, 16 или 32 IP-адреса. Если речь идет о небольшой группе идентичных серверов, компания получит лишь несколько IP-адресов.

Сетевая маска определяет размер блока IP-адресов в локальной сети. Размер блока IP-адресов определяется сетевой маской, или, иначе говоря, сетевая маска определяет количество IP-адресов, имеющихся в вашем распоряжении. Если вы имеете давнее знакомство с сетями, вам наверняка приходилось встречаться с сетевой маской 255.255.255.0 и вы знаете, что она описывает блок из 256 IP-адресов. Кроме того, возможно, вы даже знаете, что неверная сетевая маска будет препятствовать нормальной работе системы в сети. Сейчас такие простые сетевые маски встречаются все реже и реже. Чтобы понять, в чем тут дело, необходимо погрузиться в историю IP-адресов. Много лет назад IP-адреса выделялись блоками трех размеров, соответствующих классу A, классу B и классу C. Со временем эта терминология устарела, но мы возьмем ее за основу.

Класс A был очень простым: первое из четырех чисел IP-адресов было фиксированным. Агентство по выпуску IP-адресов в обращение (в прошлом – InterNIC) могло выделить блок адресов класса A, скажем, 10.0.0.0. Оставшиеся три числа владелец мог назначать по своему усмотрению, при условии, что IP-адреса будут начинаться с 10. Например, адреса с 10.1.0.0 по 10.1.1.255 можно было выделить для информационного центра, адреса с 10.1.2.0 по 10.1.7.255 – для офиса в Детройте и т. д. Блоки адресов класса A получали только очень большие компании, такие как Ford и Xerox, а также влиятельные академические организации, связанные с компьютерными технологиями, такие как Массачусетский технологический институт (MIT). Просмотрев список первоначальных владельцев класса A, можно увидеть, что в основном это учебные заведения, имевшие большое влияние в 80-х годах прошлого века.

В блоках класса B фиксированными были первые два из четырех чисел, составляющих IP-адрес. Блок адресов класса B мог выглядеть, например, как 172.16.0.0. Каждый IP-адрес, использовавшийся во внутренней сети, начинался с 172.16, а по своему усмотрению можно было назначать последние два числа. Многие компании среднего размера получили блок адресов класса B.

Подобным образом в блоке класса С фиксированы первые три числа адреса. Обычно такие блоки получали маленькие компании. Провайдер услуг Интернета выделял номер, подобный 198.22.63.0, и предоставлял владельцу блока возможность назначать последнее число каждого адреса.

Такая схема приводила к растрачиванию IP-адресов. Многим мелким фирмам не нужны были 256 IP-адресов, а многие компании среднего размера занимали больше 256, но меньше 65 000 адресов в блоке класса B. И почти никому не требовались все 16 миллионов адресов из блока класса A. Однако было принято такое решение, и до бума Интернета такое положение всех устраивало. Тогда, в 80-х годах, дети хотели просто поиграть с компьютером, теперь же они мечтают о своем собственном сайте электронной коммерции. Это привело к увеличению потребности в IP-адресах.

Сегодня IP-адреса выделяются вместе с префиксной длиной (prefix length), значение которой отделяется от IP-адреса символом слэша (slash). Блок IP-адресов может выглядеть так: 192.168.1.128/25. Подобная запись может быть не очень понятной, но делает возможным более тонкое деление классов адресов. Известно, что каждое из четырех чисел в IP-адресе состоит из 8 бит. При использовании классов «фиксированным» считается определенное количество бит – их нельзя изменить в локальной сети. Адрес класса A имеет 8 фиксированных бит, класса B – 16 бит и класса C – 24 бита.

В приведенных примерах IP-адреса того или иного класса не были представлены в двоичной форме, и я не буду заставлять вас выполнять это преобразование. Однако под IP-адресом следует понимать строку из двоичных чисел. В адресах локальной сети можно изменить биты в правой части каждого адреса, но не биты в левой части. Единственный вопрос, который осталось выяснить: «Где проходит граница, которая отделяет правую и левую части?» Нет никаких причин, по которым длина каждой части адреса должна быть кратной 8. Префиксная длина – это просто некоторое количество фиксированных битов. Запись /25 означает, что фиксированными являются 25 бит, то есть на один бит больше, чем в адресе класса C. В этом случае в адресе можно изменять последние 7 бит. В следующей записи фиксированные биты представлены единицами, а изменяемые – нулями:

11111111.11111111.11111111.10000000

 

11111111 – это число 255, а 10000000 – 128. Таким образом, данная сетевая маска приобретает вид 255.255.255.128. Все очень просто, если мыслить двоичными категориями. С двоичными числами вовсе не обязательно работать каждый день, но тем, кто не понимает базовые концепции двоичной математики, преобразование чисел из двоичной формы в десятичную кажется совершенно непонятным. В ходе практической деятельности можно научиться видеть десятичные числа в логичной двоичной записи.

Что это означает на практике? Прежде всего, блоки IP-адресов выделяются в количестве, кратном 2. Если изменяемыми являются 4 бита, то возможны 16 адресов (2×2×2×2 = 16), а если 8 бит, то (28) 256 IP-адресов. Если кто-либо говорит, что доступно 19 IP-адресов, то либо речь идет о разделяемой сети Ethernet, либо высказанное утверждение ошибочно.

Нередко можно увидеть IP-адрес хоста вместе с его сетевой маской, например 192.168.3.4/26. Такая форма записи содержит всю информацию, необходимую для подключения компьютера к локальной сети. (Поиск шлюза по умолчанию – это уже другая проблема, но, как правило, адрес шлюза находится либо в самом верху, либо в самом низу диапазона адресов.)

Вычисление сетевых масок в десятичном виде

Преобразование из десятичной формы в двоичную и обратно не всегда доставляет удовольствие. Это не только неудобно, это еще увеличивает вероятность допустить ошибку. Следующая хитрость позволит вам вычислять сетевые маски, оставаясь в рамках десятичной системы счисления.

Прежде всего нужно выяснить, сколько реальных IP-адресов есть в наличии. Это число будет кратно 2. Почти всегда количество адресов меньше 256. Из числа 256 нужно вычесть количество адресов, имеющихся в наличии, и получим последнее число сетевой маски. При этом все еще необходимо уметь определять размеры сети. Если предположить, что IP-адрес имеет вид 192.168.1.100/26, вы должны понимать, что запись /26 – это 26 фиксированных битов, или 64 IP-адреса. Взгляните на последнее число в IP-адресе – 100. Конечно, оно находится не в интервале между 0 и 63, а в интервале между 64 и 127. Другие хосты этого блока имеют IP-адреса от 192.168.1.64 до 192.168.1.127, а сетевая маска имеет вид 255.255.255.192 (256 – 64 = 192).

В этом месте я должен заметить, что сетевые маски часто записываются в шестнадцатеричном виде. У вас может возникнуть желание бросить все, как безнадежное дело, но упростить жизнь вам поможет табл. 6.2, в которой приводятся сетевые маски и количество доступных IP-адресов для сетей /24 и меньше.

Таблица 6.1. Сетевые маски и IPадреса

Префикс Двоичная Десятичная

Шестнадцатеричная Доступные маска IPадреса

256

128

64

32

16

8

4 2 1

маска

маска

00000000

10000000

11000000

11100000

11110000

11111000

11111100

11111110

11111111

255.255.255.0

255.255.255.128

255.255.255.192

255.255.255.224

255.255.255.240

255.255.255.248

255.255.255.252

255.255.255.254

255.255.255.255

0xffffff00

0xffffff80

0xffffffc0

0xffffffe0

0xfffffff0

0xfffffff8

0xfffffffc

0xfffffffe

0xffffffff

/24

/25

/26

/27

/28

/29

/30

/31

/32

 

Неиспользуемые IPадреса

Теперь вы понимаете, что объединяет сетевые маски и IP-адреса и что, например, запись /28 подразумевает 16 IP-адресов. К сожалению, не все адреса в блоке можно использовать. Первый IP-адрес блока – это номер сети (network number). Он предназначен для внутреннего управления сетевыми ресурсами.

В любой группе IP-адресов последний номер является широковещательным адресом (broadcast address). Согласно спецификации IP, каждая машина в сети должна откликаться на запрос, посылаемый по этому адресу. Такая возможность позволяет проверять доступность адресатов и выяснять, какие IP-адреса используются в сети. Например, в типичной сети /24 широковещательный адрес будет иметь вид: x.y.z.255. В конце 90-х годов отправка пакетов по широковещательному адресу применялась при организации атак на сети. Сейчас эта возможность отключена в большинстве операционных систем и сетевых устройств.1 Всистемах BSD поддержку широковещательной адресации можно включить с помощью установки параметра net.inet.icmp.bmcastecho в 1.

В любом случае интерфейсу нельзя назначить первый и последний IPадреса сети, не вызвав появление проблем. Разные системы по-разному реагируют на эти проблемы. Но можно попробовать, причем желательно после окончания рабочего дня, иначе вам придется рассказывать эту историю уже на другой работе.

Присвоение IPадресов

Можно было бы подумать, что каждый компьютер в сети имеет IP-адрес, но это не всегда верно. IP-адреса присваиваются каждому сетевому интерфейсу. Большинство компьютеров имеют единственный сетевой интерфейс, поэтому для них эта разница несущественна. Однако, если в компьютере имеется несколько сетевых карт, то каждой из них присваивается свой IP-адрес. С другой стороны, можно присвоить несколько IP-адресов одному сетевому интерфейсу, используя псевдонимы. Напротив, в некоторых конфигурациях можно связать несколько сетевых карт с единственным сетевым интерфейсом, дав компьютеру единственный виртуальный интерфейс, несмотря на имеющееся количество сетевых карт. Хотя эти различия являются незначительными, о них следует помнить при выяснении возникающих проблем.

ICMP

Протокол управляющих сообщений Интернета (Internet Control Message Protocol, ICMP) – это стандартный способ передачи информации о маршрутах и сообщений о доступности сети. Такие инструменты, как ping(8) и traceroute(8) используют ICMP для сбора необходимых сведений. Протокол ICMP необходим для обеспечения надлежащей производительности сети, но некоторые виды ICMP-сообщений могут использоваться злоумышленниками для получения дополнительных сведений о сети. Если вам необходимо блокировать трафик ICMP по причинам, связанным с обеспечением безопасности, вы должны делать это выборочно.

UDP

 

Протокол пользовательских дейтаграмм (User Datagram Protocol, UDP) – это основной транспортный протокол передачи данных, работающий поверх протокола IP. В нем не предусмотрена возможность обработки ошибок, он обладает минимальными возможностями проверки целостности и не имеет никакой защиты от потери данных. Несмотря на эти недостатки, UDP является неплохим выбором для передачи некоторых видов данных, и многие службы Интернета используют его.

Когда хост передает данные по UDP, он не знает, доставлены ли они до места назначения. Когда хост получает данные по UDP, он просто прослушивает сеть и принимает все, что из нее приходит. Программа, принимающая данные по UDP, не может проверить, откуда пришли эти данные. Хотя пакеты UDP включают в себя адрес отправителя, его легко подделать. По этой причине UDP называют протоколом без установления соединения (connectionless) или протоколом без установления состояния (stateless).

Почему тогда используется UDP, если он обладает такими недостатками? Приложения, использующие UDP, часто сами реализуют методы обработки ошибок, которые могут не совпадать с методами, предоставляемыми по умолчанию такими протоколами, как TCP. Например, простые клиентские запросы к DNS должны иметь тайм-аут не более нескольких секунд, в противном случае это будет вызывать раздражение у пользователя. Тайм-аут для соединений TCP составляет две минуты. Поскольку реакция на неудачные запросы к DNS должна следовать как можно быстрее, то запросы к DNS отправляются по протоколу UDP. В случаях, когда сервер DNS должен отправлять большие объемы данных (например, передача информации о зонах), он переходит на использование протокола TCP. Для передачи потоковых данных, как в случае с видеоконференциями, также используется протокол UDP. Если бы потеря нескольких пикселей при передаче картинки видеоконференции в реальном времени вызывала повторную передачу данных, это приводило бы лишь к перегрузке сети. Нельзя вернуться назад во времени и восполнить недостающие участки картинки! Аналогичными причинами объясняется применение протокола UDP практически всеми использующими его сетевыми приложениями.

UDP – это также протокол обмена дейтаграммами, в том смысле, что каждый передаваемый блок данных является самодостаточным и законченным и воспринимается как отдельный блок. При этом сами приложения, использующие UDP, чаще всего не считают одиночные пакеты UDP завершенным запросом, каковыми они воспринимаются сетью. Протокол TCP полностью отличается от UDP.

Протокол управления передачей данных (Transmission Control Protocol, TCP) обладает такими замечательными особенностями, как коррекция ошибок и восстановление данных. Принимающая сторона должна подтвердить получение каждого пакета, в противном случае отправитель будет повторять передачу неподтвержденных пакетов. Приложения, использующие TCP, вправе ожидать надежной передачи данных. В отличие от UDP, протокол TCP называют протоколом с установлением соединения (connected).

Кроме того, TCP является потоковым протоколом, то есть при его использовании единственный запрос может быть разбит на несколько сетевых пакетов. Несмотря на то, что отправитель может посылать пакеты по порядку, один за другим, принимающая сторона может получать их в ином порядке или вообще в фрагментированном виде. Поэтому принимающая сторона должна следить за тем, какие части она получает, и выполнять их сборку для организации нормальных сетевых взаимодействий.

Два хоста, использующие TCP для обмена данными, должны организовать между собой канал, по которому будут передаваться данные. Первый хост запрашивает открытие соединения, второй хост отвечает на этот запрос, и только после этого первый хост начинает передачу данных. Этот процесс называется тройным рукопожатием (threeway handshake). Подробности на данном этапе нас не интересуют, нам достаточно знать, что это происходит. Аналогичным образом по окончании передачи системы должны выполнить некоторые действия, чтобы закрыть соединение.

Протокол TCP обычно используется такими программами, как программы электронной почты, FTP-клиенты и веб-броузеры, по этой причине для протокола были выбраны наиболее универсальные интервалы тайм-аутов и набор функциональных возможностей.

Транспортные протоколы следующего поколения

Одной интересной особенностью FreeBSD 7.0 является поддержка протокола управления передачей потоков данных (Stream Control Transmission Protocol, SCTP). Это транспортный протокол следующего поколения, разработанный для передачи сложных потоков данных. Реализация протокола во FreeBSD спонсировалась компанией Cisco Systems, которая, по всей видимости, рассматривала свободно распространяемую систему FreeBSD как один из лучших способов вывести данный протокол в мир.

Как протоколы взаимодействуют между собой

Стек сетевых протоколов можно сравнить с семьей, сидящей за обеденным столом. Родственники передают блюда друг другу. Физический протокол (ARP, в случае использования Ethernet) позволяет увидеть всех сидящих за этим столом. Протокол IP выделяет каждому свое место за столом, кроме трех юных племянников, присевших на скамейку NAT. Протокол ICMP предоставляет информацию о маршрутизации, например: «Самый короткий путь к гороху – это попросить дядюшку Криса передать его вам». Протокол TCP вступает в игру, когда вы передаете кому-то блюдо, и он должен сказать: «Спасибо» прежде, чем вы отпустите тарелку. Наконец, протокол UDP напоминает бросок рулета тетушке Бетти, которая может быть поймает его, а может быть он будет пойман собакой, следящей за обедающими. (Да, воскресные обеды в моей семье проходят гораздо интереснее, чем в большинстве других семей.)

Порты транспортного протокола

Вы когда-нибудь замечали, что компьютеры имеют слишком много портов? Мы собираемся добавить в список порты TCP и UDP. Порты транспортных протоколов позволяют одному серверу предоставлять различные сетевые услуги посредством единственного транспортного протокола, обеспечивая возможность организации множественных соединений между компьютерами.

Когда запускается программа-сервер, она подключается к одному или более логических портов. Логический номер порта – это просто число от 1 до 65535. Например, почтовые серверы принимают соединения на порту TCP с номером 25. Каждый пакет TCP или UDP, поступающий в систему, имеет поле, которое содержит номер порта доставки. Каждый входящий запрос помечен номером порта, куда он должен быть доставлен. Если входящий запрос приходит на порт с номером 25, он передается почтовому серверу, ожидающему запросы на соединения на этом порте. Это означает, что разные порты могут обслуживаться разными программами, клиенты могут взаимодействовать с серверами на разных портах, и никто не путается, кроме системного администратора.

Файл /etc/services содержит список номеров портов и сервисов, которые с ними ассоциированы. Почти любой сервис можно запускать на произвольном порту, но таким образом можно сбить с толку другие хосты Интернета, которые пытаются соединиться с вашей системой. Если кто-то пытается отправить электронную почту, его программа автоматически пытается соединиться с портом 25 вашей системы. Если служба электронной почты работает на порту с номером 77, а вебсервер на порту 25, вы никогда не сможете получить свою электронную почту, а ваш веб-сервер начнет получать спам. Формат файла очень прост – он содержит всего пять колонок:

qotd 17/tcp quote #Quote of the Day

Эта запись описывает службу qotd , которая работает на порту с номером 17  протокола TCP . Эта служба известна также под названием quote . В последней колонке содержится комментарий , более подробно описывающий службу, в частности здесь говорится, что название qotd происходит от английского «Quote of the Day» (цитата дня). Службам присваиваются одни и те же номера портов для протоколов TCP и UDP, даже несмотря на то, что обычно они могут использовать только один протокол, например, со службой qotd связаны порты 17/tcp и 17/udp.

Многие программы читают /etc/services, чтобы выяснить, к какому порту осуществить привязку (bind to), а клиентские программы читают /etc/services, чтобы выяснить, к какому порту обращаться для установления соединения. Чтобы вынудить сервер использовать другой порт, надо отредактировать этот файл и сообщить серверу, какой порт следует использовать.

Подобно всем другим стандартам, содержимое файла /etc/services не является догмой. Служба sshd обычно занимает порт 22/tcp, однако по разным причинам я запустил ее на портах 23 (telnet), 80 (HTTP) и 443 (HTTPS). Подобные изменения зависят от программы, задействованной для предоставления того или иного сервиса.

Зарезервированные порты

Порты протоколов TCP и UDP с номерами 1024 и ниже называются зарезервированными портами. Они зарезервированы для ключевых служб инфраструктуры Интернета, таких как DNS, SSH, HTTP, LDAP и других, которые должны предоставляться только системой или сетевым администратором. Только программы, обладающие привилегиями суперпользователя (root-level), могут привязываться к зарезервированным портам (портам с низкими номерами). Пользователь может, например, запустить игровой сервер на одном из портов с высокими номерами, если политика безопасности системы допускает это, но назначение компьютера игровым сервером отличается от настройки официального веб-сервера, доступного всем желающим! Привязка портов к базовым протоколам словно высечена на каменных скрижалях.

Просмотреть и изменить зарезервированные порты можно с помощью параметров sysctl net.inet.ip.portrange.reservedhigh и net.inet.ip.portrange.reservedlow.

Многие часто думают, что если бы можно было запретить правило «привязки только при наличии прав суперпользователя», это повысило бы степень защищенности системы – в конце концов, если приложение будет работать не с правами root, а с правами обычного пользователя, разве это не повысило бы безопасность системы? В действительности большинство программ, использующих зарезервированные порты, запускаются с привилегиями пользователя root, выполняют привязку к порту, а затем понижают свои привилегии до уровня специально созданного пользователя, который обладает еще меньшими привилегиями, чем обычный пользователь. Эти программы разрабатывались так, чтобы запускаться с привилегиями суперпользователя, и часто ведут себя иначе, когда их запускают с привилегиями обычного пользователя. Некоторые программы, такие как веб-сервер Apache, написаны так, чтобы сразу запускаться с привилегиями обычного пользователя, но другие не предусматривают такой возможности.

Ethernet

Ethernet является наиболее популярным носителем в корпоративных и домашних сетях и является наиболее типичным носителем для систем FreeBSD. Ethernet – это общая сеть; самые разные компьютеры могут подключаться к одной и той же сети Ethernet и напрямую взаимодействовать друг с другом. Это одно из преимуществ Ethernet перед другими сетевыми протоколами. Однако Ethernet налагает ограничения на физические расстояния между системами, поэтому этот протокол подходит только для офисов, внутренних сетей хостинг-провайдеров (co-location facilities) и других сравнительно небольших сетей.

На протяжении многих лет для реализации Ethernet применялось много различных физических носителей. Было время, когда большинство кабелей Ethernet представляли собой толстый коаксиальный кабель, а сегодня в большинстве сетей Ethernet задействованы сравнительно тонкие кабели категории 5 (CAT5) с восемью тонкими проводами внутри. Ethernet можно реализовать по оптоволокну или через радиоэфир. В рамках нашего разговора предположим, что Ethernet в данном случае реализована по кабелю CAT5 – сегодня это наиболее распространенный носитель. Независимо от того, какой физический носитель используется, теория Ethernet от этого не меняется – не забывайте, что физический уровень для нас лишь абстракция.

Протоколы и аппаратное обеспечение

Ethernet – это широковещательный (broadcast) протокол – каждый пакет, посылаемый по сети, может доставляться на каждую рабочую станцию. (Обратите внимание на оговорку «может» – некоторые устройства Ethernet ограничивают возможность приема таких широковещательных посылок.) Драйвер сетевой платы на той или иной рабочей станции отделяет данные, предназначенные для этого компьютера, от всех остальных передаваемых пакетов. Побочный эффект широковещательной сущности Ethernet – возможность подслушивать трафик, предназначенный для других компьютеров сети. Хотя такая возможность очень полезна при диагностировании неполадок, она добавляет хлопот с точки зрения безопасности: перехват пароля – тривиальная операция в старых сетях Ethernet. Часть сети Ethernet, где все хосты могут напрямую взаимодействовать друг с другом, не прибегая к услугам маршрутизатора, называется доменом коллизий (collision domain), или сегментом.

Сегменты Ethernet соединяются между собой с помощью сетевых коммутаторов или концентраторов. Концентратор (hub) Ethernet – это центральная часть аппаратного обеспечения, обеспечивающего физическое соединение устройств Ethernet. Он просто осуществляет переадресацию и пересылку информации уровня Ethernet между устройствами, которые к нему подключены. Весь поступающий трафик Ethernet концентраторы переадресуют каждому присоединенному хосту и другим концентраторам. А каждый хост отвечает за фильтрацию нежелательного трафика. Это традиционный Ethernet.

Коммутаторы в значительной степени вытеснили концентраторы. Коммутатор предоставляет усовершенствованный способ соединения устройств Ethernet, при котором скорость передачи данных в сети Ethernet улучшается за счет отслеживания IP и MAC-адресов всех подсоединенных устройств и перенаправления пакетов тому устройству, для которого они предназначены. Поскольку каждый хост Ethernet имеет ограниченную пропускную способность, коммутация снижает нагрузку на отдельные системы за счет ограничения объема данных, передаваемых каждому устройству.

Отказы коммутаторов

Случается так, что несмотря на надежность устройств, выпускаемых компанией Cisco, коммутаторы иногда выходят из строя. Некоторые поломки видны сразу, как, например, когда из-под крышки прибора валит таинственный черный дым. Дым перестает идти, а прибор прекращает работать. Другие поломки не так очевидны, и на первый взгляд создается ощущение, что коммутатор в порядке.

Каждый производитель коммутаторов сам решает, как устройство должно реагировать на всевозможные отказы. Либо коммутатор прекращает передачу данных, пока к нему не будет проявлено должное внимание, либо он пытается предупредить администратора и продолжает передачу пакетов, хоть как-нибудь. Если вы производитель, ваш выбор вполне очевиден – прибор должен работать, пусть хоть кое-как, благодаря этому у покупателя даже не появляется мысли, что ваши коммутаторы никуда не годятся. Это означает, что коммутатор начинает действовать как концентратор и никто может даже не подозревать об этом. Плохо здесь то, что если вы рассчитываете на коммутатор, как на одно из средств, предотвращающих утечку секретной информации, вас ждет разочарование. В моей практике не раз случались поломки коммутаторов, поэтому особо не удивляйтесь, если это произойдет и с вами.

Установка и использование сервера syslog (глава 19) поможет уменьшить этот риск. Этот сервер не сможет предотвратить поломки коммутаторов, зато он поможет прислушиваться к их жалобам.

Скорость и двунаправленная передача данных в Ethernet

Первоначально Ethernet поддерживал скорость передачи всего в несколько мегабит в секунду, но со временем он стал поддерживать скорости в десятки гигабит. В большинстве случаев используются скорости 10/100 мегабит в секунду (Mbps). Если на сетевой карте имеется наклейка с надписью 10/100 Mbps, это совсем не значит, что она в действительности способна пропускать данные с такой скоростью, – мне приходилось видеть сетевые карты с пометкой 100 Mbps, которые едва дотягивали до скорости 10 Mbps, и гигабитные карты, которые начинали «задыхаться» на скорости 100 Mbps. Большое значение имеет качество сетевой карты, если вам нужна высокая скорость, и не менее важно качество самого компьютера, когда речь идет о высоких скоростях.

Такая характеристика, как duplex (дуплекс, двунаправленная передача), определяет – может ли сетевая карта выполнять прием и передачу данных одновременно. Соединение типа halfduplex (полудуплекс, односторонняя передача) означает, что в каждый конкретный момент времени сетевая карта может выполнять либо только прием, либо только передачу данных – она не в состоянии выполнять обе операции одновременно. В случае соединения fullduplex (полный дуплекс) прием и передача данных могут осуществляться одновременно.

MACадреса

Каждая сетевая карта Ethernet имеет уникальный идентификатор, или MACадрес (Media Access Control – управление доступом к среде передачи данных). MAC-адрес – это 48-битное число, которое иногда называют адресом Ethernet. Когда одна система хочет передать данные другой через Ethernet, она сначала посылает широковещательный запрос, суть которого можно выразить так: «Какой MAC-адрес отвечает за этот IP-адрес?» Если хост отвечает, отправляемые данные помечаются в соответствии с его MAC-адресом. Этот процесс известен как протокол разрешения адресов (Address Resolution Protocol, ARP).

Получить данные из таблицы ARP в системе FreeBSD можно с помощью команды arp(8). Обычно ее запускают как arp –a, что позволяет увидеть MAC-адреса и имена всех хостов в сети:

# arp a
gw.blackhelicopters.org (192.168.3.1) at 00:00:93:34:4e:78 on fxp0 [ethernet]
sipura.blackhelicopters.org (192.168.3.5) at 00:00:93:c2:0f:8c on fxp0 [ethernet]

Этот листинг информации ARP называется таблицей ARP или таблицей MAC. (Термины MAC и ARP часто используются как взаимозаменяемые, поэтому не нужно беспокоиться по этому поводу.) В этом примере хост gw.blockhelicopters.org имеет IP-адрес 192.168.3.1 и MAC-адрес 00:00:93:34:4e:78, а подключиться к этому хосту можно через интерфейс fxp0.

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

Настройка подключения к Ethernet

Прежде чем приступать к настройке системы для доступа к сети Ethernet, у вас должна иметься основная информация об IP-адресе. Если в сети используется протокол динамической настройки конфигурации хоста (Dynamic Host Configuration Protocol, DHCP) и ваш компьютер является клиентом этой службы, вы просто должны использовать ее для доступа к сети, как и любой другой клиент. Если компьютер играет роль сервера, для него больше подходит статический IP-адрес. Для каждого сервера необходимы:

  • IPадрес сервера 
  • Сетевая маска для этого IPадреса 
  • IPадрес шлюза по умолчанию
    Вооружившись этой информацией, вы сможете подключить свою систему к сети с помощью команд ifconfig(8) и route(8). 

ifconfig(8)

Утилита ifconfig(8) выводит список сетевых интерфейсов компьютера и позволяет настраивать их. Начнем с исследования списка интерфейсов в системе, который выводит команда ifconfig(8) без аргументов:

# ifconfig
fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500

options=3<RXCSUM,TXCSUM>
inet 198.22.63.43 netmask 0xfffffff0 broadcast 198.22.63.47 ether 00:02:b3:be:df:f5
media: Ethernet autoselect (10baseT/UTP)
status: àactive

rl0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500

options=8<VLAN_MTU>

ether 00:20:ed:72:3b:5f
media: Ethernet autoselect (10baseT/UTP) status: no carrier

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384

inet 127.0.0.1 netmask 0xff000000

Первый сетевой интерфейс в списке – fxp0 , или это описание первой сетевой карты, для управления которой используется драйвер fxp(4). Страница руководства fxp(4) сообщает, что это сетевая карта Intel EtherExpress PRO. Далее следует ряд основных сведений об этой карте , включая слово UP, которое сообщает, что карта либо уже работает, либо пытается включиться в работу. Далее следует IP-адрес 198.22.63.43 , присвоенный этому интерфейсу, и сетевая маска 0xfffffff0  (или 255.255.255.240, согласно табл. 6.2). Здесь также приводится MAC-адрес  и скорость соединения . Наконец запись status сообщает, что данная сетевая карта активна à: кабель подключен и горит индикатор подключения.

Для второй сетевой карты rl0 утилита не выводит ничего подобного. Ключевым фактором здесь является отсутствие несущего сигнала (no carrier) : кабель не подключен и индикатор не горит. Эта карта не используется.

Последний сетевой интерфейс lo0 – это петлевой интерфейс. Данному интерфейсу на любом компьютере присваивается IP-адрес 127.0.0.1. Этот адрес используется для организации взаимодействия сетевых приложений, исполняющихся на одной и той же машине. Это стандартный программный интерфейс, который не связан с каким-либо аппаратным обеспечением. Не пытайтесь удалить петлевой интерфейс или присвоить ему другой IP-адрес – в этом случае многие приложения не смогут работать. FreeBSD поддерживает и другие программные интерфейсы, такие как disc(4), faith(4), gif(4) и многие другие.

Назначение IPадреса интерфейсу

В процессе установки системы выполняется настройка всех сетевых карт, имеющихся в компьютере. Если в ходе установки были настроены не все сетевые карты или если уже после установки были удалены существующие или добавлены новые сетевые карты, утилита ifconfig(8) позволит присвоить IP-адреса сетевым картам. Сетевой карте необходимо присвоить IP-адрес и сетевую маску.

# ifconfig interfacename IPaddress netmask

Например, предположим, что сетевой карте fxp0 необходимо присвоить IP-адрес 192.168.1.250 и установить сетевую маску 255.255.255.0; в этом случае необходимо запустить такую команду:

# ifconfig fxp0 192.168.1.250 255.255.255.0

Сетевую маску можно указывать в точечной нотации, как это сделано выше, или в шестнадцатеричном формате (0xfffffff0). Но, пожалуй, самый простой способ состоит в том, чтобы указать маску через символ слэша:

# ifconfig fxp0 192.168.1.250/24

Утилита ifconfig(8) способна выполнять и любые другие настройки сетевых карт, такие как выбор типа носителя сигнала и установка дуплексного режима. Перечень поддерживаемых типов носителей сигнала и порядок установки дуплексного режима можно найти в странице руководства к драйверу карты. Выбор типа носителя производится с помощью ключевого слова media, а установка дуплексного режима – с помощью ключевого слова mediaopt. Некоторые комбинации сетевых карт и сетевых коммутаторов не в состоянии автоматически «договориться» о параметрах подключения, поэтому иногда возникает необходимость вручную устанавливать скорость подключения и дуплексный режим с той или с другой стороны. Некоторые сетевые карты поддерживают как полудуплексный, так и полнодуплексный режимы на скорости 100 Mbps, но на скорости 10 Mbps – только полнодуплексный режим. (Стандарт Ethernet со скоростями от 1 гигабита требует, чтобы устройства сами договаривались о выборе режима, поэтому принудительная установка – не самый лучший вариант.) Некоторые сетевые карты имеют несколько разъемов или допускают подключение носителей разных типов к одному и тому же разъему. Безусловно, все необходимые настройки можно объединить в одной команде.

# ifconfig fxp0 192.168.1.250/24 media 1000baseTX mediaopt fullduplex

Чтобы настройки сохранялись после перезагрузки, следует добавить строку, которая сообщит системе все необходимые настройки, в файл /etc/rc.conf. Строка имеет вид ifconfig_имя_интерфейсааргументы ifconfig«. Например, настройка сетевой карты re0 могла бы выглядеть примерно так:

ifconfig_re0=»192.168.1.250 255.255.255.0 media 1000baseTX mediaopt full-duplex»

 

Как только будет найдена работающая конфигурация для интерфейса, достаточно просто скопировать аргументы ifconfig(8) в /etc/rc.conf.

Проверка интерфейса

Теперь, когда интерфейсу присвоен IP-адрес, попробуем выполнить ping, задав IP-адрес шлюза по умолчанию. Если ответ получен, как показано в следующем листинге, то машина успешно подключена к сети. Выполнение ping можно прервать, нажав клавиши Ctrl-C.

# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=1.701 ms 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.436 ms ^C
—192.168.1.1 ping statistics —
2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 1.436/1.569/1.701/0.133 ms

Если ответ не был получен, следовательно, ваш сетевой интерфейс не работает. Дело либо в плохом соединении (проверьте кабель и свечение индикатора), либо в неверной настройке интерфейса.

Установка маршрута по умолчанию

Маршрут по умолчанию – это адрес, по которому система по умолчанию (т. е. если не указано иного для конкретных внешних адресов – прим. научн. ред.) посылает весь трафик, который отправляется за пределы локальной сети. Если в результате использования команды ping с адресом маршрутизатора по умолчанию был получен ответ, можно установить этот IP-адрес в качестве маршрута по умолчанию с помощью команды route(8).

# route add default 192.168.1.1
Вот и все! Теперь ping должен проходить по любому IP-адресу Интернета.

Если в ходе установки системы вы не указали используемые серверы имен, то вместо имен хостов вам придется указывать их IP-адреса. Настройка DNS будет рассматриваться в главе 14, а пока замечательным источником IP-адресов могут служить корневые серверы имен, перечисленные в файле /etc/namedb/named.root.

Маршрутизатор по умолчанию, устанавливаемый при начальной загрузке системы, можно задать оператором defaultrouter в /etc/rc.conf:

defaultrouter=»192.168.1.1″

 

Несколько IPадресов на одном сетевом интерфейсе

Одна система FreeBSD может отвечать на запросы по нескольким IP-адресам на одном интерфейсе. Такая возможность широко применяется в серверах Интернета, особенно для защищенных (SSL) веб-сайтов. Возможно, один сервер должен поддерживать сотни или тысячи доменов, и ему нужен IP-адрес для каждого из них. Дополнительные IP-адреса можно добавить с помощью команды ifconfig(8) и ключевого слова alias. Сетевая маска для псевдонима (alias) всегда устанавливается равной /32, независимо от количества адресов в сети с основным адресом.

# ifconfig fxp0 alias 192.168.1.225/32

После запуска предыдущей команды дополнительные IP-адреса появятся в выводе команды ifconfig(8). Основной IP-адрес всегда идет первым, а за ним следуют псевдонимы:

# ifconfig fxp0
fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500

options=b<RXCSUM,TXCSUM,VLAN_MTU>

inet6 fe80::202:b3ff:fe63:e41d%fxp0 prefixlen 64 scopeid 0x1

inet 192.168.1.250 netmask 0xffffff00 broadcast 192.168.1.255

inet 192.168.1.225 netmask 0xffffffff broadcast 192.168.1.255

ether 00:02:b3:63:e4:1d

Остальные хосты, запустив команду ping с IP-адресами-псевдонимами, будут получать ответ от этого сервера.

Настроив псевдонимы, можно добавить еще один оператор ifconfig с параметрами их настройки в файл /etc/rc.conf:

ifconfig_fxp0_alias0=»192.168.1.225/32″

 

Единственное реальное различие между этой записью и стандартной записью rc.conf – это фрагмент alias0. Ключевое слово alias сообщает системе FreeBSD, что этот IP-адрес является псевдонимом, а 0 – это уникальный номер псевдонима. Каждый псевдоним, устанавливаемый в /etc/rc.conf, должен иметь уникальный номер, причем номера должны быть последовательными. Если пропустить какой-нибудь номер, то псевдонимы после пропуска не будут установлены при начальной загрузке. Это самая распространенная ошибка в конфигурировании интерфейсов; система FreeBSD требует перезагрузки так редко, что ошибки в /etc/rc.conf могут месяцами оставаться незамеченными!

Многие демоны могут выполнить привязку только одного IP-адреса, поэтому, чтобы иметь возможность обслуживать несколько IP-адресов, вам придется запускать несколько экземпляров программ. Например, named(8) (глава 14) способен привязать только один IP-адрес, но есть возможность запустить несколько экземпляров named(8) на одном компьютере, используя различные IP-адреса для каждого из экземпляров.

Переименование интерфейсов

FreeBSD присваивает сетевым интерфейсам имена, исходя из названия драйвера устройства, который используется для обслуживания сетевой карты. Это старая добрая традиция в мире UNIX, и она соблюдается в большинстве промышленных операционных систем. Некоторые операционные системы дают имена сетевым интерфейсам, исходя из их типа, например в Linux интерфейсы Ethernet получают имена eth0, eth1 ит.д. Иногда появляется необходимость переименовать интерфейс – либо для обеспечения соответствия стандартам, либо для большей наглядности. Например, представим, что имеется устройство с двенадцатью сетевыми интерфейсами, каждый из которых подключен к отдельной сети. Каждая сеть имеет свои имена, такие как test, QA и т. д. Определенно имеет смысл переименовать сетевые интерфейсы, чтобы их имена наглядно говорили о том, к какой сети подключен каждый из них.

Система FreeBSD отличается высокой гибкостью в выборе имен интерфейсов, но некоторые программы предполагают, что имя интерфейса – это короткое слово, за которым следует число. Такое положение дел едва ли изменится в ближайшем будущем, поэтому для интерфейсов желательно выбирать короткие имена, оканчивающиеся цифрой. Для переименования сетевого интерфейса используется ключевое слово name команды ifconfig(8). Например, чтобы переименовать интерфейс fxp1 в test1, можно было бы запустить следующую команду:

# ifconfig fxp1 name test1
Запустив после этого команду ifconfig(8) без аргументов, можно убе-

диться, что интерфейс был переименован.

test1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500

options=b<RXCSUM,TXCSUM,VLAN_MTU>


Чтобы сохранить эти изменения, следует добавить параметр ifconfig_

interface_name в файл /etc/rc.conf. ifconfig_fxp1_name=»test1″

Переименование интерфейсов во время загрузки FreeBSD должно производиться до назначения IP-адреса или других значений. То есть при настройке параметров интерфейса должно использоваться не старое, а новое имя. Полная настройка интерфейса, включая его переименование, может выглядеть примерно так:

ifconfig_fxp1_name=»dmz2″

ifconfig_dmz2=»192.168.1.2 netmask 255.255.255.0″

ifconfig_dmz2_alias0=»192.168.1.3″

 

DHCP

Существуют такие сети, в которых назначение IP-адресов компьютерам, включая и серверы, выполняется посредством протокола DHCP. Сервер DHCP выполняет назначение IP-адресов, сетевых масок, серверов имен и шлюзов по умолчанию. Если в вашей сети конфигурирование серверов производится посредством DHCP, вам необходимо настроить сетевую карту так, чтобы она принимала всю необходимую информацию с помощью DHCP, например, так:

ifconfig_fxp0=»DHCP»

 

Перезагрузка!

Теперь, когда все сетевые интерфейсы настроены, выполните перезагрузку системы, чтобы убедиться, что все параметры настройки, указанные в файле /etc/rc.conf, правильно устанавливаются во время загрузки. Если во время загрузки FreeBSD обнаружит ошибки в /etc/ rc.conf, особенно в настройках сети, вы не сможете взаимодействовать с системой с удаленного рабочего места. Лучше все ошибки выявить сразу, пока имеется доступ к серверу, чем потом терять часы работы.

Деятельность в сети

Теперь, когда подключение к сети установлено, как можно увидеть, что происходит в ней? Существует несколько способов заглянуть в сеть, и мы рассмотрим все эти способы по порядку. В отличие от многих коммерческих операционных систем, информацию о сети в системе FreeBSD можно получить с помощью команд netstat(8) и sockstat(1).

Текущая активность в сети

netstat(8) – это многоцелевая программа наблюдения за сетями, которая отображает различные сведения в зависимости от ключей, с которыми она была запущена. Наиболее часто возникает вопрос: «Какой объем трафика проходит через компьютер прямо сейчас?» Команда netstat(8) с ключом –w покажет количество пакетов и байтов, обработанных системой. Ключ –w принимает один аргумент – количество секунд между обновлениями. Ключ –d сообщит netstat(8) о необходимости включить в вывод информацию о сброшенных пакетах. Ниже представлена команда, которая заставляет netstat(8) обновлять информацию на экране каждые 5 секунд:

# netstat w 5 d
input (Total) output

packets  errs     bytes    packets  errs      bytes  colls  drops

34 0 44068 23 0 1518 à0 0 33 0 42610 23 0 1518 0 0

Сразу после ввода команды никаких видимых изменений на экране не происходит, но через несколько секунд выводится единственная строка с информацией. Первые три колонки описывают входящий трафик, а следующие три – исходящий. Здесь можно увидеть число пакетов, принятых с момента последнего обновления , число ошибок интерфейса при приеме входящего трафика с момента последнего обновления  и число байтов, принятых с момента последнего обновления . В следующих трех колонках выводится число пакетов, отправленных компьютером с момента последнего обновления , количество ошибок передачи с момента последнего обновления  и количество отправленных байтов . Далее выводится количество коллизий в сети, обнаруженных с момента последнего обновления à, и количество сброшенных пакетов . Например, в данном случае система приняла 34 пакета , начиная с момента запуска команды netstat –w 5 –d.

Через пять секунд netstat(8) вывела вторую строку, описывающую сетевую активность, начиная с момента вывода первой строки.

Интервал обновления информации можно регулировать по своему желанию. Если необходимо выводить сведения раз в секунду, просто запустите команду netstat –w 1 –d. Если достаточно интервала в одну минуту, запустите команду netstat –w 60 –d. Когда я занимаюсь мониторингом сетевой активности, наиболее подходящим для меня является интервал в пять секунд, однако вы сами быстро поймете, какой интервал лучше подходит для ваших нужд.

Чтобы остановить работу утилиты, нужно нажать комбинацию клавиш Ctrl-C.

Открытые порты

Другой не менее популярный вопрос: «Какие порты открыты и какие программы ожидают соединения на них?» В состав системы FreeBSD входит утилита sockstat(1). Этот дружелюбный инструмент позволит получить ответ на столь важный вопрос. Он покажет список активных соединений и портов, доступных для клиентов.

Программа sockstat(1) не только перечислит порты, доступные для соединения, но и другие порты (или сокеты) в системе. Так как основной интерес для нас представляют открытые порты для протокола TCP/IP версии 4, то нужно не забывать использовать ключ –4.1 Ниже приводится сокращенный вывод команды sockstat(1), запущенной на очень маленьком сервере:

 

Ключ –4 используется для протокола TCP/IP версии 4. Не забывайте, нас сейчас интересует только сеть, и мы игнорируем IPv6.

# sockstat 4
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS

mwlucas sshd
root sendmail  www httpd
root sshd
à root sshd
bind named

11872 4 tcp4 198.22.63.43:22 24.192.127.92:62937 11433 4 tcp4 *:25 *:*
9048 16 tcp4 *:80 *:*
573 3 tcp4 *:23 *:*

426   3   tcp4  *:22                *:*

275   20  udp4  198.22.63.8:53      *:*

 

В первой колонке выводится имя пользователя, с привилегиями которого исполняется программа, выполнившая привязку порта. Вторая колонка – это имя команды. Далее указаны идентификатор процесса (PID) программы и дескриптор файла, соответствующего сокету. В следующей колонке указано название транспортного протокола, который используется сокетом, – это либо tcp4 для TCP в TCP/IP версии 4, либо udp4 для UDP в TCP/IP версии 4. Далее выводится локальный IP-адрес с номером порта, а в последней колонке указываются IP-адрес и номер порта удаленной системы, в случае открытого соединения.

Взгляните на самую первую запись. Она соответствует работающей программе sshd . Страница справочного руководства sshd(8) рассказывает о демоне SSH. Основной демон sshd(8) запустил дочерний процесс от моего имени для обслуживания соединения с моей рабочей станцией, поэтому в списке имеется несколько экземпляров sshd(8) с различными идентификаторами процесса. В данном случае соединение установлено с локальным IP-адресом 198.22.63.43  и с портом TCP 22. Удаленный хост, участвующий в этом соединении, имеет IPадрес 24.192.127.92  и соединение выполнено с портом 62937. Это SSH-соединение было выполнено на локальный компьютер с удаленной системы.

В число других соединений входят Sendmail , сервер электронной почты, принимающий запросы на порту 25. Обратите внимание: в этой записи отсутствуют IP-адреса. Данный сокет ожидает получения запросов на соединение. Процесс httpd  ожидает получение запросов на порту с номером 80.

Наиболее проницательные читатели могут заметить, что на этом сервере имеются два демона SSH, ожидающие получения запросов на подключение, один на порту с номером 23  и другой на порту с номером 22 à. В файле /etc/services указывается, что SSH обычно работает с портом 22, а порт 23 зарезервирован за службой telnet. Любой, кто попытается подключиться с помощью команды telnet, будет подключен к демону SSH, который работает совсем не так, как ожидается. Наиболее подозрительные читатели могут предположить, что данный сервер SSH был настроен для компенсации недостатков в настройках межсетевого экрана, который фильтрует трафик, исходя из исходящего и входящего номеров портов, а не из фактически используемого протокола. (У меня нет комментариев по поводу таких утверждений.)

Последняя запись в списке соответствует серверу имен named , ожидающему запросы на порту с номером 53. Здесь видно, что прослушивание производится по протоколу UDP (а не TCP) и соединения принимаются на IP-адресе 198.22.63.8.

Подробнее об открытых портах

Утилита sockstat(1) предоставляет обзорную информацию о доступных сетевых службах, однако с помощью netstat(8) можно получать более подробные сведения об отдельных соединениях. Чтобы увидеть открытые сетевые соединения, можно использовать команду netstat(8) с ключом –a. Ключ –n сообщает команде netstat(8), что она не должна выполнять преобразование IP-адресов в имена хостов, – такое преобразование не только замедляет вывод информации, но и может породить неоднозначность полученных результатов. Наконец, параметр –f inet требует от netstat(8) беспокоиться только о сетевых соединениях. Ниже приводится пример вывода, полученного от команды netstat с того же компьютера, на котором только что был получен вывод команды sockstat(1):

# netstat na f inet
Active Internet connections (including servers)

Proto Recv-Q Send-Q  Local Address

Foreign Address     (state)

24.192.127.92.62937  ESTABLISHED

LISTEN

LISTEN

LISTEN

LISTEN

tcp4       0

tcp4       0

tcp4       0

tcp4       0

tcp4       0

udp4       0

48  198.22.63.43.22

0  *.25                   *.*

0  *.23                   *.*

0  *.80                   *.*

0  *.22                   *.*

0  198.22.63.43.53        *.*

 

Здесь нетрудно догадаться, какая программа к какому порту подключена. Первая колонка во всех записях – это название транспортного протокола, используемого сокетом, – здесь в большинстве случаев используется протокол TCP, и только в последней записи – UDP.

Колонки Recv–Q и Send–Q показывают, сколько байт в том или ином соединении ожидают обслуживания. Если в колонке Recv–Q ненулевые значения присутствуют постоянно, значит, система не может обрабатывать входные данные достаточно быстро. Точно так же постоянно присутствующие значения в Send–Q говорят о том, что либо сеть, либо другая сторона соединения не могут принять данные с той скоростью, с какой они посылаются. Случайные пакеты, ожидающие своей очереди, – это нормально. Исследуйте свою систему, чтобы определить, какая ситуация нормальна, а какая – нет.

Очевидно, что Local Address – это IP-адрес и номер порта локальной системы, на котором локальная система ожидает получение запросов на соединение. Сетевой порт находится в конце записи и отделяется от IP-адреса точкой. Например, 198.22.63.43.22 – IP-адрес 198.22.63.43 и порт 22. Если запись представлена как «звездочка, точка, номер порта», это означает, что система прослушивает этот порт на всех IPадресах. В приведенном примере система готова принимать соединения по указанным портам.

Колонка Foreign Address (внешний адрес) показывает удаленный адрес (remote address) и номер порта для каждого соединения.

Наконец, колонка (state) показывает состояние рукопожатия TCP. В данный момент не требуется знать все возможные состояния TCPcоединения; достаточно понять, какие из них являются нормальными. Состояние ESTABLISHED означает, что соединение установлено и данные, по всей видимости, передаются. Состояния LAST_ACK, FIN_WAIT_1 и FIN_WAIT_2 означают, что соединение закрывается. Состояния SYN_RCVD, ACK и SYN+ACK – это этапы нормального создания соединения. Состояние LISTEN говорит, что порт готов принимать входящие соединения. В предыдущем примере одно соединение TCP активно и четыре ожидают входящих соединений. Протокол UDP не устанавливает соединений, поэтому в данном листинге для этого протокола отсутствует информация о состоянии.

Ознакомившись с этой информацией и сопоставив ее со сведениями, полученными от sockstat(1), можно разобраться, какая программа ведет себя вполне нормально, а какая является узким местом в системе.

Если вас не интересуют сведения о сокетах, ожидающих входящие соединения, а интерес представляют только активные соединения, можно вместо ключа –a использовать ключ –b. Например, команда netstat –nb –f inet отобразит только установленные соединения с удаленными системами.

Пропускная способность сетевой подсистемы в ядре

Система FreeBSD оптимизирует сетевую работу с помощью mbufs. mbuf – это отдельный участок памяти ядра, выделенный для сетевых операций. При просмотре документации, описывающей сетевой стек FreeBSD, вы постоянно будете спотыкаться о термин mbuf, поэтому очень важно иметь хотя бы поверхностное представление об этом.

Во время загрузки FreeBSD автоматически выделяет память для нужд сетевой подсистемы, исходя из общего объема физической памяти. Предполагается, что если в системе имеется 4 Гбайт памяти, то было бы желательно выделить для нужд сетевой подсистемы больше памяти, чем ее выделяется на маломощном компьютере с 128 Мбайт памяти. Узнать, как FreeBSD распределяет эти ресурсы, можно с помощью команд netstat –s и netstat –m. Рассмотрим сначала самый короткий вариант.

Команда netstat –m позволяет получить общее представление об использовании памяти ядра для сетевой подсистемы. Полученные результаты делятся на две большие категории: как много памяти используется, и сколько запросов на соединение потерпело неудачу. Ниже приводится сокращенный вывод этой команды, который включает

Оптимизация производительности сети 219 в себя всего несколько примеров, но все они следуют одному и тому же

формату:

# netstat m

32/372/404/25600 mbuf clusters in use (current/cache/total/max) …
0/0/0 requests for mbufs denied (mbufs/clusters/mbuf+clusters) …

Здесь видно, сколько кластеров mbuf используется . Если вы сделали предположение, что они как-то связаны с mbufs, то вы были правы. Вам пока не обязательно точно знать, что такое кластеры mbuf, важно знать количество, которое может быть выделено , и что этот предел еще не достигнут.

Также здесь можно видеть количество запросов на выделение mbufs, отвергнутых ядром . В данном случае система не отвергла ни одного запроса, а это означает, что в ней отсутствуют проблемы производительности, связанные с нехваткой памяти. Если система начинает отвергать запросы на выделение mbufs, следовательно, в сетевой подсистеме ощущается нехватка памяти. О решении этой проблемы рассказывается в разделе «Оптимизация производительности сети» ниже.

Команда netstat –m производит всего с десяток строк результатов, а вот команда netstat –s выводит данные страница за страницей. Она выводит статистические данные о производительности для каждого из протоколов. Как и в случае с командой netstat –m, эти данные можно разбить на категории: как много было сделано и сколько проблем было обнаружено. Время от времени запускайте обе эти команды и просматривайте полученные результаты, чтобы быть в курсе событий и вовремя обнаруживать возникающие проблемы.

Оптимизация производительности сети

Как теперь, имея возможность увидеть, что происходит с сетевой подсистемой FreeBSD, можно повысить ее производительность? При рассмотрении вопроса оптимизации существует простое эмпирическое правило: ничего не предпринимать. Вообще производительность сетевой подсистемы ограничивается только возможностями аппаратных средств. С другой стороны, многие приложения не в состоянии обрабатывать данные с той же скоростью, с какой их поставляет сетевая подсистема. Если у вас появилась мысль о необходимости оптимизации производительности системы, скорее всего вы смотрите не в ту сторону. Прочитайте главу 19, где приводятся рекомендации для тех, кто занимается поиском узких мест.

Вообще говоря, сетевая подсистема нуждается в корректировке только в том случае, если вы испытываете сложности при работе в сети. Это означает, что вы должны иметь результаты работы команд netstat –m и netstat –s, которые явно указывают на нехватку ресурсов, выделяемых ядром. Если ядро начинает отвергать запросы или закрывать соединения из-за нехватки ресурсов, прочитайте рекомендации, которые приводятся в этом разделе. В первую очередь, при появлении проблем или при желании повысить производительность системы обратите внимание на аппаратные средства.

Оптимизация сетевых аппаратных средств

Не все сетевые устройства одинаковы. То, о чем часто слышал любой специалист в области информационных технологий, открытая природа FreeBSD делает очевидным. Например, ниже приводится комментарий, взятый из исходных текстов драйвера сетевой карты rl:

The RealTek 8139 PCI NIC redefines the meaning of ‘low end.’ This is

probably the worst PCI ethernet controller ever made, with the possible

exception of the FEAST chip made by SMC. The 8139 supports bus-master

DMA, but it has a terrible interface that nullifies any performance

gains that bus-master DMA usually offers.

(Перевод: Сетевая карта RealTek 8139 PCI по-новому заставляет оценить понятие ‘низкокачественный’. Это, пожалуй, самый худший PCI-контроллер Ethernet
из когда-либо производившихся, за исключением разве что чипа FEAST, выпускаемого компанией SMC. Карта 8139 поддерживает работу с DMA,

но интерфейс карты настолько ужасен, что сводит на нет весь выигрыш

в производительности, который обычно способна дать поддержка DMA.)

Этот комментарий может быть перефразирован так: «Эта карта не выдерживает никакой критики. Купите другую карту». Это самый едкий комментарий, который я видел в исходных текстах FreeBSD, впрочем, в наше время эти устройства очень сложно найти. В других драйверах содержатся более корректные комментарии в адрес других сетевых карт. Оптимизировать производительность сетевой подсистемы с помощью низкокачественных устройств – это все равно, что пытаться ставить гоночную трансмиссию на Chevrolet Chevette 1982 года. Скорее поможет замена дешевой карты. Например, Intel выпускает вполне приличные сетевые карты, эта компания предоставляет свой драйвер FreeBSD для своих проводных карт и обеспечивает поддержку сообществу FreeBSD, которая помогает сопровождать этот драйвер. (Беспроводные карты – это уже другая история.) Подобным же образом многие другие компании, выпускающие серверы, считают для себя обязательным использовать высококачественные сетевые карты. Некоторые компании не предоставляют никакой документации к своим устройствам, но поставляют свои драйверы для FreeBSD. Это означает, что драйвер наверняка будет работать, но вы впадаете в зависимость от поставщика при планировании будущих обновлений системы. Устройства от производителей, специализирующихся на выпуске недорогого потребительского сетевого оборудования, – это не самый лучший выбор для установки на высокопроизводительный сервер. В конце концов, обычный средний пользователь понятия не имеет, как выбирать сетевые карты, и в основном руководствуется ценой на изделие. Если у вас возникают сомнения, обращайтесь в архивы почтовых рассылок, где можно найти достаточно свежие рекомендации по выбору сетевых карт.

Точно так же в широких пределах варьируется и качество сетевых коммутаторов. Если в сопроводительной документации утверждается, что коммутатор поддерживает соединения со скоростями 10/100 Mbps, это совершенно не означает, что вы в действительности получите скорость 100 Mbps! У меня есть сетевой концентратор, рассчитанный на скорость 10 Mbps, который обеспечивает скорость всего 0.5 Mbps, и коммутатор на 100 Mbps, который дает всего 15 Mbps. Скорость работы коммутатора можно представить себе как протокол или язык: я могу заявлять, что говорю по-китайски, но через 20 лет после окончания обучения я смогу выговорить не более трех слов в минуту. Опять же, коммутаторы, предназначенные для домашнего пользования, не самый лучший выбор для использования в промышленных условиях.

Если замена устройств не решила ваших проблем, тогда читайте дальше.

Память

При принятии решения, какой объем памяти выделить для нужд сетевой подсистемы, FreeBSD исходит из общего объема физической памяти. Память, выделяемая для mbufs, не может использоваться для каких-либо других целей, поэтому выделение гигабайтов памяти под mbufs может негативно сказаться на общей производительности системы. Не следует корректировать число mbufs, если команда netstat –m явно не укажет на нехватку пространства под mbufs. Если сетевой подсистеме не хватает памяти, самый действенный способ ликвидировать эту проблему заключается в увеличении общего объема памяти компьютера. Это вынудит FreeBSD пересчитать объем для mbufs во время загрузки и тем самым решит проблему. В противном случае вы лишь переместите проблему в другую часть системы или в другое приложение. Можно было бы выделить больше памяти для сетевой подсистемы и посадить на голодный паек сервер базы данных. Если вы уверены в своих действиях, то можно предпринять следующее.

Распределением памяти для mbufs управляют два параметра sysctl – kern.maxusers и kern.ipc.nmbclusters. Первый из них, kern.maxusers, является настройкой, выполняемой на этапе загрузки. Система автоматически определяет соответствующее значение kern.maxusers во время загрузки, исходя из аппаратной конфигурации. Корректировка этого значения – пожалуй, лучший способ масштабировать систему в целом. В старых версиях FreeBSD значение kern.maxusers отвечало за предварительное выделение памяти для сетевой подсистемы, вследствие чего она становилась недоступной для решения других задач, поэтому чрезмерное увеличение значения kern.maxusers могло приводить к ужасным последствиям для других частей системы. В современных версиях FreeBSD предварительное распределение памяти для сетевой подсистемы не производится, а данное значение обозначает лишь верхний предел, до которого может расти объем памяти сетевой подсистемы. Если значение kern.maxusers слишком мало, в файле протокола /var/log/messages начнут появляться предупреждения (глава 19).

Числом mbufs, выделяемых системой, управляет параметр kern.ipc. nmbclusters. Хотя этот параметр и допускает настройку во время работы системы, тем не менее лучше устанавливать его на ранних этапах загрузки, добавив запись в файл /etc/sysctl.conf (глава 5). Это позволит отобрать память у других задач и передать ее сетевой подсистеме или наоборот. Если это значение выбрать слишком большим, это может привести к нехватке памяти для других задач и даже к аварийному завершению системы.

# sysctl kern.ipc.nmbclusters kern.ipc.nmbclusters: 25600

Память для mbufs выделяется блоками, которые называются nmbclusters (иногда mbuf clusters). Хотя размер одного блока mbuf может варьироваться, размер одного кластера остается постоянным и составляет порядка 2 Кбайт. С помощью несложных вычислений можно выяснить, сколько памяти выделяется для текущего количества nmbclusters, а затем рассчитать приемлемые значения для системы и приложений. В данном примере имеется 25600 nmbclusters, то есть ядро зарезервировало для нужд сетевой подсистемы порядка 50 Мбайт памяти. Это не так много, учитывая, что речь идет о ноутбуке с объемом памяти 1 Гбайт, но это слишком много для какого-нибудь антикварного Pentium.

Чтобы найти наиболее подходящее количество кластеров mbuf, нужно запустить netstat –m, когда сервер испытывает серьезную нагрузку. Во второй строке результатов вы получите число mbuf, находящихся в использовании, и общее их число. Если в периоды пиковой нагрузки сервер не использует полный объем доступных кластеров mbuf, следовательно, вы идете по ложному пути – прекратите эксперименты с mbufs и замените, наконец, аппаратные устройства.1 Например:

32/372/404/25600 mbuf clusters in use (current/cache/total/max)

В настоящий момент система использует 32 кластера , и в кэш были помещены 372 кластера , использовавшиеся ранее. При количестве кластеров, равном 404 , и общем объеме выделенной памяти 25600 кластеров  мы получаем, что используется всего 1,5 процента. Если это реальная нагрузка на систему, то имеет смысл уменьшить число nmbclusters. Однако есть вероятность, что ваш компьютер вообще имеет низкую нагрузку, тогда любая оптимизация не имеет смысла.

Мое личное эмпирическое правил гласит: сервер должен иметь такое количество mbufs, чтобы оно в два раза превосходило потребность при высокой нагрузке. Если сервер потребляет 25 000 кластеров в часы пик, значит общее число кластеров должно составлять 50 000, чтобы иметь возможность противостоять пиковым нагрузкам.

Планирование пропускной способности сетевой подсистемы

Придет день, когда к вам придет ваш шеф и спросит: «Какой нужен сервер, чтобы иметь возможность обслужить одновременно сто тысяч клиентов?» Я не смогу помочь вам в оценке объемов памяти, которая потребуется вашему приложению (ладно, ладно – я смогу это сделать, но это тема уже другой книги), но рассчитать объем памяти, необходимый для сетевой подсистемы, вам вполне по силам. Каждое TCP-соединение требует наличия приемного и передающего буфера, тогда как для входящих UDP-соединений требуется только приемный буфер. В ходе сеанса FreeBSD может изменять размеры этих буферов, но изначально они имеют размеры, заданные значениями по умолчанию. Узнать значения по умолчанию можно из параметров sysctl – net.inet.tcp.sendspace, net.inet.tcp.recvspace и net.inet.udp.recvspace.

# sysctl net.inet.tcp.sendspace net.inet.tcp.sendspace: 32768
# sysctl net.inet.tcp.recvspace net.inet.tcp.recvspace: 65536

# sysctl net.inet.udp.recvspace net.inet.udp.recvspace: 41600

Предположим, что у вас имеется веб-сервер, который должен обрабатывать одновременно сто тысяч подключений. Протокол HTTP работает поверх протокола TCP, поэтому для каждого соединения потребуется выделить приемный и передающий буферы. Для каждого соединения потребуется 96 Кбайт памяти (32 768 байт + 65 538 байт = 98 304 байт, или 96 Кбайт). Для одновременного обслуживания ста тысяч пользователей потребуется 9 Гбайт памяти (100 000 × 96 Кбайт = 9 Гбайт)! Кроме того, на этом компьютере должно работать какое-то приложение. Вам потребуется предусмотреть какое-то решение, связанное с распределением нагрузки или кэшированием данных, или готовьтесь писать чертовы объяснительные по поводу единственного компьютера.

Задайте следующий далее вопрос тому, кто попытается предположить, что вам придется одновременно обслуживать сто тысяч пользователей. Если только вы не работаете в Yahoo! или в одной из конкурирующих компаний, вам едва ли придется видеть такие нагрузки. Даже если у вашего веб-приложения и наберется 100 000 зарегистрированных пользователей, то они, скорее всего, никогда не будут работать с ним одновременно. Сколько денег вы готовы потратить, чтобы гарантировать работу в этом крайне редком случае?

Максимальное число входящих соединений

Ядро FreeBSD обеспечивает пропускную способность, необходимую для обработки определенного числа новых входящих TCP-соединений. Это ограничение не касается уже установленных и обрабатываемых подключений, оно относится к числу новых соединений, которые пытаются установить одновременно. Например, в это число не попадают веб-страницы, которые к настоящему моменту уже были отправлены клиентам, – сюда относятся входящие запросы, которые еще даже не достигли веб-сервера.

Параметр kern.ipc.somaxconn определяет максимальное число одновременных попыток установить соединение, которые будут обслужены системой. По умолчанию оно равно 128, что может оказаться недостаточным для веб-сервера, работающего под высокой нагрузкой. Если вы занимаетесь сопровождением высокопроизводительного сервера, который, как ожидается, будет получать более 128 новых запросов одновременно, скорее всего, вам потребуется увеличить этот параметр sysctl. Если от пользователей начинают поступать жалобы, что они не могут подключиться к серверу, причина может крыться в значении этого параметра. Конечно, очень немногие приложения способны принимать такое количество новых подключений, поэтому, прежде чем изменять этот параметр, вам, возможно, следует настроить само приложение.

Опрос

Механизм опроса берет проверенную временем идею прерываний и IRQ и выкидывает ее из окна, заменяя регулярными проверками сетевой активности. В классической модели, управляемой прерываниями, всякий раз, когда пакет поступает в сетевую карту, она требует от центрального процессора уделить ей внимание, генерируя прерывание. Процессор прекращает обычную последовательность операций и приступает к обработке этих данных. Это очень хорошо и даже желательно при условии, что карта не занимается обработкой трафика большого объема. Но как только система начинает иметь дело с огромными объемами данных, сетевая карта начинает генерировать прерывания непрерывно. Более эффективный способ заключается в том, чтобы ядро извлекало данные из сетевой карты через регулярные интервалы времени. Такая регулярная проверка называется опросом (polling). Вообще говоря, использовать механизм опроса полезно только в случае объемного трафика.

К моменту написания этих строк механизм опроса невозможно собрать в виде модуля ядра, так как он требует изменений в драйверах устройств. Также следует иметь в виду, что не все сетевые карты обладают поддержкой механизма опроса, поэтому обязательно ознакомьтесь с полным списком, который приводится в странице руководства polling(4). Чтобы активировать механизм опроса, следует добавить параметр DEVICE_POLLING в конфигурацию ядра. После перезагрузки системы разрешить использование механизма опроса отдельно для каждого из устройств можно с помощью команды ifconfig(8).

# ifconfig re0 polling

Точно так же, с помощью аргумента –polling, можно запретить использование этого механизма. Кроме того, команда ifconfig(8) показывает, был ли активирован механизм опроса для интерфейса.

Так как активация и деактивация механизма опроса возможны прямо в процессе работы системы, попробуйте активировать его в часы высокой нагрузки и проверить, не приведет ли это к повышению производительности.

Изменение размера окна

Для обслуживания входящих соединений система FreeBSD использует три буфера: net.inet.tcp.sendspace, net.inet.tcp.recvspace и net.inet.udp.recvspace. Гуру TCP/IP эти параметры настройки известны как размер окна (window size). При изменении размеров этих буферов изменяется и производительность сетевой подсистемы. Значения по умолчанию были выбраны не просто так: они работают. С увеличением размеров буферов увеличивается объем памяти ядра, которая должна выделяться для каждого соединения. Если одновременно не увеличить количество nmbclusters соответственным образом, может не хватить памяти для работы сетевых служб.

В версии FreeBSD 7.0 размеры этих буферов регулируются автоматически, в зависимости от сетевой нагрузки. В Интернете вам часто будут попадаться ссылки на информацию, описывающую порядок настройки этих параметров sysctl, но это лишь отзвуки многолетнего усовершенствования FreeBSD. В действительности вам не следует выполнять настройку этих параметров вручную.

Прочие способы оптимизации

В системе FreeBSD имеется порядка 150 параметров sysctl, которые имеют отношение к сетевой подсистеме. В ваших руках есть все необходимые инструменты, которые позволят оптимизировать систему до такой степени, что она вообще не будет пропускать трафик. Будьте крайне осторожны, экспериментируя с оптимизацией сетевой подсистемы. Многие параметры позволяют избавиться только от одного набора проблем, тут же принося другие. Некоторые производители программного обеспечения (например, Samba) рекомендуют вносить изменения в отдельные параметры настройки сети. Будьте осторожны с ними, прежде чем принять их как новые значения по умолчанию, обязательно проверяйте на появление побочных эффектов в других программах. TCP/IP очень, очень сложный протокол, и настройки по умолчанию, принятые в системе FreeBSD, отражают многолетний опыт тестирования и страданий системных администраторов.

Группировка сетевых адаптеров

Серверы сети становятся все более жизненно важными для бизнеса, и все более важной становится избыточность. У нас имеются избыточные жесткие диски на сервере и избыточная полоса пропускания в информационном центре, а как быть с избыточностью полосы пропускания на сервере? Операционная система FreeBSD может трактовать две сетевых карты как нечто единое целое, позволяя иметь несколько подключений к единственному коммутатору. Это обычно называется группировкой сетевых адаптеров (network adapter teaming). Группировка реализована в системе FreeBSD через lagg(4) – интерфейс агрегированного канала (link aggregation interface).

lagg(4) – это модуль ядра, который создает виртуальный интерфейс lagg0. Вы можете связать физические интерфейсы с интерфейсом lagg0, сделав их частью агрегированного канала. Существует возможность использовать lagg(4) и с единственным физическим интерфейсом, но создавать агрегированный канал имеет смысл только при наличии двух или более физических интерфейсов. lagg(4) позволяет реализовать бесшовный роуминг между проводными и беспроводными сетями, обеспечить устойчивость к отказам оборудования и поддержку несколько различных агрегатных протоколов.

Агрегатные протоколы

Не все сетевые коммутаторы поддерживают агрегатные протоколы. Система FreeBSD имеет базовую реализацию некоторых достаточно сложных и высокопроизводительных протоколов, а также включает основные параметры обеспечения отказоустойчивости. Я рекомендую три из них: Fast EtherChannel, LACP и failover. (Есть и другие схемы включения, о которых можно узнать в странице руководства lagg(4).)

Fast EtherChannel (FEC) – это агрегатный протокол, разработанный компанией Cisco, но он работает только с коммутаторами Cisco высокой и средней производительности, работающими под управлением операционной системы компании Cisco. Если у вас используется неуправляемый коммутатор, то вы не сможете использовать протокол Fast EtherChannel. Он очень сложен в настройке (на стороне коммутатора), поэтому я могу его порекомендовать только тем, у кого этот протокол используется как корпоративный стандарт.

Протокол управления агрегированным каналом (Link Aggregation Control Protocol, LACP) – это индустриальный стандарт построения агрегированных каналов. Физические интерфейсы объединяются в единый виртуальный интерфейс с пропускной способностью, приблизительно равной сумме пропускных способностей объединяемых физических интерфейсов. Протокол LACP обеспечивает превосходную отказоустойчивость, и практически все коммутаторы поддерживают его. Я рекомендую LACP, только если у вас отсутствует необходимость использовать Fast EtherChannel и ваш коммутатор способен обеспечить необходимую пропускную способность при использовании LACP.

Если ваш коммутатор «задыхается» при использовании LACP, используйте failover. При использовании метода failover трафик отправляется через один физический интерфейс. Если этот интерфейс выходит из строя, происходит переключение на следующий интерфейс из пула. Несмотря на то, что этот метод не дает увеличения пропускной способности, тем не менее вы получаете возможность подключить сервер к нескольким коммутаторам для повышения отказоустойчивости.

Так как LACP обычно является лучшим выбором, в наших примерах мы будем использовать именно его.

Настройка lagg(4)

Интерфейс lagg является виртуальным в том смысле, что в компьютере отсутствует физическое устройство, на которое можно было бы указать пальцем и сказать: «Это интерфейс lagg0». Прежде чем приступать к настройке, интерфейс сначала необходимо создать. FreeBSD позволяет создавать интерфейсы с помощью команды ifconfig intrfacename create, однако то же самое можно сделать с помощью оператора cloned_interfaces в файле /etc/rc.conf.

Настройка lagg(4) в файле rc.conf производится в три этапа: создание интерфейса, запуск в работу физических интерфейсов и их агрегирование. В следующем примере из двух гигабитных сетевых карт Intel em0 и em1 создается единственный интерфейс lagg0.

cloned_interfaces=»lagg0″

ifconfig_em0=»up»

ifconfig_em1=»up»

ifconfig_lagg0=»laggproto lacp laggport em0 laggport em1 192.168.1.1 netmask

255.255.255.0″

 

Сначала указывается имитируемый интерфейс lagg0; FreeBSD создаст его во время загрузки. Затем производится запуск интерфейсов em0 и em1, при этом их настройка не производится. Наконец интерфейсу lagg0 сообщается, какой агрегатный протокол будет использоваться, какие физические интерфейсы будут ему принадлежать, а также сетевые параметры интерфейса. Эти несколько строк в конфигурационном файле обеспечат вас отказоустойчивым Ethernet-соединением.

Это было длинное путешествие через исследование сетевых возможностей и вы, вероятно, узнали даже больше, чем предполагали. Давайте немного постоим на месте и рассмотрим основы обеспечения безопасности системы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Закончите арифметическое действие * Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.