ping6.net

IPv6 в AWS: VPC, EC2, ELB и другое

Полное руководство по развертыванию IPv6 в Amazon Web Services. Настройка VPC, подсетей, групп безопасности, балансировщиков нагрузки и egress-only шлюзов.

ping6.net14 декабря 2024 г.12 min read
IPv6AWScloudVPCEC2networking

AWS имеет полную поддержку IPv6 в большинстве сервисов, но она не включена по умолчанию. Вы должны включить ее явно, и настройка распределена по нескольким уровням.

TL;DR - Краткое резюме

Ключевые моменты:

  • AWS предоставляет dual-stack IPv6 (не только IPv6 для большинства сервисов)
  • Вы получаете выделенные Amazon блоки /56 из диапазона 2600::/12
  • Все IPv6-адреса глобально уникальны и маршрутизируемы (без NAT)
  • Egress-only шлюзы обеспечивают stateful фильтрацию без трансляции адресов

Перейти к: Настройка VPC | Инстансы EC2 | Группы безопасности | Балансировщики нагрузки | Пример Terraform


Обзор архитектуры IPv6 в AWS#

AWS предоставляет IPv6 в конфигурации dual-stack. Ваши ресурсы получают как IPv4, так и IPv6 адреса. Вы не можете запустить только IPv6 в большинстве сервисов (за исключением некоторых контейнерных и serverless нагрузок).

Amazon назначает IPv6 CIDR-блоки из своего публичного пула. Вы не можете выбрать свой префикс — AWS выделяет блок /56 для вашего VPC из диапазона 2600::/12.

В отличие от IPv4, где вы используете частные адреса RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), все IPv6-адреса AWS глобально уникальны и маршрутизируемы (GUA). Нет NAT для IPv6 в традиционном смысле — если вам нужна только исходящая связь, вы используете egress-only интернет-шлюз.

Настройка IPv6 VPC#

Начните с вашего VPC. Добавление IPv6 не нарушает существующие IPv4-ресурсы.

Ассоциация IPv6 CIDR-блока#

Добавьте IPv6 CIDR от Amazon к вашему VPC:

aws ec2 associate-vpc-cidr-block \
  --vpc-id vpc-0abc123def456 \
  --amazon-provided-ipv6-cidr-block

AWS назначает блок /56. Ответ показывает назначенный диапазон:

{
  "Ipv6CidrBlockAssociation": {
    "Ipv6CidrBlock": "2600:1f13:1234:5600::/56",
    "Ipv6CidrBlockState": {
      "State": "associating"
    }
  }
}

Дождитесь изменения статуса на associated:

aws ec2 describe-vpcs --vpc-ids vpc-0abc123def456 \
  --query 'Vpcs[0].Ipv6CidrBlockAssociationSet[0].Ipv6CidrBlockState.State'

Вы также можете использовать «принеси свой IP» (BYOIP), если у вас есть независимое от провайдера IPv6-пространство и вы хотите сохранить адреса при переходе между аккаунтами AWS или миграции. Большинство пользователей используют адреса, предоставленные Amazon.

Настройка IPv6 подсетей#

Подсетям нужны собственные слайсы /64 из блока VPC /56.

Получите IPv6 CIDR вашего VPC:

aws ec2 describe-vpcs --vpc-ids vpc-0abc123def456 \
  --query 'Vpcs[0].Ipv6CidrBlockAssociationSet[0].Ipv6CidrBlock'

Вывод: 2600:1f13:1234:5600::/56

Назначьте блоки /64 подсетям. Используйте шестнадцатеричные значения 00-FF для части подсети:

# Публичная подсеть A — 2600:1f13:1234:5600::/64
aws ec2 associate-subnet-cidr-block \
  --subnet-id subnet-0abc111 \
  --ipv6-cidr-block 2600:1f13:1234:5600::/64
 
# Публичная подсеть B — 2600:1f13:1234:5601::/64
aws ec2 associate-subnet-cidr-block \
  --subnet-id subnet-0abc222 \
  --ipv6-cidr-block 2600:1f13:1234:5601::/64
 
# Частная подсеть A — 2600:1f13:1234:5610::/64
aws ec2 associate-subnet-cidr-block \
  --subnet-id subnet-0abc333 \
  --ipv6-cidr-block 2600:1f13:1234:5610::/64

Включите автоматическое назначение IPv6-адресов для инстансов, запускаемых в публичных подсетях:

aws ec2 modify-subnet-attribute \
  --subnet-id subnet-0abc111 \
  --assign-ipv6-address-on-creation

Таблицы маршрутизации#

Маршрутизация IPv6 отделена от IPv4. Создайте маршруты для ваших IPv6 CIDR-блоков.

Для публичных подсетей направьте весь IPv6-трафик (::/0) на интернет-шлюз:

aws ec2 create-route \
  --route-table-id rtb-0abc123 \
  --destination-ipv6-cidr-block ::/0 \
  --gateway-id igw-0def456

Интернет-шлюзы обрабатывают как IPv4, так и IPv6 без модификаций.

Для частных подсетей вы будете использовать egress-only интернет-шлюз (объясняется позже):

aws ec2 create-route \
  --route-table-id rtb-0abc789 \
  --destination-ipv6-cidr-block ::/0 \
  --egress-only-internet-gateway-id eigw-0ghi012

Проверьте маршруты:

aws ec2 describe-route-tables --route-table-ids rtb-0abc123 \
  --query 'RouteTables[0].Routes'

Настройка IPv6 EC2-инстансов#

EC2-инстансы требуют явного назначения IPv6-адресов.

Запуск новых инстансов с IPv6#

Укажите --ipv6-address-count при запуске:

aws ec2 run-instances \
  --image-id ami-0abc123 \
  --instance-type t3.medium \
  --subnet-id subnet-0abc111 \
  --ipv6-address-count 1 \
  --key-name mykey \
  --security-group-ids sg-0abc456

Или назначьте конкретный IPv6-адрес из диапазона вашей подсети:

aws ec2 run-instances \
  --image-id ami-0abc123 \
  --instance-type t3.medium \
  --subnet-id subnet-0abc111 \
  --ipv6-addresses Ipv6Address=2600:1f13:1234:5600::a \
  --key-name mykey \
  --security-group-ids sg-0abc456

Добавление IPv6 к существующим инстансам#

Получите ID сетевого интерфейса (ENI):

aws ec2 describe-instances --instance-ids i-0abc123 \
  --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId'

Назначьте IPv6-адрес:

aws ec2 assign-ipv6-addresses \
  --network-interface-id eni-0def456 \
  --ipv6-address-count 1

Или укажите точные адреса:

aws ec2 assign-ipv6-addresses \
  --network-interface-id eni-0def456 \
  --ipv6-addresses 2600:1f13:1234:5600::b

Настройка ОС инстанса#

Большинство современных AMI (Amazon Linux 2023, Amazon Linux 2, Ubuntu 20.04+) настраивают IPv6 автоматически через cloud-init и DHCPv6.

Подключитесь по SSH к инстансу и проверьте:

ip -6 addr show

Вы должны увидеть назначенный IPv6-адрес на интерфейсе eth0:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001
    inet6 2600:1f13:1234:5600::a/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::4a2:c9ff:fe12:3456/64 scope link
       valid_lft forever preferred_lft forever

Проверьте связь:

ping6 google.com
curl -6 https://ifconfig.co

Если IPv6 не настроен, проверьте логи cloud-init:

sudo cat /var/log/cloud-init.log | grep -i ipv6

Некоторые старые AMI могут требовать ручной настройки. Добавьте в /etc/network/interfaces (Debian/Ubuntu) или /etc/sysconfig/network-scripts/ifcfg-eth0 (RHEL/CentOS).

Группы безопасности#

Группы безопасности требуют явных правил IPv6. Правила IPv4 не применяются к IPv6-трафику.

Создание Dual-Stack правил групп безопасности#

Разрешите HTTP/HTTPS отовсюду (IPv4 и IPv6):

# IPv4
aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges='[{CidrIp=0.0.0.0/0}]'
 
# IPv6
aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,Ipv6Ranges='[{CidrIpv6=::/0}]'

Разрешите SSH с конкретного IPv6-префикса:

aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --ip-permissions IpProtocol=tcp,FromPort=22,ToPort=22,Ipv6Ranges='[{CidrIpv6=2001:db8::/32,Description="Office IPv6"}]'

Разрешите весь ICMPv6 (требуется для работы IPv6):

aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --ip-permissions IpProtocol=ipv6-icmp,FromPort=-1,ToPort=-1,Ipv6Ranges='[{CidrIpv6=::/0}]'

ICMPv6 критически важен для IPv6. Не блокируйте его. Он используется для neighbor discovery, PMTUD и других основных функций.

Лучшие практики групп безопасности#

  1. Зеркалируйте правила IPv4 на IPv6 если у вас нет специальных причин не делать этого
  2. Всегда разрешайте ICMPv6 из тех же источников, что и ваш трафик приложений
  3. Используйте списки префиксов для управления сложными наборами правил для обоих семейств
  4. Размечайте группы безопасности для идентификации dual-stack vs. только IPv4

Пример: Создайте управляемый список префиксов для IPv6-диапазонов вашей организации:

aws ec2 create-managed-prefix-list \
  --prefix-list-name org-ipv6-ranges \
  --address-family IPv6 \
  --max-entries 10 \
  --entries Cidr=2001:db8:100::/40,Description=HQ \
           Cidr=2001:db8:200::/40,Description=DataCenter

Ссылайтесь на него в правилах группы безопасности:

aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,PrefixListIds='[{PrefixListId=pl-0abc123}]'

Elastic Load Balancing#

Application Load Balancer (ALB) и Network Load Balancer (NLB) поддерживают dual-stack. Classic Load Balancer не поддерживает.

Application Load Balancer Dual-Stack#

Создайте или измените ALB для использования dual-stack:

aws elbv2 create-load-balancer \
  --name my-alb \
  --subnets subnet-0abc111 subnet-0abc222 \
  --security-groups sg-0abc123 \
  --ip-address-type dualstack

Для существующих балансировщиков:

aws elbv2 set-ip-address-type \
  --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/1234567890abcdef \
  --ip-address-type dualstack

Балансировщик автоматически получает как A, так и AAAA DNS-записи:

dig my-alb-1234567890.us-east-1.elb.amazonaws.com A
dig my-alb-1234567890.us-east-1.elb.amazonaws.com AAAA

Клиенты могут подключаться через IPv4 или IPv6. Балансировщик перенаправляет трафик на цели, используя их настроенное семейство адресов (обычно IPv4 для backend-инстансов).

Network Load Balancer Dual-Stack#

NLB поддерживает dual-stack аналогично:

aws elbv2 create-load-balancer \
  --name my-nlb \
  --type network \
  --subnets subnet-0abc111 subnet-0abc222 \
  --ip-address-type dualstack

NLB сохраняет IP-адреса клиентов, поэтому цели видят фактические IPv6-адреса источников. Убедитесь, что ваше приложение и группы безопасности обрабатывают оба семейства адресов.

Target Groups#

Целевые группы регистрируют инстансы по их IPv4-адресам (наиболее распространенный вариант) или IPv6. Вы не можете смешивать семейства адресов в одной целевой группе.

Создайте IPv4 целевую группу:

aws elbv2 create-target-group \
  --name my-targets-ipv4 \
  --protocol HTTP \
  --port 80 \
  --vpc-id vpc-0abc123 \
  --ip-address-type ipv4

Создайте IPv6 целевую группу:

aws elbv2 create-target-group \
  --name my-targets-ipv6 \
  --protocol HTTP \
  --port 80 \
  --vpc-id vpc-0abc123 \
  --ip-address-type ipv6

Большинство развертываний используют IPv4 целевые группы даже с dual-stack балансировщиками. Балансировщик прозрачно обрабатывает преобразование протоколов.

Egress-Only Internet Gateway#

Egress-only интернет-шлюзы разрешают исходящие IPv6-соединения из частных подсетей, блокируя входящие соединения. Это похоже на NAT для IPv4, но без преобразования адресов — IPv6-адреса остаются глобально уникальными.

Создание Egress-Only шлюза#

aws ec2 create-egress-only-internet-gateway \
  --vpc-id vpc-0abc123

Запомните ID шлюза:

{
  "EgressOnlyInternetGateway": {
    "EgressOnlyInternetGatewayId": "eigw-0abc123"
  }
}

Маршрутизация трафика частных подсетей#

Добавьте маршрут в таблицу маршрутизации частной подсети:

aws ec2 create-route \
  --route-table-id rtb-0abc789 \
  --destination-ipv6-cidr-block ::/0 \
  --egress-only-internet-gateway-id eigw-0abc123

Инстансы в частных подсетях теперь могут инициировать исходящие IPv6-соединения, но не будут принимать входящий трафик из интернета.

Случаи использования:

  • Серверы баз данных, которым нужны обновления ПО
  • Серверы приложений, обращающиеся к внешним API
  • Внутренние сервисы, вызывающие AWS API (S3, DynamoDB и т.д.) через IPv6

Соображения безопасности#

Egress-only шлюзы не обеспечивают анонимность. Ваш IPv6-адрес все еще виден внешним сервисам. Это stateful файрволинг, а не NAT.

Если вам нужен настоящий только исходящий трафик с маскировкой адресов, вам потребуется NAT64-шлюз (более сложная настройка, редко необходима).

Route 53 DNS#

Route 53 полностью поддерживает IPv6 с AAAA-записями.

Создание AAAA-записей#

Добавьте AAAA-запись для вашего инстанса или балансировщика:

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "AAAA",
        "TTL": 300,
        "ResourceRecords": [{"Value": "2600:1f13:1234:5600::a"}]
      }
    }]
  }'

Alias-записи для балансировщиков#

Используйте alias-записи для ALB/NLB (лучше чем AAAA-записи — автоматически обновляются при изменении IP балансировщика):

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "AAAA",
        "AliasTarget": {
          "HostedZoneId": "Z35SXDOTRQ7X7K",
          "DNSName": "my-alb-1234567890.us-east-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }]
  }'

HostedZoneId в AliasTarget — это канонический hosted zone для ELB в этом регионе (см. документацию AWS для правильного значения).

Health Checks#

Route 53 health checks поддерживают IPv6:

aws route53 create-health-check \
  --health-check-config \
    IPAddress=2600:1f13:1234:5600::a,Port=443,Type=HTTPS,ResourcePath=/health,RequestInterval=30,FailureThreshold=3 \
  --caller-reference $(uuidgen)

Используйте health checks с политиками failover или weighted routing для высокой доступности.

CloudFront IPv6#

CloudFront-дистрибутивы поддерживают IPv6 по умолчанию (в большинстве случаев нельзя отключить).

Глобальная edge-сеть CloudFront использует dual-stack. Клиенты, подключающиеся через IPv6, попадают на те же edge-локации, что и IPv4-клиенты.

Проверьте поддержку IPv6:

dig d111111abcdef8.cloudfront.net AAAA

CloudFront обрабатывает преобразование протоколов. Если ваш origin только IPv4, CloudFront все равно обслуживает контент IPv6-клиентам.

Настройка origin не требует изменений:

aws cloudfront create-distribution \
  --distribution-config file://distribution-config.json

Пример distribution-config.json (сокращенно):

{
  "Origins": {
    "Items": [{
      "Id": "my-origin",
      "DomainName": "example.com",
      "CustomOriginConfig": {
        "OriginProtocolPolicy": "https-only"
      }
    }]
  },
  "Enabled": true,
  "Comment": "My distribution"
}

CloudFront автоматически выделяет IPv6-адреса для вашего дистрибутива. Дополнительная настройка не требуется.

Пример Terraform#

Инфраструктура как код для dual-stack настройки AWS:

# VPC с IPv6
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  assign_generated_ipv6_cidr_block = true
  enable_dns_support   = true
  enable_dns_hostnames = true
 
  tags = {
    Name = "main-vpc"
  }
}
 
# Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
}
 
# Egress-Only Internet Gateway
resource "aws_egress_only_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
}
 
# Публичная подсеть
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  ipv6_cidr_block         = cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, 1)
  assign_ipv6_address_on_creation = true
  availability_zone       = "us-east-1a"
 
  tags = {
    Name = "public-subnet"
  }
}
 
# Таблица маршрутизации для публичной подсети
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
 
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
 
  route {
    ipv6_cidr_block = "::/0"
    gateway_id      = aws_internet_gateway.main.id
  }
 
  tags = {
    Name = "public-rt"
  }
}
 
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}
 
# Группа безопасности
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Allow HTTP/HTTPS"
  vpc_id      = aws_vpc.main.id
 
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
 
  ingress {
    from_port   = -1
    to_port     = -1
    protocol    = "ipv6-icmp"
    ipv6_cidr_blocks = ["::/0"]
  }
 
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}
 
# EC2 инстанс с IPv6
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"  # Amazon Linux 2023
  instance_type = "t3.medium"
  subnet_id     = aws_subnet.public.id
  ipv6_address_count = 1
 
  vpc_security_group_ids = [aws_security_group.web.id]
 
  tags = {
    Name = "web-server"
  }
}
 
# Application Load Balancer
resource "aws_lb" "main" {
  name               = "main-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.web.id]
  subnets            = [aws_subnet.public.id]  # Добавьте больше подсетей для HA
  ip_address_type    = "dualstack"
 
  tags = {
    Name = "main-alb"
  }
}
 
# Вывод IPv6 CIDR
output "vpc_ipv6_cidr" {
  value = aws_vpc.main.ipv6_cidr_block
}
 
output "instance_ipv6" {
  value = aws_instance.web.ipv6_addresses
}

Примените с помощью:

terraform init
terraform plan
terraform apply

Тестирование вашего AWS IPv6 развертывания#

Проверьте сквозную связь:

# Тест DNS-резолвинга
dig app.example.com AAAA
 
# Тест HTTP/HTTPS доступа
curl -6 https://app.example.com
 
# Тест с инстанса
ssh ec2-user@<instance-ipv6>
ping6 google.com
curl -6 https://ifconfig.co

Используйте AWS Reachability Analyzer для проверки сетевых путей:

aws ec2 create-network-insights-path \
  --source <instance-eni> \
  --destination <alb-eni> \
  --protocol tcp \
  --destination-port 443
 
aws ec2 start-network-insights-analysis \
  --network-insights-path-id <path-id>

Проверьте на неправильные конфигурации, которые могут блокировать IPv6.

Распространенные проблемы и решения#

Проблема: Инстанс имеет IPv6-адрес, но не может достичь интернета Решение: Проверьте, что таблица маршрутизации имеет маршрут ::/0 к IGW, проверьте группу безопасности на исходящий IPv6

Проблема: У балансировщика нет AAAA-записи Решение: Убедитесь, что ip-address-type установлен на dualstack, проверьте, что подсети имеют IPv6 CIDR-блоки

Проблема: Невозможно подключиться по SSH к инстансу через IPv6 Решение: Добавьте правило группы безопасности, разрешающее TCP порт 22 от ::/0 или конкретного IPv6 CIDR

Проблема: Egress-only шлюз не работает Решение: Проверьте ассоциацию таблицы маршрутизации, проверьте, что инстансу назначен IPv6-адрес

Проблема: CloudFront не обслуживает через IPv6 Решение: IPv6 в CloudFront автоматический и не может быть отключен — проверьте DNS-резолвинг и связь клиента

Соображения о стоимости#

Сам IPv6 бесплатен в AWS. Вы не платите за IPv6 CIDR-блоки или адреса.

Стоимость передачи данных одинакова для IPv4 и IPv6. Нет ценового преимущества у IPv6 — преимущество в архитектурной простоте и избежании истощения IPv4.

Egress-only интернет-шлюзы бесплатны (в отличие от NAT-шлюзов, которые стоят ~$0.045/час плюс плата за обработку данных).

Связанные статьи#

Проверьте связь AWS IPv6

Используйте наш Ping-инструмент для тестирования ваших AWS-ресурсов и DNS-инструмент для проверки ваших Route 53 AAAA-записей.

Дополнительные ресурсы#