ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Nginx: allow/deny и IPv6 — как правильно ограничить доступ

Разберём, как в Nginx работают allow/deny с IPv6: порядок обработки правил, CIDR для адресов и подсетей, типовые ошибки dual-stack и прокси. Покажу рецепты для админки и метрик, связку с auth_basic/htpasswd и быстрые проверки curl -4/-6.
Nginx: allow/deny и IPv6 — как правильно ограничить доступ

IPv6 давно стал «обычной реальностью»: браузеры и провайдеры охотно используют AAAA-записи, а серверы всё чаще работают в режиме dual-stack (IPv4 + IPv6). Поэтому IP-ограничения, настроенные только «под IPv4», регулярно дают ложное чувство защищённости.

Зачем вообще думать про IPv6 в allow/deny

Ограничение доступа по IP в Nginx (директивы allow/deny) — простой и очень рабочий слой защиты для закрытых зон: админки CMS, панели мониторинга, приватные API, служебные локации. Проблема в том, что многие правила пишут под IPv4 и забывают про IPv6.

Если у сервера включён dual-stack, запрос в «закрытую» админку может прийти по IPv6. Тогда IPv4-правила не помогут, и приватная зона внезапно окажется доступной «снаружи».

Ещё нюанс: у клиентов IPv6 часто динамический, и фиксировать «один адрес» бывает рискованно — можно легко заблокировать самого себя. В таких случаях логичнее опираться на подсети (обычно /64) и держать резервный барьер вроде auth_basic.

Как Nginx применяет allow/deny: порядок и логика

Директивы allow и deny относятся к модулю ngx_http_access_module. Они сравнивают IP клиента и либо пропускают запрос, либо возвращают 403.

  • Проверка идёт сверху вниз в порядке, как директивы написаны в конфиге.
  • Срабатывает первое совпадение.
  • Если совпадений нет, то всё решает наличие финального «запрета» deny all;.
  • IPv4 и IPv6 можно спокойно смешивать в одном server или location.

Для режима «белого списка» обязательно завершайте блок строкой deny all;. Иначе доступ получат все, кто не попал под ваши allow.

Где размещать правила: server vs location

Директивы можно ставить на разных уровнях конфигурации, но чаще всего оптимально ограничивать доступ именно в location — так вы не рискуете «уронить» публичную часть сайта.

  • server — общий контур для всего виртуального хоста.
  • location — точечная защита конкретных URI (например, /admin/, /metrics, /internal/).

Схема: как allow/deny в Nginx применяются для IPv4 и IPv6 на уровне server и location

IPv6 в allow/deny: синтаксис и примеры

Nginx понимает IPv6-адреса и подсети в CIDR-нотации.

  • Один адрес: allow 2001:db8:1234::10;
  • Подсеть /64: allow 2001:db8:1234:5678::/64;
  • Локальный loopback: allow ::1;

Шаблон для защиты админки: разрешаем IPv4, IPv6-подсеть и доступ с localhost, остальным запрещаем.

location /admin/ {
    allow 192.0.2.10;
    allow 2001:db8:1234:5678::/64;
    allow 127.0.0.1;
    allow ::1;
    deny all;

    proxy_pass http://backend;
}

Почему часто выбирают именно /64: у домашних/офисных сетей адрес конкретного устройства может меняться, а префикс /64 обычно остаётся стабильным в рамках выдачи провайдера/роутера.

Что выбрать для IPv6: один адрес или подсеть

  • Один адрес — хорошо для серверов и внешних сервисов (например, выход вашего VPN или IP другого бэкенда).
  • Подсеть — практичнее для офисов/домашних провайдеров, где «хостовая часть» IPv6 меняется.

Если сомневаетесь в стабильности префикса, не делайте ставку только на IP-ACL: добавьте второй барьер (например, auth_basic), а доступ по сети используйте как «сужение поверхности атаки».

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Комбинация allow/deny и auth_basic (Basic Auth + htpasswd)

Популярный рабочий вариант: режем «весь интернет» по IP и одновременно требуем логин/пароль через Basic Auth. Сценарий особенно полезен, когда админка нужна нескольким людям из разных мест: ACL оставляет доступ только доверенным сетям, а auth_basic добавляет настоящую аутентификацию.

location /admin/ {
    allow 192.0.2.0/24;
    allow 2001:db8:abcd:100::/64;
    allow 127.0.0.1;
    allow ::1;
    deny all;

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd-admin;

    proxy_pass http://backend;
}

Файл auth_basic_user_file храните вне веб-корня и с правами, исключающими чтение посторонними. Если используете утилиту htpasswd, убедитесь, что выбираете современный хеш (в зависимости от дистрибутива и политики безопасности).

Что проверяется раньше: IP или пароль

  • Если IP запрещён, клиент сразу получит 403 и даже не увидит запрос учётных данных.
  • Если IP разрешён, Nginx запросит логин/пароль и при ошибке вернёт 401.

Это удобно: меньше попыток перебора пароля и меньше лишней нагрузки.

Типовые ошибки с IPv6 в allow/deny и как их быстро найти

Ошибка 1. Разрешили IPv4, забыли IPv6

Классика: настроили allow для IPv4, добавили deny all;, проверили с одной сети — а потом выяснилось, что часть клиентов ходит по IPv6 и упирается в неожиданный доступ или неожиданный запрет (в зависимости от того, как именно был собран блок правил).

Практика: если зона должна быть закрыта, думайте в терминах dual-stack и тестируйте оба стека.

Ошибка 2. Неправильный префикс (слишком широко или слишком узко)

/64 часто подходит для «клиентских» сегментов, но провайдер может выдавать /56, /60 или даже единичный /128. Неверный префикс приводит либо к само-блокировке, либо к излишне широкому доступу.

Если вы поднимаете инфраструктуру на сервере и вам нужен предсказуемый доступ извне, иногда удобнее иметь выделенный узел (VPN/bastion) на VDS с фиксированными IPv4/IPv6 и разрешать доступ к админке только с него.

Ошибка 3. Nginx видит не реальный IP (прокси, CDN, балансировщик)

Если Nginx стоит за прокси/балансировщиком, то allow/deny будут сравнивать не реального клиента, а адрес ближайшего узла. В результате ACL либо «разрешает всем», либо «запрещает всем».

Решение — настраивать получение реального IP через real_ip_header и доверенные источники в set_real_ip_from. Доверяйте только вашим прокси и балансировщикам.

Не задавайте доверие слишком широко. Например, set_real_ip_from 0.0.0.0/0 (и аналогично широкие IPv6-диапазоны) позволяют подделать заголовок и обходить ACL.

Ошибка 4. Неполное закрытие дерева /admin/ из-за location-матчинга

Админка часто состоит из нескольких путей: /admin/, /admin/api/, /admin/assets/. Если ограничения стоят не там, где реально обрабатываются запросы (или часть попала в более специфичный location без ACL), можно получить утечки.

Правило: проверьте, какие именно location выигрывают при матчинге, и закройте все чувствительные эндпоинты.

Терминал: проверка remote_addr для IPv6 и сравнение статусов 401 и 403 при связке ACL и Basic Auth

Рецепты: защита admin panel по IPv4/IPv6

Рецепт 1. Белый список + deny all (самый строгий)

location ^~ /admin/ {
    allow 198.51.100.0/24;
    allow 2001:db8:10:20::/64;
    allow 127.0.0.1;
    allow ::1;
    deny all;

    auth_basic "Admin";
    auth_basic_user_file /etc/nginx/.htpasswd-admin;
}

Подходит, когда админка должна быть доступна только из определённых сетей (офис, VPN, служебные серверы) и никак иначе.

Рецепт 2. Разрешить всем, но закрыть опасные точки по IP

Если публичная часть приложения должна быть доступна всем, часто имеет смысл закрыть диагностические URL (метрики, дебаг, внутренние статусы):

location = /metrics {
    allow 127.0.0.1;
    allow ::1;
    allow 192.0.2.10;
    allow 2001:db8:1234:5678::10;
    deny all;

    proxy_pass http://backend;
}

Рецепт 3. Раздельные правила для разных зон (UI и API)

location ^~ /admin/ {
    allow 203.0.113.0/24;
    allow 2001:db8:aaaa:100::/64;
    deny all;

    auth_basic "Admin";
    auth_basic_user_file /etc/nginx/.htpasswd-admin;
}

location ^~ /admin/api/ {
    allow 203.0.113.10;
    allow 2001:db8:aaaa:100::10;
    deny all;
}

Так вы не раздаёте доступ шире необходимого: UI — офису/VPN, API — только конкретному сервису.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Проверка и отладка: как убедиться, что IPv6 ACL работает

1) Проверьте, слушает ли Nginx IPv6

Включён ли IPv6 на уровне сокета, зависит от listen (например, listen [::]:443 ssl;). Если IPv6 не слушается, «обхода по IPv6» не будет, но и доступ по IPv6 у клиентов работать не станет.

ss -lntp | grep nginx

2) Посмотрите, какой IP видит Nginx

Для диагностики полезно временно вывести $remote_addr в access log (или использовать отдельный формат логов). Важно убедиться, что при заходе по IPv6 в $remote_addr действительно IPv6 клиента, а не адрес прокси.

Если вы работаете с NAT64/DNS64 или смешанными сетями, полезно понимать, как именно у вас формируется путь клиента до сервера. Для более глубокого контекста можно заглянуть в материал про NAT64/DNS64 и особенности доступа по IPv6.

3) Тесты curl по IPv4 и IPv6

С хоста, который должен иметь доступ, проверьте оба стека:

curl -I -4 https://example.com/admin/
curl -I -6 https://example.com/admin/

4) Проверяйте итог по статусам: 401 vs 403

  • 403 — IP запрещён (сработал deny).
  • 401 — IP разрешён, но Basic Auth не пройден.
  • 200/302 — доступ есть, аутентификация пройдена (или не включена).

Практические советы по эксплуатации

Держите аварийный доступ

  • Оставляйте доступ с localhost: 127.0.0.1 и ::1, чтобы можно было проверить через SSH и локальный curl.
  • Применяйте изменения только после проверки: сначала nginx -t, затем reload.
  • Если у вас часто меняются внешние адреса, удобнее администрировать через VPN или bastion, чем постоянно править allowlist.

Не превращайте allowlist в «вечную помойку»

Списки allow разрастаются: временные подрядчики, старые офисы, «на недельку открой». Это снижает ценность ACL.

Минимальная дисциплина: комментарии к правилам (кто/зачем/до какого числа) и периодическая чистка.

IPv6: адресов много, но контроль нужен

В IPv6 нормально получать широкие префиксы. Поэтому «разрешим один адрес» часто ломается, а «разрешим слишком широкую сеть» опасен. Обычно баланс даёт связка:

  • ACL по сети там, где это оправдано (офис/VPN/серверы).
  • auth_basic как второй рубеж.
  • Корректный real IP, если вы за прокси.

Если хотите глубже разобраться, почему у клиентов адреса «плавают» и как устроены SLAAC/DHCPv6, пригодится статья про SLAAC, DHCPv6 и маршрутизацию IPv6.

Чек-лист перед выкладкой в прод

  1. В конце ACL для «белого списка» стоит deny all;.
  2. IPv6-правила добавлены (или IPv6 осознанно не слушается в listen).
  3. Разрешены 127.0.0.1 и ::1 для аварийного доступа.
  4. Если есть прокси/CDN — настроены real_ip_header и корректные set_real_ip_from.
  5. Проверены ответы по curl -4 и curl -6.
  6. Понимаете разницу 401 (Basic Auth) и 403 (ACL).

Итог

allow/deny в Nginx остаётся отличным инструментом, но в 2025 году его нельзя считать корректно настроенным, пока вы не проверили IPv6. Для реальной защиты административных зон чаще всего достаточно связки IP-ACL + auth_basic с htpasswd: она одновременно ограничивает круг источников и даёт аутентификацию. Главное — тестировать оба стека (IPv4/IPv6) и не забывать про реальный IP за прокси.

Поделиться статьей

Вам будет интересно

Apache HTTP/2: h2, ALPN и PHP-FPM через proxy_fcgi — настройка и диагностика OpenAI Статья написана AI (GPT 5)

Apache HTTP/2: h2, ALPN и PHP-FPM через proxy_fcgi — настройка и диагностика

Пошагово включаем HTTP/2 в Apache через mod_http2: как работает h2 и ALPN, какие требования к TLS и MPM, как правильно проксироват ...
Apache HTTP/2 (h2), ALPN и PHP-FPM: настройка и типовые проблемы OpenAI Статья написана AI (GPT 5)

Apache HTTP/2 (h2), ALPN и PHP-FPM: настройка и типовые проблемы

Пошагово включаем HTTP/2 (h2) в Apache: проверяем mod_http2, работу ALPN и настройки TLS, задаём Protocols во vhost’ах и подключае ...
Nginx allow/deny и IPv6: как ограничить доступ к админке и не заблокировать себя OpenAI Статья написана AI (GPT 5)

Nginx allow/deny и IPv6: как ограничить доступ к админке и не заблокировать себя

Разбираем, как в Nginx работают allow/deny для IPv4 и IPv6, какие префиксы указывать и почему «IPv6 allow» часто не совпадает с ре ...