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 конфиги нужно адаптировать.
Пошаговый план миграции
- Получите IPv6-префикс у провайдера (если ещё нет)
- Настройте dual-stack на сетевом оборудовании (роутеры, L3 свитчи)
- Добавьте IPv6 адреса на серверы начиная с dev/staging
- Проверьте firewall правила — IPv6 должен фильтроваться отдельно
- Добавьте AAAA-записи в DNS
- Мониторьте трафик — сколько % идёт по IPv6
- Постепенно переводите внутренние сервисы на IPv6-only
Миграция не происходит за выходные, но каждый новый сервер должен сразу получать IPv6-адрес. Через год ваша инфраструктура будет dual-stack без героических усилий.
CGNAT — это реально боль. У нас несколько корпоративных клиентов за CGNAT, и когда кто-то из них начинает скрейпить сайт, приходится либо банить целый блок и попадать под других клиентов, либо смотреть сквозь пальцы. IPv6 бы решил это за счёт уникальных адресов.