Переход на IPv6: что готово, а что сломается
«Просто включите IPv6 и всё заработает» — фраза, за которой чаще всего стоит не опыт, а маркетинг. На практике часть инфраструктуры действительно принимает IPv6 без единой правки конфига, а часть — ломается тихо и не сразу, потому что годами настраивалась в предположении, что кроме IPv4-адреса на сервере ничего не бывает. Разберём по пунктам, что реально готово из коробки, а что стоит проверить руками, прежде чем включать AAAA-запись в продакшене.
Содержание
Что действительно работает само собой
Начнём с хорошей новости: на уровне веб-сервера и клиента переход почти безболезненный.
Nginx и Apache уже много лет умеют dual-stack — слушать одновременно IPv4 и IPv6 на одном порту без каких-либо архитектурных изменений. В nginx это буквально одна строка в конфиге:
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
...
}
Если забыть listen [::]:80 — сервер просто не будет слушать IPv6 на этом порту, но это не «сломается», а «не заработает», что диагностируется сразу через curl -6 http://example.com или ss -tlnp | grep nginx.
В Apache аналогично — достаточно, чтобы Listen был указан без явной привязки к IPv4-адресу (Listen 80 вместо Listen 0.0.0.0:80), либо явно добавить IPv6-адрес:
Listen [::]:80
Listen [::]:443
Второй момент, который обычно не требует вмешательства — клиентская сторона. Современные браузеры (Chrome, Firefox, Safari) и большинство HTTP-библиотек реализуют Happy Eyeballs (RFC 8305): если у хоста есть и A-, и AAAA-запись, клиент пробует оба протокола почти одновременно и использует тот, что ответил быстрее и надёжнее, с прозрачным для пользователя фоллбэком на IPv4. Пользователь ничего не замечает, даже если IPv6-путь до сервера чуть кривее, чем IPv4-путь.
То есть сама раздача контента по IPv6 — не та часть, на которой стоит фокусировать бдительность. Проблемы начинаются на уровнях, которые обычно настраивались один раз и потом не трогались годами.
DNS: забытая AAAA-запись создаёт половинчатое поведение
IPv6 не появится у клиентов сам по себе, даже если сервер уже слушает [::] — нужна отдельная запись в DNS:
example.com. A 203.0.113.10
example.com. AAAA 2001:db8:1234::10
Забытая или неполная AAAA-запись — источник самой частой путаницы при поэтапном включении IPv6. Типичный сценарий: включили IPv6 на основном домене, а забыли на www., на API-поддомене или на CDN-эндпоинте. В результате часть запросов клиента идёт по IPv4, часть — по IPv6, и если на каком-то из промежуточных узлов (firewall, балансировщик, WAF) IPv6-путь настроен не идентично IPv4-пути, поведение начинает расходиться: один и тот же пользователь может то проходить проверку по IP, то не проходить, в зависимости от того, какой протокол выбрал его браузер в конкретный момент.
Проверить реальное состояние легко:
dig AAAA example.com +short
dig AAAA api.example.com +short
dig AAAA www.example.com +short
Если по одному из поддоменов список пуст — это ожидаемо (IPv6 туда ещё не докатили) или баг, который нужно закрыть до включения IPv6 «в общем виде». Отдельно стоит проверить TTL записи перед изменениями — если AAAA придётся откатывать в экстренном порядке, короткий TTL (300–600 секунд) даст возможность сделать это быстро, а не ждать часами, пока прогреются резолверы у части пользователей.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSFirewall — самая частая и самая опасная ошибка
Это главный пункт статьи, и вот почему. Правила iptables и ip6tables — два независимых набора правил в ядре Linux: правило из iptables не действует на IPv6-трафик, и наоборот. Если фаервол настраивался годами исключительно под IPv4, весь набор правил — блокировки портов, гео-ограничения, whitelist для админки, правила fail2ban — полностью игнорирует IPv6-трафик, потому что для него никогда не писались отдельные правила. Пока IPv6-адреса на интерфейсе не было, это не имело значения — трафика просто не было. В момент, когда вы добавляете серверу IPv6-адрес, ситуация меняется мгновенно: порты, годами закрытые правилами iptables, оказываются полностью открытыми по IPv6, потому что ip6tables либо пуст, либо стоит в default ACCEPT.
Наглядный пример: у вас закрыт порт 5432 (PostgreSQL) для внешнего доступа правилом
iptables -A INPUT -p tcp --dport 5432 -j DROP
Это правило не существует для IPv6. Если у сервера есть глобальный IPv6-адрес и в ip6tables не настроен аналогичный DROP, порт 5432 открыт для всего IPv6-интернета в тот момент, когда провайдер начинает маршрутизировать IPv6 до вашего сервера — то есть иногда даже до того, как вы «сознательно» что-то включали, просто потому что провайдер выдал IPv6-подсеть по умолчанию.
Проверка того, что реально происходит, — обязательный шаг перед любым включением IPv6:
# Что видит IPv4-фаервол
iptables -L -n -v --line-numbers
# Что видит IPv6-фаервол — часто здесь пусто или default ACCEPT
ip6tables -L -n -v --line-numbers
# Есть ли у сервера вообще глобальный IPv6
ip -6 addr show scope global
Если используется ufw (что типично на Ubuntu/Debian VPS), по умолчанию он тоже применяет правила к обоим стекам — но только если IPv6 в принципе включён в самом ufw, что нужно проверить явно:
grep IPV6 /etc/default/ufw
# должно быть: IPV6=yes
Если IPV6=no (или файл был отредактирован ранее, когда IPv6 сознательно отключали как «ненужный»), правила ufw создаются исключительно для IPv4, и после смены на IPV6=yes требуется перезапуск/переприменение:
ufw disable
ufw enable
ufw status verbose
ufw status verbose покажет правила отдельно по v4 и v6 — это первое, что стоит проверить после любых изменений. Правило ufw allow 22/tcp при включённом IPV6=yes создаётся сразу для обоих протоколов, но если правила добавлялись до включения IPv6 в ufw, часть из них может не продублироваться автоматически — обязательно перепроверяйте вручную, не полагаясь на то, что «раз IPv4 защищён — значит IPv6 автоматически тоже».
То же самое касается fail2ban: старые версии и часть кастомных jail-конфигов работают только с IPv4-адресами в regex действий бана. Если атакующий начнёт перебор паролей по SSH через IPv6-адрес, а jail настроен под IPv4-regex, бан просто не сработает — это стоит протестировать отдельно, а не предполагать по умолчанию.
Логи и скрипты анализа — формат адреса меняется
Второй частый источник сюрпризов — код и скрипты, которые парсят логи в расчёте на формат IPv4-адреса. IPv6-адрес выглядит принципиально иначе (2001:db8:85a3::8a2e:370:7334 вместо 192.168.1.1), и регэксп вида \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} для извлечения IP просто не найдёт совпадения в такой строке. Последствия конкретны:
- Гео-блокировки и гео-аналитика. Если геолокация по IP реализована через старую версию базы (например GeoIP Legacy вместо GeoIP2/GeoLite2) или через самописный скрипт с IPv4-парсингом, запросы с IPv6-адресов либо не определяются по стране вообще, либо (что хуже) ошибочно классифицируются как «неизвестный регион» и попадают под общие ограничения для неопределённой геолокации.
- Блокировки по IP в самописных модулях. Скрипт бана по IP, который хранит забаненные адреса в структуре, рассчитанной на 32-битный IPv4 (например
unsigned intпод адрес), физически не может сохранить 128-битный IPv6-адрес — либо упадёт с ошибкой, либо обрежет адрес до бессмысленного значения. - Парсинг access-логов nginx. Сам nginx корректно пишет IPv6-адрес в стандартный
$remote_addr, проблема не в веб-сервере, а в том, что скрипты последующей обработки (grep/awk-конвейеры, самописные Python/Bash-парсеры для отчётов) часто писались с жёстко заданным форматом IPv4 и на строке вида
2001:db8::1 - - [28/Aug/2026:12:00:01 +0000] "GET / HTTP/1.1" 200 612
либо падают с исключением при попытке распарсить адрес как четыре октета, либо тихо пропускают строку, из-за чего часть трафика выпадает из отчётов и аналитики без явной ошибки.
Практический совет — прогнать реальные лог-файлы через тестовый IPv6-запрос до массового включения:
curl -6 -v https://example.com/ 2>&1 | grep "Connected to"
tail -n 50 /var/log/nginx/access.log | grep -E '^[0-9a-fA-F:]+ '
И явно протестировать, что скрипты анализа (будь то logrotate-хуки, self-hosted аналитика, экспорт в SIEM) корректно обрабатывают строку с IPv6-адресом — не «должны», а именно протестировать на реальном примере.
Исходящие соединения и whitelist у партнёров
Отдельная категория проблем — не входящий, а исходящий трафик сервера. Если сервер получает IPv6-адрес и ОС по умолчанию предпочитает IPv6 для исходящих соединений (стандартное поведение большинства современных дистрибутивов Linux при наличии рабочего IPv6-маршрута), любое исходящее соединение к внешнему API — платёжному шлюзу, SMS-провайдеру, партнёрскому REST API — может уйти с IPv6-адреса вместо привычного IPv4.
Проблема в том, что многие интеграции всё ещё настроены на whitelist по IPv4-адресам на стороне партнёра — это классическая практика для платёжных систем и B2B API, где список разрешённых источников поддерживается вручную. Если ваш сервер внезапно начинает стучаться с IPv6-адреса, которого нет в этом whitelist, партнёр просто отклоняет соединение — часто без внятного сообщения об ошибке, потому что с точки зрения партнёра запрос выглядит как попытка обращения с неавторизованного источника, а не как «тот же клиент, но по другому протоколу».
Это особенно неприятно тем, что проблема не проявляется на этапе тестирования веб-сайта (тестируете вы обычно входящие соединения к сайту), а всплывает в проде именно на исходящих интеграциях, которые редко тестируют отдельно при включении IPv6.
Практическая проверка перед включением:
# Проверить, с какого адреса реально уйдёт исходящее соединение
curl -v https://api.partner.example/ping 2>&1 | grep "Trying"
# Принудительно проверить оба варианта
curl -4 -v https://api.partner.example/ping
curl -6 -v https://api.partner.example/ping
Если для критичной интеграции (платежи, банковское API) IPv6 не согласован с партнёром заранее — стоит либо явно приколотить исходящие соединения к IPv4 через --interface/bind-адрес в конфиге приложения, либо временно отключить preference IPv6 для исходящих на уровне sysctl (net.ipv6.conf.all.disable_ipv6 — но это радикально и отключает IPv6 целиком, обычно достаточно точечной настройки в конкретном HTTP-клиенте или прокси).
Как включать поэтапно, не ломая продакшен
Собранный выше список подсказывает разумный порядок действий — не «включить всё и посмотреть», а поэтапно, с проверкой на каждом шаге.
- Сначала firewall, потом всё остальное. Проверьте
ip6tables/ufw status verboseи явно продублируйте туда все правила безопасности, которые есть в IPv4-стеке — прежде чем добавлять IPv6-адрес на интерфейс или включать AAAA-запись. Это единственный пункт, где ошибка означает не «не работает», а «открыт доступ туда, куда не должен быть открыт». - Включите IPv6 на интерфейсе и проверьте связность отдельно от DNS. Убедитесь, что
ping6/curl -6до нужных сервисов работает, прежде чем что-либо публиковать в DNS. - Добавьте AAAA-запись на тестовом/staging-поддомене, а не сразу на продакшен-домене. Прогоните через него реальные сценарии: логин, платёж (в тестовом режиме), геолокацию, парсинг логов.
- Проверьте исходящие интеграции отдельно — особенно те, где на другой стороне ручной whitelist по IP.
- Только после этого включайте AAAA на продакшене, лучше с коротким TTL, чтобы иметь возможность быстро откатить.
- Мониторьте отдельно IPv6-трафик первые недели — не полагайтесь, что раз IPv4-мониторинг зелёный, всё в порядке. Логи и алерты нужно явно проверить на способность видеть и разбирать IPv6-адреса.
Ключевая мысль, которую стоит держать в голове на каждом из этих шагов: IPv4 и IPv6 — это не «один и тот же трафик через разную трубу», а два параллельных стека, каждый из которых требует собственной настройки безопасности, логирования и мониторинга. Всё, что настраивалось только под IPv4 годами, по умолчанию не защищает и не обрабатывает IPv6 — оно просто не видит его вообще, пока вы явно не научите его это делать.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Обязательно ли включать IPv6, если сайт и так работает по IPv4?
Нет, это не обязательно технически. Причины включать — часть мобильных операторов и провайдеров уже используют IPv6-only или CGNAT-сети с трансляцией, где прямое IPv4-соединение менее эффективно, а также требования отдельных гос- и корпоративных сетей. Если аудитория преимущественно в сетях с полноценным IPv4, срочности нет.
Если я включу listen [::] в nginx, но не добавлю AAAA-запись — что-то сломается?
Нет, ничего не сломается: без AAAA-записи клиенты просто не узнают о существовании IPv6-адреса и продолжат обращаться по IPv4, как раньше. Это безопасный промежуточный шаг для тестирования (можно обращаться к серверу по IPv6-адресу напрямую, минуя DNS).
Как быстро проверить, что firewall одинаково настроен для обоих стеков?
Сравните вывод iptables -L -n -v и ip6tables -L -n -v построчно — количество и логика правил (особенно default policy на INPUT) должны совпадать. Расхождение default policy (например DROP для IPv4 и ACCEPT для IPv6) — это и есть та самая частая ошибка.
Нужно ли менять что-то в приложении (backend-коде), чтобы оно "понимало" IPv6?
Обычно нет, если приложение использует стандартные библиотеки работы с сетью и не хранит IP-адреса в полях, рассчитанных на 32 бита (например INET-тип вместо строкового поля недостаточной длины в базе данных — тут стоит явно проверить схему БД, если IP-адреса логируются в отдельную таблицу).
Что делать, если после включения AAAA часть пользователей стала жаловаться на недоступность сайта?
Это типичный признак «битого» IPv6-маршрута у части сетей (broken IPv6) в сочетании с плохо работающим Happy Eyeballs у части старых клиентов. Первый шаг — временно уменьшить TTL AAAA-записи и, если проблема массовая, откатить AAAA-запись до выяснения причины на стороне сети.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →