12k
All articles

Понимание нотации CIDR и диапазонов IP-адресов

Объяснение CIDR, IP-диапазонов и расчета подсетей для IPv4 и IPv6. Как читать префиксы, задавать размер сети и избегать пересечений и открытых правил.

OpenReplay Team
OpenReplay Team
Понимание нотации CIDR и диапазонов IP-адресов

Нотация CIDR записывается как address/prefix, где префикс — это количество старших битов, закреплённых за сетевой частью. Так, в 10.0.0.0/16 первые 16 битов определяют сеть, а остальные 16 свободны для хостов.

Большинство людей усваивают это на горьком опыте — примерно на третий раз, когда security group молча блокирует трафик, а виновником оказывается префикс, отличающийся на одну цифру. Эта единственная строка — почти всё, что нужно знать, чтобы перестать копипастить 10.0.0.0/16 в Terraform-файл и начать понимать смысл записи. В этой статье вы получите мысленную модель, двухшаговый расчёт для перехода от префикса к используемому диапазону и количеству хостов, а также разбор мест, где веб- и full-stack-разработчик реально сталкивается с CIDR (определение размера VPC, правила security group, allowlist’ы и сети контейнеров), включая подводные камни, которые незаметно ломают связность.

Ключевые выводы

  • Нотация CIDR — это address/prefix; префикс считает старшие сетевые биты, а не общее количество битов в адресе.
  • Количество используемых хостов в блоке IPv4 равно 2^(32 − prefix) − 2: /24 даёт 254, /26 даёт 62, а /30 даёт 2 — за вычетом адреса сети и широковещательного адреса.
  • 0.0.0.0/0 (IPv4) и ::/0 (IPv6) означают любой адрес: разрешающее правило с областью 0.0.0.0/0 для SSH или порта базы данных открывает их всему интернету.
  • RFC 1918 закрепляет три приватных диапазона, которые постоянно встречаются в облачных и контейнерных конфигурациях: 10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/16.
  • Две сети, которые вы собираетесь связать через peering или VPN, не должны использовать перекрывающиеся блоки CIDR, иначе маршрутизация к общим адресам становится неоднозначной.

Что такое нотация CIDR?

Нотация CIDR (Classless Inter-Domain Routing) описывает сеть как IP-адрес, за которым следует слеш и длина префикса, где длина префикса — это количество старших битов, закреплённых за сетевой частью. Она заменила жёсткую систему классов A/B/C, благодаря чему блоки могут иметь любой размер, а не привязываться к границам 8, 16 или 24 битов. Схема была введена в 1993 году в RFC 1519 и консолидирована в действующем на сегодня документе RFC 4632 в 2006 году. Префикс — это не общее количество битов в адресе; это распространённое заблуждение. В 192.168.129.23/17 запись /17 означает, что первые 17 битов — сетевые, а на хосты остаётся 15.

Битовая модель: сетевые биты и биты хоста

Адрес IPv4 — это 32-битное число, разделённое на четыре 8-битных октета, и префикс /n проводит линию через эти 32 бита: всё слева от линии — фиксированная сетевая часть, всё справа — переменная часть хоста. Сдвиньте линию вправо (больший префикс) — получите больше сетей меньшего размера; сдвиньте влево — меньше сетей, но крупнее.

Возьмём 10.0.1.0/24. /24 отрезает после третьего октета, поэтому первые 24 бита зафиксированы, а последние 8 — ваши:

00001010 . 00000000 . 00000001 . 00000000
└──────── network (24 bits) ──────┘ └ host ┘
   10          0          1        0–255

Эти 8 битов хоста принимают значения от 00000000 до 11111111: 256 комбинаций, от 10.0.1.0 до 10.0.1.255. Только префикс определяет, где проходит разрез.

Сколько хостов в блоке CIDR?

Количество используемых хостов в блоке IPv4 равно 2^(32 − prefix) − 2: /24 даёт 254, /26 даёт 62, а /30 даёт 2, причём вычитаются адрес сети (все биты хоста 0) и широковещательный адрес (все биты хоста 1) — ни один из них нельзя назначить хосту. Сначала вычислите общее число адресов (2^(32 − prefix)), затем вычтите два.

ПрефиксВсего адресовИспользуемых хостовГде встречается
/1665 53665 534Целый VPC
/24256254Стандартная подсеть
/266462Уровень (tier) внутри подсети
/3042Двухточечное соединение
/3122Двухточечное соединение (RFC 3021)
/3211Маршрут к одному хосту

На практике важны два исключения из правила −2: /31 даёт 2 используемых адреса, потому что RFC 3021 отменяет резервирование адреса сети и широковещательного адреса на двухточечных соединениях, а /32 — это маршрут к одному хосту, форма записи, которой вы указываете один конкретный IP в правиле файрвола или allowlist’а.

Чтение блока CIDR на практике

Чтобы прочитать блок вида 10.0.1.0/24: адрес сети — 10.0.1.0, широковещательный — 10.0.1.255, а используемый диапазон — от 10.0.1.1 до 10.0.1.254. Рецепт состоит из четырёх шагов: (1) префикс говорит, сколько битов зафиксировано; (2) установите остальные биты хоста в 0 — получите адрес сети; (3) установите их в 1 — получите широковещательный адрес; (4) всё между ними — используемые адреса.

Чтобы пойти в обратном направлении, от требования по количеству хостов к префиксу, выберите наименьший блок, чьё количество используемых адресов покрывает вашу потребность. Нужно место для 30 устройств? /27 даёт 30 используемых; /28 даёт всего 14, значит ответ — /27. Проверить любой блок можно с помощью модуля стандартной библиотеки Python ipaddress, устанавливать ничего не нужно:

python3 -c "import ipaddress; n=ipaddress.ip_network('10.0.1.0/24'); print(n.network_address, n.broadcast_address, n.num_addresses)"
# 10.0.1.0 10.0.1.255 256

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

Если не хочется идти в терминал, калькулятор CIDR от OpenReplay выполняет то же самое разложение в браузере. Вставьте блок вида 10.0.0.0/16 — и получите адрес сети и широковещательный адрес, маску и wildcard-маску, первый и последний используемый хост, а также общее количество адресов. Инструмент поддерживает IPv4 и IPv6 и использует арифметику больших целых чисел, поэтому крупные блоки и диапазоны IPv6 возвращаются точно. Все вычисления выполняются локально, так что внутренние диапазоны никогда не покидают вашу машину.

Где разработчики действительно сталкиваются с CIDR

Большинство разработчиков встречает CIDR в облачных и прикладных конфигурациях задолго до того, как увидит его в таблице маршрутизации. RFC 1918 закрепляет три приватных диапазона, которые вы будете видеть постоянно (10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/16), ни один из которых не маршрутизируется в публичном интернете — именно поэтому облачные VPC и сети Docker берут адреса оттуда. Четыре сценария покрывают почти всё, с чем вам придётся иметь дело:

  • Определение размера VPC и подсетей. Вы задаёте блок при создании и нарезаете из него подсети. Блок IPv4 у AWS VPC должен быть в пределах от /16 до /28, и каждая подсеть резервирует первые четыре адреса плюс последний (пять, а не два), поэтому подсеть /24 в AWS даёт 251 используемый адрес, а не 254. Универсальное −2 — это верхняя граница, а не гарантия.
  • Правила файрвола и security group. Правила задаются в терминах CIDR, например: разрешить входящий трафик на порт 5432 только с 10.10.1.0/24 — чтобы уровень базы данных принимал трафик Postgres от веб-уровня и ни от кого больше.
  • Allowlist’ы и denylist’ы в конфигурации приложения. CORS-origin’ы, правила WAF, диапазоны источников в API-шлюзе и директивы allow/deny в nginx — все они принимают блоки CIDR. Слишком узкий префикс молча блокирует легитимных клиентов; в session replay таких реализаций сбой часто проявляется как заблокированные или падающие запросы, которые сводятся к одному неверному префиксу.
  • Подводный камень перекрывающихся CIDR. Две сети, которые вы собираетесь связать через peering или VPN, не должны использовать перекрывающиеся блоки CIDR, потому что у хоста не может быть двух однозначных маршрутов к одному и тому же адресу. Выделите каждой свой непересекающийся диапазон RFC 1918, скажем 10.10.0.0/16 и 10.20.0.0/16.

Одно значение стоит запомнить: 0.0.0.0/0 в IPv4 (и ::/0 в IPv6) означает любой адрес. Это полезно для маршрута по умолчанию и опасно в качестве разрешающего входящего правила: 0.0.0.0/0 на порту 22 или 5432 — это открытая дверь для всего интернета.

IPv6 использует ту же нотацию

IPv6 применяет идентичную нотацию со слешем к 128-битным адресам, и /64 — стандартный размер подсети, оставляющий 64 бита на хосты внутри каждой подсети. Относитесь к /64 как к соглашению, а не закону: это не универсальный инвариант, и даже AWS допускает маски подсетей IPv6 от /44 до /64 с шагом /4. Логика разделения битов абсолютно та же. Просто адрес длиннее.

Читайте префикс как количество сетевых битов, применяйте 2^(32 − prefix) − 2 для подсчёта используемых хостов IPv4, помните про исключения /31, /32 и облачные резервирования и не допускайте перекрытия связанных сетей. Сделайте это — и сможете подобрать размер подсети или проверить правило файрвола, не хватаясь за калькулятор. В следующий раз, когда блок CIDR появится в pull request, разберите его с первого взгляда и проверьте, действительно ли этот /0 должен там быть.

Часто задаваемые вопросы

В чём разница между маской подсети вида 255.255.255.0 и префиксом CIDR вида /24?

Это два способа выразить одну и ту же границу. Маска подсети — это 32-битное значение, где сетевые биты равны 1, а биты хоста равны 0, поэтому 255.255.255.0 в двоичном виде — это 24 единицы, за которыми следуют 8 нулей. Префикс CIDR /24 просто считает эти старшие единичные биты. 255.255.255.0 равно /24, 255.255.255.192 равно /26, а 255.255.255.252 равно /30. CIDR — это сокращённая запись той же маски.

Сколько используемых IP-адресов даёт /30 и почему он часто применяется для двухточечных соединений?

/30 даёт 2 используемых адреса из 4 общих, потому что адрес сети и широковещательный адрес по-прежнему зарезервированы согласно стандартному правилу «минус два». Двух используемых адресов ровно достаточно для двух конечных точек двухточечного соединения — именно поэтому /30 был традиционным выбором. Позднее RFC 3021 разрешил использовать /31 для той же цели, давая 2 используемых адреса из 2: резервирование адреса сети и широковещательного адреса отменяется, и адреса не расходуются впустую.

Могут ли две подсети иметь перекрывающиеся блоки CIDR в одной сети?

Нет, если им нужно маршрутизировать трафик друг к другу. Внутри одной таблицы маршрутизации перекрытие разрешается по правилу самого длинного совпадающего префикса: пакет для 10.0.1.5 пойдёт по маршруту 10.0.1.0/24, а не по более широкому 10.0.0.0/16, поэтому путь никогда не бывает неоднозначным. Проблема возникает, когда вы соединяете две сети, адресация которых задавалась независимо. Peering-соединение между двумя VPC, которые обе используют 10.0.0.0/16, не работает, потому что каждая сторона уже маршрутизирует этот блок локально и не имеет способа достичь другой стороны. Именно поэтому VPC peering и site-to-site VPN требуют непересекающихся диапазонов. Назначайте каждой сети собственный отдельный блок RFC 1918 с самого начала.

Меньшее число префикса означает большую или меньшую сеть?

Меньшее число префикса означает большую сеть. Префикс считает фиксированные сетевые биты, поэтому чем меньше сетевых битов, тем больше битов остаётся на хосты. У /8 есть 24 бита хоста и более 16 миллионов адресов, тогда как у /24 — 8 битов хоста и 256 адресов. По мере уменьшения числа префикса размер блока удваивается на каждом шаге: /23 содержит в два раза больше адресов, чем /24, а /16 — в 256 раз больше, чем /24.

Почему AWS даёт в подсети /24 только 251 используемый адрес вместо 254?

AWS резервирует пять адресов на подсеть, а не два, как предполагает универсальное правило «минус два». AWS удерживает первые четыре адреса каждого блока CIDR подсети плюс последний — под адрес сети, маршрутизатор VPC, DNS, будущее использование и широковещательный адрес. Поэтому /24 с 256 общими адресами даёт 251 используемый в AWS против 254 при обычном сетевом расчёте. Всегда проверяйте правила резервирования вашего облачного провайдера, прежде чем подбирать размер подсети «в обрез».

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.