Серверное оборудование для бизнеса — надёжные решения для любых задач Подробнее →
Статья

IPv6 в продакшене: практический опыт миграции

«Мы перейдём на IPv6 когда-нибудь потом» — эту фразу я слышу от коллег уже десять лет. Потом наступило: RIPE NCC исчерпал свободные блоки IPv4 ещё в 2019 году, и каждый новый сервер без IPv6 — это будущая головная боль. Делюсь практическим опытом миграции.

Почему IPv6 уже нельзя игнорировать

Исчерпание IPv4 — не теоретическая угроза. IANA раздал последние /8 блоки региональным регистраторам в 2011 году. Купить новый IPv4-блок сегодня можно только на вторичном рынке по $40–60 за адрес. Для стартапа с несколькими сотнями серверов это миллионы рублей только на адресное пространство.

CGNAT (Carrier-Grade NAT) — то, чем мобильные и некоторые домашние провайдеры латают нехватку IPv4. Тысячи абонентов за одним публичным IP. Последствия для вас как сервис-провайдера:

  • невозможность точно геолоцировать пользователей по IP
  • проблемы с rate limiting (весь CGNAT-блок как один клиент)
  • сломанные механизмы защиты от брутфорса
  • логи теряют смысл для расследования инцидентов

IPv6 решает все эти проблемы: у каждого устройства свой глобальный адрес.

Dual-stack vs IPv6-only

Dual-stack — сервер имеет и IPv4, и IPv6 адрес. Клиенты с IPv6 подключаются по IPv6 (Happy Eyeballs алгоритм выбирает лучший протокол), остальные — по IPv4. Это переходная стратегия, наименее рискованная для начала миграции.

IPv6-only — только IPv6. Для взаимодействия с IPv4 ресурсами используется NAT64/DNS64. Радикально, но именно так работает большинство современных мобильных сетей Apple и крупных провайдеров. Для новых внутренних сервисов вполне реалистично.

Рекомендация: начинайте с dual-stack, постепенно переводя сервисы на работу преимущественно через IPv6.

Адресация: /64, /48, link-local

В IPv6 адреса 128-битные, но планировать нужно иначе, чем в IPv4.

Типичное выделение провайдером: /48 prefix на организацию — это 65 536 подсетей /64. Каждой VLAN выделяете /64.

Link-local адреса (fe80:/10) — автоматически назначаются каждому интерфейсу, не маршрутизируются за пределы сегмента. Используются для работы NDP (аналог ARP в IPv6) и роутинг-протоколов.

Global Unicast (2000:/3) — публично маршрутизируемые адреса, аналог публичных IPv4.

Пример планирования:
Провайдер выдаёт: 2001:db8🔡:/48
Web tier:         2001:db8🔡0001::/64
App tier:         2001:db8🔡0002::/64
DB tier:          2001:db8🔡0003::/64
Management:       2001:db8🔡ffff::/64

SLAAC vs DHCPv6

SLAAC (Stateless Address Autoconfiguration) — устройство само генерирует адрес из prefix (анонсируется роутером через Router Advertisement) и своего MAC-адреса или случайного числа. Не требует сервера, работает из коробки.

DHCPv6 — явная выдача адресов, аналог DHCP. Нужен если хотите контролировать какой адрес получает какое устройство, или собирать логи выдачи.

Для серверов рекомендую статические адреса — никакого SLAAC и DHCPv6, просто прописываете адрес вручную. Предсказуемо и легко аудируется.

Настройка на Linux

sysctl для включения IPv6-форвардинга:

# /etc/sysctl.d/99-ipv6.conf
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.accept_ra = 2  # принимать RA даже при включённом forwarding
net.ipv6.conf.default.accept_ra = 2

Netplan (Ubuntu 22.04+):

network:
  version: 2
  ethernets:
    ens3:
      addresses:
        - 192.168.1.10/24
        - 2001:db8🔡0001::10/64
      gateway4: 192.168.1.1
      routes:
        - to: ::/0
          via: 2001:db8🔡0001::1
      nameservers:
        addresses:
          - 8.8.8.8
          - 2001:4860:4860::8888

Firewall: ip6tables / nftables

Критически важно: IPv6 не имеет NAT как защитного механизма. Каждый адрес публично достижим. Firewall обязателен.

# nftables — рекомендуемый инструмент для новых конфигураций
cat /etc/nftables.conf
table ip6 filter {
  chain input {
    type filter hook input priority 0; policy drop;

    ct state established,related accept
    iif lo accept
    ip6 nexthdr icmpv6 accept   # ICMPv6 нельзя блокировать!
    tcp dport { 22, 80, 443 } accept
  }
  chain forward {
    type filter hook forward priority 0; policy drop;
  }
}

ICMPv6 нельзя полностью блокировать — это сломает NDP, Path MTU Discovery и другие базовые механизмы IPv6. Блокируйте только специфические типы если нужно.

DNS: AAAA-записи

Добавьте AAAA-записи для всех публичных сервисов:

example.com.     IN A    203.0.113.10
example.com.     IN AAAA 2001:db8🔡1::10

Проверка:

dig AAAA example.com
curl -6 https://example.com

Подводные камни

  • Приложения с захардкоженным IPv4: некоторые старые приложения слушают только 0.0.0.0 или явно указывают AF_INET. Нужен аудит кода или конфигов.
  • Мониторинг: Prometheus, Grafana, Zabbix — убедитесь что агенты и экспортеры слушают на IPv6 тоже.
  • Логи: fail2ban и другие инструменты парсинга логов должны понимать IPv6-адреса. Обновите регексы.
  • Балансировщики: nginx слушает на :: (wildcard IPv6) по умолчанию в современных версиях. Старые HAProxy конфиги нужно адаптировать.

Пошаговый план миграции

  1. Получите IPv6-префикс у провайдера (если ещё нет)
  2. Настройте dual-stack на сетевом оборудовании (роутеры, L3 свитчи)
  3. Добавьте IPv6 адреса на серверы начиная с dev/staging
  4. Проверьте firewall правила — IPv6 должен фильтроваться отдельно
  5. Добавьте AAAA-записи в DNS
  6. Мониторьте трафик — сколько % идёт по IPv6
  7. Постепенно переводите внутренние сервисы на IPv6-only

Миграция не происходит за выходные, но каждый новый сервер должен сразу получать IPv6-адрес. Через год ваша инфраструктура будет dual-stack без героических усилий.

3 Ответа

  1. CGNAT — это реально боль. У нас несколько корпоративных клиентов за CGNAT, и когда кто-то из них начинает скрейпить сайт, приходится либо банить целый блок и попадать под других клиентов, либо смотреть сквозь пальцы. IPv6 бы решил это за счёт уникальных адресов.

  1. По безопасности IPv6 добавлю: не забывайте про link-local адреса в логах, они не уникальны глобально и могут совпадать у разных интерфейсов. При расследовании инцидентов важно учитывать и зону (interface id), иначе логи могут вводить в заблуждение.