Имена сервера задаются с помощью директивы server_name и определяют, в каком блоке server будет обрабатываться тот или иной запрос. См. также “Как nginx обрабатывает запросы”. Имена могут быть заданы точно, с помощью маски или регулярного выражения:
server < listen 80; server_name example.org www.example.org; . >server < listen 80; server_name *.example.org; . >server < listen 80; server_name mail.*; . >server < listen 80; server_name ~^(?.+)\.example\.net$; . >
При поиске виртуального сервера по имени, если имени соответствует несколько из указанных вариантов, например, одновременно подходят и имя с маской, и регулярное выражение, будет выбран первый подходящий вариант в следующем порядке приоритета:
- точное имя
- самое длинное имя с маской в начале, например “ *.example.org ”
- самое длинное имя с маской в конце, например “ mail.* ”
- первое подходящее регулярное выражение (в порядке следования в конфигурационном файле)
Имена с масками
Имя с маской может содержать звёздочку (“ * ”) только в начале или в конце имени, и только на границе, определяемой точкой. Имена “ www.*.example.org ” и “ w*.example.org ” являются некорректными, но их можно задать с помощью регулярных выражений, например, “ ~^www\..+\.example\.org$ ” и “ ~^w.*\.example\.org$ ”. Звёздочка может соответствовать нескольким частям имени. Имени с маской “ *.example.org ” соответствует не только www.example.org , но и www.sub.example.org .
Специальное имя с маской вида “ .example.org ” соответствует как точному имени “ example.org ”, так и маске “ *.example.org ”.
Имена, заданные регулярными выражениями
Регулярные выражения, используемые в nginx, совместимы с используемыми в языке программирования Perl (PCRE). Имя сервера, заданное регулярным выражением, должно начинаться с символа тильды:
server_name ~^www\d+\.example\.net$;
в противном случае оно будет рассматриваться как точное, или же, если выражение содержит звёздочку (“ * ”), то как имя с маской (и, скорее всего, некорректное). Не забывайте ставить специальные символы начала (“ ^ ”) и конца (“ $ ”) строки. По синтаксису они не требуются, но логически они могут быть нужны. Также заметьте, что все точки в доменных именах должны быть экранированы символом обратной косой черты. Регулярное выражение, содержащее символы “ < ” и “ >”, необходимо экранировать:
server_name "~^(?\w\d1,3>+)\.example\.net$";
иначе nginx откажется запускаться и выдаст сообщение об ошибке:
directive "server_name" is not terminated by ";" in .
К именованному выделению в регулярном выражении можно впоследствии обратиться через переменную:
server < server_name ~^(www\.)?(? .+)$; location / < root /sites/$domain; > >
Библиотека PCRE поддерживает именованные выделения, используя следующий синтаксис:
?< name > | Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 |
?’ name ‘ | Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 |
?P< name > | Python-совместимый синтаксис, поддерживается начиная с PCRE-4.0 |
Если nginx отказывается запускаться и выдаёт сообщение об ошибке:
pcre_compile() failed: unrecognized character after (?< in .
то это значит, что используется старая версия библиотеки PCRE и следует вместо этого попробовать синтаксис “ ?P< name > ”. Также можно использовать нумерованные выделения:
server < server_name ~^(www\.)?(.+)$; location / < root /sites/$2; > >
Однако такое использование должно ограничиваться простыми случаями как в примере выше, поскольку нумерованные выделения легко могут быть перезаписаны.
Прочие имена
Некоторые имена имеют специальное значение.
Если необходимо обрабатывать запросы без поля “Host” в заголовке в блоке server, который не является сервером по умолчанию, следует указать пустое имя:
server
Если директива server_name не задана в блоке server, то nginx будет использовать пустое имя в качестве имени сервера.
Версии nginx вплоть до 0.8.48 в этом случае использовали имя хоста (hostname) машины в качестве имени сервера.
Если имя сервера задано как “ $hostname ” (0.9.4), то используется имя хоста (hostname) машины.
Если в запросе вместо имени сервера указан IP-адрес, то поле “Host” заголовка запроса будет содержать IP-адрес, и запрос можно обработать, используя IP-адрес как имя сервера:
server < listen 80; server_name example.org www.example.org "" 192.168.1.1 ; . >
В примерах конфигурации серверов, обрабатывающих все запросы, встречается странное имя “ _ ”:
server
Оно не является каким-то особенным, это просто одно из множества некорректных доменных имён, которые никогда не пересекутся ни с одним из реальных имён. С тем же успехом можно использовать имена типа “ -- ” и “ !@# ”.
Версии nginx вплоть до 0.6.25 поддерживали специальное имя “ * ”, которое многими неверно воспринималось как имя сервера для обработки всех запросов. Оно никогда так не работало, и не работало как имя с маской. Это имя действовало так же, как сейчас действует директива server_name_in_redirect. Специальное имя “ * ” объявлено устаревшим, а вместо него следует использовать директиву server_name_in_redirect. Заметьте, что с помощью директивы server_name нельзя задать ни имя сервера для обработки всех запросов, ни сервер по умолчанию. Это является свойством директивы listen, а не server_name. См. также “Как nginx обрабатывает запросы”. Можно настроить серверы, слушающие на портах *:80 и *:8080, и указать, что один из них будет сервером по умолчанию для порта *:8080, а другой — для порта *:80:
server < listen 80; listen 8080 default_server; server_name example.net; . >server
Интернационализованные имена
Для указания интернационализированных доменных имён (IDNs) в директиве server_name следует указывать Punycode-представление имени:
server
Выбор виртуального сервера
Сначала соединение создаётся в контесте сервера по умолчанию. Затем имя сервера может быть определено на следующих стадиях обработки запроса, каждая из которых участвует в выборе конфигурации:
- предварительно во время операции SSL handshake согласно SNI
- после обработки строки запроса
- после обработки поля Host заголовка запроса
- если после обработки строки запроса или поля Host заголовка запроса имя сервера не было выбрано, то nginx будет использовать пустое имя в качестве имени сервера.
На каждой из этих стадий могут применяться различные конфигурации сервера. Таким образом, некоторые директивы следует указывать с осторожностью:
- в случае использования директивы ssl_protocols список протоколов задаётся библиотекой OpenSSL перед применением конфигурации сервера согласно имени, запрашиваемого через SNI. Таким образом, протоколы должны быть заданы только для сервера по умолчанию;
- директивы client_header_buffer_size и merge_slashes задействуются перед чтением строки запроса, таким образом они используют конфигурацию сервера по умолчанию или конфигурацию сервера, выбранного через SNI;
- в случае использования директив ignore_invalid_headers, large_client_header_buffers и underscores_in_headers, которые участвуют в обработке полей заголовка запроса, выбор сервера дополнительно зависит от того, была ли обновлена конфигурация сервера согласно строке запроса или полю заголовка Host ;
- ошибочный ответ будет обработан с помощью директивы error_page в том сервере, который в настоящий момент выполняет запрос.
Оптимизация
Точные имена, имена с масками, начинающиеся со звёздочки, и имена с масками, заканчивающиеся на звёздочку, хранятся в трёх хэш-таблицах, привязанных к слушающим портам. Размеры хэш-таблиц оптимизируются на фазе конфигурации таким образом, что имя может быть найдено с минимальным числом непопаданий в кэш процессора. Подробнее настройка хэш-таблиц обсуждается в отдельном документе.
В первую очередь имя ищется в хэш-таблице точных имён. Если имя не было найдено, то имя ищется в хэш-таблице имён с масками, начинающихся со звёздочки. Если и там поиск не дал результата, то имя ищется в хэш-таблице имён с масками, оканчивающихся на звёздочку.
Поиск в хэш-таблице имён с масками медленнее, чем поиск в хэш-таблице точных имён, поскольку имена сравниваются по доменным частям. Заметьте, что специальное имя с маской вида “ .example.org ” хранится в хэш-таблице имён с масками, а не в хэш-таблице точных имён.
Регулярные выражения проверяются последовательно, а значит являются самым медленным и плохо масштабируемым методом.
По вышеизложенным причинам предпочтительнее использовать точные имена, где это только возможно. Например, если к серверу наиболее часто обращаются по именам example.org и www.example.org , то эффективнее будет указать их явно:
server
нежели чем использовать упрощённую форму:
server
Если задано большое число имён серверов, либо заданы необычно длинные имена, возможно потребуется скорректировать значения директив server_names_hash_max_size и server_names_hash_bucket_size на уровне http. Значение по умолчанию директивы server_names_hash_bucket_size может быть равно 32, 64, либо другой величине, в зависимости от размера строки кэша процессора. Если значение по умолчанию равно 32 и имя сервера задано как “ too.long.server.name.example.org ”, то nginx откажется запускаться и выдаст сообщение об ошибке:
could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32
В этом случае следует увеличить значение директивы до следующей степени двойки:
http < server_names_hash_bucket_size 64; .
Если задано большое число имён серверов, то будет выдано другое сообщение об ошибке:
could not build the server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 32
В таком случае сначала следует попробовать установить server_names_hash_max_size в величину, близкую к числу имён серверов, и только если это не поможет или время запуска nginx станет неприемлемо большим, следует попытаться увеличить server_names_hash_bucket_size.
Если сервер является единственным сервером для слушающего порта, то nginx не будет проверять имена сервера вообще (а также не будет строить хэш-таблицы для слушающего порта). За одним исключением: если имя сервера задано регулярным выражением с выделениями, то nginx’у придётся выполнить это выражение, чтобы получить значения выделений.
Совместимость
- Специальное имя сервера “ $hostname ” поддерживается начиная с версии 0.9.4.
- Имя сервера по умолчанию является пустой строкой “” начиная с версии 0.8.48.
- Именованные выделения в именах серверов, заданных с помощью регулярных выражений, поддерживаются начиная с версии 0.8.25.
- Выделения в именах серверов, заданных с помощью регулярных выражений, поддерживаются начиная с версии 0.7.40.
- Пустое имя сервера “” поддерживается начиная с версии 0.7.12.
- В качестве первого имени сервера можно задать маску или регулярное выражение начиная с версии 0.6.25.
- Регулярные выражения в имени сервера поддерживаются начиная с версии 0.6.7.
- Имена с маской вида example.* поддерживаются начиная с версии 0.6.0.
- Специальная форма имени вида .example.org поддерживается начиная с версии 0.3.18.
- Имена с маской вида *.example.org поддерживаются начиная с версии 0.1.13.
автор: Игорь Сысоев редактор: Brian Mercer |
Лабораторная работа №5
Цель: Изучение классификации IP-адресов. Назначение масок подсети.
Методические указания и задания к лабораторной работе
Одной из наиболее важных тем при обсуждении стека TCP/IP является
IP-адресация. IP-адрес представляет собой числовой идентификатор, присваиваемый каждому компьютеру сети IP. Он отражает расположение
устройства в сети. IP-адрес является программным, а не аппаратным адресом — последний "зашит" в компьютере или плате сетевого интерфейса. IP-адреса позволяют хостам одной сети взаимодействовать с хостами другой сети вне зависимости от типов этих локальных сетей.
Перед подробным изучением IP-адресации нужно усвоить несколько
базовых понятий и терминов.
Термины IP-адресации
Byte (байт) 7 или 8 бит, в зависимости от использованной схемы проверки четности. В этой главе мы будем считать, что один байт всегда равен 8 бит.
Octet (октет) Всегда равен 8 бит (разрядам).
Network address (сетевой адрес) Точка назначения, используемая в маршрутизации пакетов к удаленной сети, например сетевые адреса 10.0.0.0,
172.16.0.0 и 192.168.10.0.
Broadcast address (адрес широковещательной рассылки) Используется приложениями и хостами для пересылки информации всем узлам сети. Примеры адресов широковещательной рассылки: 255.255.255.255 (всем узлам всех сетей), 172.16.255.255 (всем подсетям и хостам сети 17.16.0.0), 10.255.255.255 (широковещательная рассылка всем подсетям и хостам
Иерархическая схема IP-адресации
IP-адрес содержит 32 бита информации, которые разделяются на четыре однобайтовые (восьмибитовые) секции, иначе называемые октетами. Существуют три способа представления IP-адресов:
• Представление десятичными числами, разделенными точками, на-
• Двоичное представление, например
• Шестнадцатеричное представление, например АС 10 IE 38
Здесь показаны три формы представления одного и того же IP-адреса. Шестнадцатеричное представление используется реже, чем двоичное или десятичное, но все же применяется в некоторых программах, например, в реестре Windows IP-адреса компьютеров хранятся в шестнадцатеричном виде.
Для адресации выбрана иерархическая схема с тремя уровнями иерархии: сеть, подсеть и хост.
Для примера рассмотрим структуру телефонного номера. Первая его
часть (код региона) описывает обширную географическую область. Вторая часть (префикс) сужает эту область до зоны действия локальной телефонной станции. Последний сегмент (собственно номер телефона) определяет конкретное соединение. При IP-адресации также используется схема с тремя уровнями. Вместо того чтобы рассматривать 32-разрядную комбинацию как единый идентификатор, в адресе выделяются части для адреса сети и для адреса узла.
Адресация сетей
Адрес сети однозначно определяет сеть. В IP-адресах всех машин, подключенных к одной сети, указывается один и тот же адрес сети. Например, в IP-адресе 172.16.30.56 адресом сети может быть 172.16.
Адрес узла присваивается каждой машине сети. В отличие от адреса сети, описывающего группу устройств, адрес узла уникален и однозначно определяет конкретную машину сети. Адрес узла называют также адресом хоста. В приведенном примере адрес узла имеет вид 30.56.
Диапазон сетевых адресов класса А
Создатели схемы IP-адресации установили, что первый бит первого байта сетевого адреса сети класса А всегда выключен (т.е. равен 0). Следовательно, адреса класса А находятся между 0 и 127.
Диапазон сетевых адресов класса В
В сетях класса В спецификация RFC предписывает, что всегда должен
быть включен первый бит первого байта, однако второй бит должен быть выключен. Если выключить, а затем включить остальные шесть разрядов, то мы получим диапазон для сетей В:
Следовательно, сети класса В имеют в первом байте значения от 128
Диапазон сетевых адресов класса С
В сетях класса С спецификация RFC предписывает, что всегда должны
быть включены два первых бита первого октета. Найдем диапазон для сети класса С преобразованием из двоичного вида в десятичный:
Следовательно, если начало IP-адреса находится между 192 и 223, то
это адрес сети класса С.
Диапазоны сетевых адресов классов D и Е
Адреса в диапазоне между 224 и 255 зарезервированы для сетей классов D и Е. Класс D используется для многоадресных рассылок, а класс Е — для исследовательских разработок. Далее мы не будем возвращаться к этим классам адресов.
Диапазоны сетевых адресов для специального применения
Некоторые IP-адреса зарезервированы для специальных целей и сетевые администраторы не могут присвоить их узлам своих сетей.
Адреса класса А
В IP-адресе сетей класса А первый байт занимает адрес сети, а в трех последующих байтах размещается адрес узла. Формат IP-адреса сети класса А:
Например, в IP-адресе 49.22.102.70 адрес сети равен 49, а адрес узла — 22.102.70. Каждая машина этой сети должна иметь адрес сети, равный 49. Адрес сети класса А имеет длину 1 байт, причем его первый бит зарезервирован, но доступны оставшиеся семь разрядов. Это означает, что
можно создать не более 128 сетей класса А. Почему? Потому что каждый из семи оставшихся битов может принимать значение 0 или 1, т.е. существует 27 или 128 различных комбинаций.
Однако было решено, что нулевой адрес сети (0000 0000) резервируется для обозначения маршрута, выбранного по умолчанию. Однако из-за того, что нулевой адрес зарезервирован, диапазон становится уже: от 1 до 127. В результате реальное число сетей класса А равно 128-2, т.е. 126.
Под адрес узла в IP-адресе сетей класса А отведено 3 байта (24 разряда). В них можно разместить 16777216 различных двоичных комбинаций или адресов узлов. Поскольку адреса, состоящие только из нулей и только из единиц, зарезервированы, точное число узлов в сети класса А составляет 16777216 - 2=16777214.
Допустимые значения идентификаторов хостов в сети класса А
Рассмотрим пример определения допустимого идентификатора хоста для сетевого адреса класса А:
10.0.0.0 В сетевом адресе выключены все разряды, определяющие
10.255.255.255 Все разряды для хостов в широковещательном адресе.
Допустимое количество хостов находится в диапазоне между сетевым адресом и адресом широковещательной рассылки: от 10.0.0.1 до 10.255.255.254. Заметим, что допустимы идентификаторы хостов из всех нулей и 255. Для подсчета количества доступных адресов хостов нужно, помнить, что разряды хоста не могут быть все вместе включены или выключены.
Адреса класса В
В IP-адресе сетей класса В первые два байта занимает адрес сети, а в двух последующих байтах размещается адрес узла. Формат IP-адреса сети класса В:
Например, в IP-адресе 172.16.30.56 адрес сети равен 172.16, а адрес узла — 30.56.
Для адреса сети, состоящего из 16 разрядов, имеется 216 возможных комбинаций. Однако разработчики Интернета решили, что адрес сети класса В должен начинаться с комбинации 10. Поэтому свободными для формирования адреса остаются лишь 14 бит; это означает, что может су-
ществовать 214 или 16 384 сетей класса В.
Под адрес узла в IP-адресе сетей класса В отведено 2 байта. Поскольку
адреса, состоящие только из нулей и только из единиц, зарезервированы, точное число узлов в сети класса В равно 216 - 2=65 534.
Допустимые значения идентификаторов хостов в сети класса В
Рассмотрим пример определения допустимого идентификатора хоста длясетевого адреса класса В:
172.16.0.0 В сетевом адресе выключены все разряды, определяющие идентификатор хоста.
172.16.255.255 Все разряды для хостов в широковещательном адресе.
Допустимое количество хостов находится в диапазоне между сетевым
адресом и адресом широковещательной рассылки: от 172.16.0.1 до 172.16.255.254.
Адреса класса С
Первые три байта, в IP-адресе сетей класса С занимает адрес сети, и всего один байт остается для адреса узла. Формат IP-адреса сети класса С:
Например, в IP-адресе 192.168.100.102 адрес сети равен 192.168.100, а
Первые три разряда адреса сети класса С занимает комбинация 110.
Поэтому для формирования адреса остается лишь 24 - 3= 21 разряд. Та-
ким образом, может существовать 221 или 2 097 152 сетей класса С.
Под адрес узла в IP-адресе сетей класса С отведен 1 байт. Следователь-
но, в каждой сети класса С может быть 28 - 2=254 узла.
Допустимые значения идентификаторов хостов в сети класса С
Рассмотрим пример определения допустимого идентификатора хоста для сетевого адреса класса С:
192.168.100.0 В сетевом адресе выключены все разряды, определяющие идентификатор хоста.
192.168.100.255 Все разряды для хостов в широковещательном адресу.
Допустимое количество хостов находится в диапазоне между сетевым
адресом и адресом широковещательной рассылки: от 192.168.100.1 до 192.168.100.254.
Маска подсети
При применении схемы адресации с подсетями каждая машина сети должна знать, какая часть адреса хоста занята адресом подсети. Для этого на каждом компьютере создается маска подсети. Это 32-разрядное число, которое позволяет получателю пакета IP отделить идентификатор сети в IP-адресе от идентификатора хоста.
Администратор сети создает 32-разрядную маску подсети, состоящую
из 0 и 1. Единицы в маске подсети помечают позиции, относящиеся к адресам сети и подсети.
Не во всех сетях нужны подсети, т.е. иногда используются маски подсети по умолчанию (иными словами, в такой сети нет адресов подсетей).
Выделение подсетей в классе С
Существуют разные способы выделения подсетей, среди которых можно выбрать наиболее подходящий для себя. Сначала мы обсудим двоичный метод, а затем познакомимся с другим способом выделения подсетей.
В адресном пространстве класса С для определения хостов доступны
только 8 разрядов. Биты подсети отсчитываются слева направо без пропусков разрядов. Масками подсетей могут быть:
Спецификация RFC не разрешает использовать для подсетей только один разряд, поскольку он всегда будет либо включен, либо выключен, а это недопустимо. Следовательно, первой правильной маской подсети будет 192, а последней — 252, поскольку нужно не менее двух разрядов для указания хостов.
Двоичный метод: Выделение подсетей в классе С
Рассмотрим выделение подсетей в адресном пространстве класса С с помощью двоичного метода. Сначала следует выявить первую доступную маску подсети, которая заимствует два разряда. Например, можно использо-
Два разряда применяются для выделения подсетей, 6 разрядов определяют хосты в каждой подсети. Какими будут подсети? Поскольку разряды подсети не могут быть одновременно включены или выключены, допустимы только две подсети:
01000000=64 (все разряды хостов выключены)
10000000=128 (все разряды хостов выключены)
Корректные адреса хостов находятся между подсетями, за исключением вариантов, когда одновременно включены или выключены все разряды хостов.
Для выявления адресов хостов нужно сначала выключить все разряды
хостов в адресе, а затем включить их, чтобы найти широковещательный адрес подсети. Допустимые адреса хостов располагаются между двумя полученными адресами.
В таблице ниже показана подсеть 64, диапазон хостов и адрес широковещательной рассылки.
В таблице ниже показана подсеть 128, диапазон хостов и адрес широко-
Операция проста, но в наших примерах рассмотрен только случай с
двумя разрядами для подсети. Что делать, когда нужно 9, 10 или даже 20
разрядов? Рассмотрим альтернативный метод, пригодный для выделения большого количества подсетей.
Альтернативный метод:
Выделение подсетей в классе С
Установив маску подсети, следует определить количество подсетей, хостов и широковещательные адреса. Для этого нужно ответить на несколько простых вопросов:
1. Сколько подсетей формирует данная маска?
2. Сколько хостов будет в каждой подсети?
3. Каковы правильные подсети?
4. Каковы правильные хосты в каждой подсети?
5. Какие широковещательные адреса в подсетях?
Приведем примеры ответов на поставленные вопросы:
1. Сколько подсетей? 2х- 2 = количество_подсетей, где X равно количе-
ству маскируемых разрядов (т.е. единиц). Например, для 11000000
мы имеем 22 - 2, т.е. 2 подсети.
2. Сколько хостов в подсетях? 2х- 2 = количество_хостов_в_подсети,
где X равно количеству немаскируемых разрядов (т.е. нулей). Напри-
мер, для 11000000 мы имеем 26 - 2, т.е. 62 хоста в подсети.
3. Каковы корректные подсети? 256-маска_подсети = базовое_количество. Например, 256 - 192 = 64.
4. Каковы корректные хосты? Количество хостов равно разности между подсетями, минус "все нули" и "все единицы".
5. Каков широковещательный адрес в каждой подсети? Адрес широковещательной рассылки получается после включения всех разрядов
хостов, поэтому легко вычисляется для любой подсети.
Примеры выделения подсетей в классе С
Рассмотрим несколько примеров выделения подсетей в классе С с помощью рассмотренных выше методов.
Пример 1:255.255.255.192
Начнем с адреса подсети в классе С, который использовался в предыдущем примере (255.255.255.192), чтобы показать преимущество альтернативного метода над двоичным. В этом примере мы используем сетевой адрес 192.168.10.0 и маску подсети 255.255.255.192.
Не трудно получить ответы на пять основных вопросов:
1. Сколько подсетей? В 192 включены два разряда (11000000), поэтому
22- 2=2. (вычитание 2 связано с некорректными по определению адресами, в которых включены или выключены все разряды подсети).
2. Сколько хостов в подсети? Выключено 6 разрядов хоста (11000000),
следовательно, 26 - 2=62 хоста.
3. Какова правильная подсеть? 256-192=64 и мы получаем первую подсеть, а также базовое количество (переменную). Далее следует складывать эту переменную до тех пор, пока не будет достигнута маска
подсети. 64+64=128. 128+64=192, но это уже некорректная маска, поскольку в ней включены все разряды подсети. Итак, получаем две
подсети: 64 и 128.
4. Каковы правильные хосты? Они находятся между подсетями. Проще
всего выявить их адреса, записав адреса подсетей и адреса широковещательных рассылок.
5. Какие широковещательные адреса в подсетях? Это число находится
перед следующей подсетью и имеет включенными все биты хостов.
В таблице ниже показаны подсети 64 и 128, диапазон хостов в каждой
из них и широковещательные адреса в каждой подсети.
Мы получили те же ответы, что и в двоичном методе, но нам уже не пришлось прибегать к преобразованию числа из двоичного вида в десятичный. Однако этот метод не всегда будет проще двоичного. Для первой подсети, где только два разряда подсети, двоичный метод будет удобнее. Возможно, следует хорошо изучить оба метода, поскольку часто
приходится выполнять вычисления о подсетях в уме.
Остальные примеры вычисления масок можно найти в литературе:
1) CCNA Cisco Certified Network Associate Учебное руководство, Экзамен
640-507, Тодд Леммл, Издательство "Лори", 2002 г.
Какие адреса из приведенного ниже списка не являются допустимыми адресами хостов?
Укажите, какие адреса из приведенного ниже списка не являются допустимыми адресами хостов. Обоснуйте ответ.
а) 0.10.10.10 /16 – первый октет не может быть нулевым
б) 10.0.10.10 /18
в) 10.10.0.10 /24
г) 10.10.10.10 /18
д) 127.0.127.127 /16 – недопустим
е) 127.0.127.0 /8 – недопустим и 0 значение
ж) 255.0.200.1 /16 - нельзя использовать
з) 1.255.0.0 /24 - нельзя использовать
и) 192.168.255.0 /24 –
к) 192.168.255.0 /23 –
л) 167.234.56.13 /16 - может
м) 224.0.5.3 /20 может, сеть класса D
н) 172.34.267.34 /18
о) 230.0.0.7 /8 – может
п) 160.54.255.255 /16
р) 160.54.255.255 /12
с) 160.54.255.255 /24
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Какие из ниже приведенных отношений на Z являются рефлексивными, симметричными, а какие транзитивными
~ 1. Определите, какие из ниже приведенных отношений на Z являются рефлексивными, симметричными, а.
Какие из перечисленных ниже множеств являются бинарными соответствиями?
Какие из перечисленных ниже множеств являются бинарными соответствиями, определить свойства.
Определите, какие из приведенных ниже отношений z являются рефлексивными, симметричными , транзитивными
Определите, какие из приведенных ниже отношений z являются рефлексивными, симметричными .
Почему при выводе односвязного списка на экран он выдаёт ещё какие-то дополнительные адреса?
Здравствуйте, помогите пожалуйста разобраться, почему при выводе односвязного списка на экран он.
860 / 433 / 128
Регистрация: 20.04.2014
Сообщений: 1,117
Сообщение от Катя6
Укажите, какие адреса из приведенного ниже списка не являются допустимыми адресами хостов. Обоснуйте ответ.
а) 0.10.10.10 /16 – первый октет не может быть нулевым
б) 10.0.10.10 /18
в) 10.10.0.10 /24
г) 10.10.10.10 /18
д) 127.0.127.127 /16 – недопустим
е) 127.0.127.0 /8 – недопустим и 0 значение
ж) 255.0.200.1 /16 - нельзя использовать
з) 1.255.0.0 /24 - нельзя использовать
и) 192.168.255.0 /24 –
к) 192.168.255.0 /23 –
л) 167.234.56.13 /16 - может
м) 224.0.5.3 /20 может, сеть класса D
н) 172.34.267.34 /18
о) 230.0.0.7 /8 – может
п) 160.54.255.255 /16
р) 160.54.255.255 /12
с) 160.54.255.255 /24
б, в, г - норм
и - сеть
к - норм
м - не годится, мультикаст
н - норм
п - directed broadcast
р - норм
Регистрация: 18.03.2019
Сообщений: 689
Korax, что значит сеть, directed broadcast? Вопрос был в том, что допустим или нет, если нет, то почему?
860 / 433 / 128
Регистрация: 20.04.2014
Сообщений: 1,117
Сообщение было отмечено Катя6 как решение
Решение
Сообщение от Катя6
Korax, что значит сеть, directed broadcast? Вопрос был в том, что допустим или нет, если нет, то почему?
Что ж непонятного?
"сеть" - использовать нельзя, это адрес сети (узловая часть адреса - из бинарных нулей)
"directed broadcast" - использовать нельзя, это адрес широковещательный (broadcast)
в IPv4 два типа широковещательных адресов - directed/targeted (узловая часть адреса - из бинарных единиц) и limited (все единицы - 255.255.255.255)
Определение IP адреса
Значение REMOTE_ADDR : 95.214.216.82
HTTP заголовки, которые могут содержать информацию об IP адресе:
HTTP_CLIENT_IP : не установлено
HTTP_X_FORWARDED_FOR : не установлено
HTTP_VIA : не установлено
HTTP_X_REAL_IP : не установлено
Беллетристика
Один из самых дремучих вопросов в околопхпешном вебе - это определение IP адреса.
Такого количества неправильного кода не написано, наверное, ни для какой другой операции.
Каждый, кто в один прекрасный день узнаёт о существовании переменной HTTP_X_FORWARDED_FOR, тут же воображает себя мегагуру, и заменяет ей REMOTE_ADDR. Потом приходит знание о других переменных (X_REAL_IP, VIA, и ещё вагон и маленькая тележка), изобретаются многослойные мегаконструкции, изобретатели хвастаются друг перед другом их многоэтажностью и сравнивают свои творения с "кодом из PHPbb!".
При этом спроси любого из них - "какой именно адрес они хотят определить?" - ни один не ответит: понимание основ функционирования сети TCP/IP среди пхп-программистов традиционно слабое.
А вот стремление к нахождению Идеального и Единственно Правильного Решения - традиционно сильное.
В результате вместо IP адреса в логи пишется не пойми что.
К примеру, возьмем, казалось бы, простой вопрос "какой именно IP адрес (из цепочки хостов, через которые идет запрос от компьютера клиента к серверу) мы хотим записать в лог?". После того, как выяснилось, что большинство пхп-программистов затрудняются на него ответить, я и решил написать эту заметку.
А это, между прочим, очень важный вопрос. Не ответив на него, наряду с вопросом "Зачем нам нужен IP адрес?", приступать к самому определению бессмысленно.
При том, что большинству читателей этого текста вопросы покажутся бессмысленными.
Ну что ж, попробуем разобраться.
Теория
Во-первых. Самые азы. Для тех, кто не знает.
Все элементы массива $_SERVER, начинающиеся со слова "HTTP_" - это HTTP-заголовки.
Как уже знают вдумчивые читатели фака на танке, HTTP заголовки присылает клиент. И прислать может любые.
К примеру, заголовок X-All-Your-Base-Belongs-To-Us: Surrender!
Или, как вы уже, наверное, догадались, заголовок X-Forwarded-For: admin durak
Мне кажется, что записывать столь глубокомысленную строку вместо IP адреса - не самая лучшая идея.
Как и вообще доверять любым переменным, начинающимся с HTTP. Это первое правило, которое надо запомнить с молоком матери: Любые элементы массива $_SERVER, начинающиеся с "HTTP_", можно использовать только в справочных целях! К примеру, HTTP_REFERER записываем, чтобы потом посмотреть. Но ни в коем случае не делаем на него Location.
Во-вторых, определимся с тем, ДЛЯ ЧЕГО нам нужен IP адрес. Если мы хотим записать в лог, то пишем однозначно только REMOTE_ADDR. В этой переменной содержится реальный IP адрес реального хоста в интернете, который произвел соединение с нашим сервером. Единственный реальный адрес. Никаких других сервер не знает.
Апач пишет в логи именно REMOTE_ADDR. Не надо считать авторов веб-сервера дурнее себя.
Что значит - реальный IP адрес? А то и значит. Адрес хоста, который произвел соединение с нашим сервером. Этот адрес по определению может быть только один. Один, а не 5 по цепочке. Рассмотрим типичный пример:
Есть пользовательский компьютер, который, который находится в офисной сети. IP компьютера 192.168.0.22
Офисная сеть включена через роутер в сеть здания. IP роутера - 10.10.0.3
Сеть здания, в свою очередь, подключена к интернету, через роутер. IP роутера - 77.88.22.11
Пользователь заходит на сайт, через НТТР прокси. IP прокси - 212.121.0.8
Так вот, сеть TCP/IP так устроена, что каждый следующий узел ничего не знает о предыдущих. Есть только пара хостов, которые соединяются друг с другом. В самих TCP/IP пакетах никакой информации о предыдущих хостах не предусмотрено.
Поэтому, как это ни обидно, но реальным адресом мы можем считать только последний в цепочке - адрес HTTP прокси.
Больше того. Ну допустим, узнали мы адрес компьютера пользователя (чем кичатся многие определители с помощью activeX и ява-апплетов). Этот адрес - 192.168.0.22. Он из приватной сети. Компьютеров с такими адресами в мире - миллионы. Найти компьютер по такому адресу - невозможно. Пользы от него - практически никакой. Практически, но не совсем. Почему? Слушаем дальше:
Поскольку в протоколе HTTP текстовые заголовки, то в них можно добавить свой. Что некоторые хосты и делают. В те самые X-Forwarded-For, Via и прочие.
Можем мы их использовать? Можем. Если правильно понимать - для чего.
Для определения "реального IP адреса", как мы уже убедились - нельзя. А для чего же можно? Например - справки. просто записать, на всякий случай. НО! Только в том случае, если мы откажемся от дурацкой идеи найти один идеальный IP адрес. Если мы не будем писать вместо реального всякую лабуду, а будем записывать все похожее на IP адрес с реальным наряду, то почему нет?
Итак, можно записать всё, похожее на IP адрес. Понадобится выявить злостного вредителя - возможно, какой-то интересный айпишник среди заголовков и проскочит.
Для небольшого повышения надежности сессий - тоже можно. Писать в сессию не только реальный, но и все похожие. И все сверять. Хоть один не совпал - сессию рубим.
И в других подобных случаях.
Не забывая: реальный - отдельно, все похожее на IP адрес - отдельно.
Не забывая: особо полагаться на все эти заголовки не стоит.
Практика.
Итак. Из всего вышеизложенного делается простой вывод.
IP адрес в скрипте может быть только один. Лежит он в переменной REMOTE_ADDR.
Следовательно, вожделенный код получания "идеального IP адреса" выглядит, как
$ip=$_SERVER['REMOTE_ADDR']
Точка.
Далее. Если мы хотим воспользоваться "заголовками, похожими на IP адрес" (лучше всего, во избежание недоразумений, совсем не считать их адресами хостов, а HTTP заголовками особого формата. Тем более, что никакого стандарта на содержимое заголовков X-Forwarded-For, Via и прочих - нет. Там могут оказаться IP адреса чарез запятую, или доменные имена или не через запятую. Не говоря уже о подделках!), то нет смысла судорожно искать все имена заголовков, где может встретиться адрес. Проще искать сами адреса.
Берем, пишем простой код, который в цикле перебирает массив $_SERVER, и регулярным выражением выцепляет все заголовки, в которых встречается подхдящая под шаблон IP адреса строка. Если встретилась, то весь заголовок - с именем и всем содержимым - добавляем в массив или в строку. Которая хранится отдельно от IP адреса, в текстовом виде.
Соответственно, в нужном месте повторяем операцию, и сверяем. IP адрес с IP адресом, строку похожих заголовков - со строкой похожих заголовков.
function get_all_ip() $ip_pattern="#(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)#";
$ret="";
foreach ($_SERVER as $k => $v) if (substr($k,0,5)=="HTTP_" AND preg_match($ip_pattern,$v)) $ret.=$k.": ".$v."\n";
>
return $ret;
>
Такой вот, несложный код.
Правда, нужда в нем, если задуматься, очень невелика. Разве что, для тех же сессий. А для справки, про запас. не проще ли писать вообще все HTTP заголовки, пришедшие в скрипт? И это поинформативнее будет, чем выцеплять какой-то один адрес из HTTP_X_REAL_IP.
Да и для сессий следует применять с осторожностью - IP адрес может оказаться, к примеру, в реферере.
Примечания.
Недавно я выяснил удивительную вещь. Оказывается, на свете существуют криворукие хостеры, у которых на сервере нет REMOTE_ADDR (а точнее есть, но в нем лежит. адрес самого сервера!). И пихают они адрес удаленного хоста кому куда бог на душу положит. Некоторые - вы будете смеяться - в HTTP_X_FORWARDED_FOR. Говорят, в некоторых больших программных продуктах есть даже специальная настройка для таких случаев - "Получать IP-адреса из заголовка X_FORWARDED_FOR".
Разумеется, этот курьёз не опровергает сказанного выше, и не стоит кидаться писать автоматические определители IP с его учетом. Все подобные случаи должны разбираться только в ручном режиме, самим программистом. Который сначала убедится - где именно в HTTP_X_FORWARDED_FOR лежит нужный адрес - в начале цепочки запятых или в конце, напишет правильный рег, и только потом в настройки сайта добавит код
$_SERVER['REMOTE_ADDR']=get_ip_from_xff();
Примечание для хостеров: mod_realip или mod_rpaf
Примечание для пользователей: разумеется, таких хостеров надо избегать, как калёного железа. Наверняка ведь это не единственная их криворукость?