2023年 7月 30日に AWS よりパブリック IPv4 アドレス利用についての新しい料金体系が発表され、2024年 2月 1日 からパブリック IPv4 アドレスの利用に対して課金が発生することになります。せっかくの機会ですので EC2 に割り当てていた IP を v4 から v6 に移行してみました。

2024/04/26 更新

2024年04月25日 (日本時間26日) 自動割り当てされたパブリック IPv4 アドレスが動的に削除、追加できるようになようになりました。これにより EC2 のクローンは不要になりますので一部記事を修正しました。

また、パブリック IPv4 アドレスは 1つまでであれば、毎月無料になります(1ヶ月あたり750時間分は無料)。これは無料利用枠の扱いなので、Organizations 管理下のアカウントでは適用されない点にご注意ください。

もう1つ、エンドポイントがまだ IPv6 に対応していない AWS サービスが一部あるので、EC2 から利用している場合はご注意ください。

前提

普段は起動していないのですが、パブリックサブネットに EC2 を 1つ作成し、Elastic IP (EIP) を設定していましたので、こちらのインスタンスの IP を v4 から v6 に移行していきます(普段起動していないので、EIP のコストが普段からかかっていました…)。

また、移行前の時点では VPC には v4 CIDR のみ設定しており、v6 に関しては何も設定していない状態です。

最初にお伝えしておくと、EC2 起動時にパブリック IP を自動設定するようにしていた場合(パブリックサブネットだとそうなってるケースが多いと思います)、EC2 をクローン(AMI を取得して、インスタンスを再作成)する必要があります (2024/04/26 更新: 不要になりました)。

0. 事前準備

EC2 にインストールしているソフトについて、必要であれば IPv6 でリッスンできるようにしておきます。例えば Nginx とかであれば

http {
  # :
  server {
    # :
    # IPv6 でリッスンするようにする
    listen [::]:443 ssl http2;
  }
}

1. VPC に IPv6 CIDR を割り当て

まずはじめに、VPC に IPv6 CIDR を割り当てます。Amazon から提供されるブロックを利用します。

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

マネジメントコンソールの場合

マネジメントコンソールからだと、“お使いの VPC” から VPC を選択した状態で “アクション” メニューから

Edit VPC CIDR

“Add New IPv6 CIDR” を選択します。

Select “Add New IPv6 CIDR”

“Amazon-provided IPv6 CIDR block” を選択します。

Select Amazon-provided IPv6 CIDR block

2. サブネットに IPv6 CIDR を割り当て

今回は IPv6 only サブネットを作成するのではなく、既存のサブネットに IPv6 を追加するようにしました。

aws ec2 associate-subnet-cidr-block \
  --ipv6-cidr-block 24XX:XXXX:XXXX:XX00::/64 \
  --subnet-id subnet-XXXXX

マネジメントコンソールの場合

マネジメントコンソールからだと、“VPC” - “サブネット” から該当のサブネットを選択した状態で “アクション” メニューから “IPv6 CIDR の編集” を選択します。

Select “Edit IPv6 CIDRs”

“IPv6 CIDR を追加” から CIDR を追加します(下図は追加した状態です)。

Edit IPv6 CIDRs

IPv6 を利用するサブネット全てについて IPv6 CIDR を追加していきます。

3. ルートテーブルの編集

続いてルートテーブルを変更します。パブリックサブネットの場合は IPv6 のルートを Internet Gateway (IGW) に向けてあげます。

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

マネジメントコンソールの場合

マネジメントコンソールの場合は “VPC” - “ルートテーブル” から該当のルートテーブルを選択した状態で “アクション” メニューから “ルートを編集” を選択します。

Select “Edit routes”

“ルートを追加” を選択し、送信先 ::/0、ターゲットに IGW (IPv4 と同じもの) を設定します。

Edit routes

4. サブネットの IP アドレス自動割り当て設定の変更

パブリックサブネットの場合 EC2 インスタンスを作成すると、通常 パブリック IPv4 アドレスが自動的に割り当てられるような設定になっているかと思いますので無効化しておきます。

aws ec2 modify-subnet-attribute \
  --no-map-public-ip-on-launch \
  --subnet-id subnet-XXXXX

また、EC2 作成時に IPv6 アドレスが自動的に割り当てられるようにしておきます。

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

マネジメントコンソールの場合

マネジメントコンソールからだと、“VPC” - “サブネット” から該当のサブネットを選択した状態で “アクション” メニューから “サブネットの設定の編集” を選択します。

Select “Edit subnet settings”

“IP アドレスの自動割り当て設定” で IPv6 を有効にし、IPv4 を無効にします。

Edit “Auto-assign IP settings”

5. 既存 EC2 の パブリック IP アドレスの自動割り当て設定について

ここまでの設定で、今後 新規に作成する EC2 にはパブリック IPv4 アドレスが割り当てられない状態で起動するようになります。 が、既存の EC2 については作成時にパブリック IPv4 アドレスを自動割り当てするようにしていた場合、サブネットの設定で IPv4 の割り当てを無効にしていても起動時に v4 アドレスが割り当たってしまいます。現時点では後から変更ができなさそうです

なので既存の EC2 でパブリック IPv4 アドレスが自動的に割り当たってしまうものは AMI を作成し、クローンします。そして、AMI からのインスタンス作成時に以下のように “ネットワーク設定” にて “パブリック IP の自動割り当て” を “無効化” にして作り直します(今回は IPv6 アドレスを手動で割り当ててみようと思いましたので IPv6 の方も無効化しています)。

2024/04/26 更新: 既存の EC2 についてもパブリック IPv4 の自動割り当て設定を変更できるようになりました。次の手順「6.」の中で紹介します。

6. IPv6 アドレスの割り当てとパブリック IPv4 自動割り当ての無効化

EC2 に IPv6 アドレスを割り当てていきます。自動割り当て、手動割り当てそれぞれ紹介します。
また、パブリック IPv4 アドレスの自動割り当ての設定を無効化しておきます。

6.1-a. IPv6 アドレスを自動で割り当てる場合

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

--ipv6-address-count でいくつ割り当てるかを指定します。

6.1-b. IPv6 アドレスを手動で割り当てる場合

手動で割り当てる場合は --ipv6-addresses オプションで直接指定します。

aws ec2 assign-ipv6-addresses \
  --network-interface-id eni-XXXXX \
  --ipv6-addresses 24XX:XXXX:XXXX:XX00::1

An error occurred (InvalidParameterValue) when calling the AssignIpv6Addresses operation: Address is in subnet's reserved address range

どうやら ...00::1 から ...00::3 は予約されているようで、割り当てできませんでした。なので ...00::4 で割り当てます。

aws ec2 assign-ipv6-addresses \
  --network-interface-id eni-XXXXX \
  --ipv6-addresses 24XX:XXXX:XXXX:XX00::4

6.2 プライマリ設定

また、プライマリ IPv6 の割り当てを有効化しておきます。これにより ENI に関連付けられている最初の IPv6 アドレスを変更不可能にすることができます。

aws ec2 modify-network-interface-attribute \
  --enable-primary-ipv6 \
  --network-interface-id eni-XXXXX

6.3 パブリック IPv4 アドレスの自動割り当ての無効化 (2024/04/26 追記)

AWS CLI v1 (1.32.91 ~) には modify-network-interface-attribute というコマンドに --no-associate-public-ip-address というオプションが存在するようですが(v1 ドキュメント)、v2 (2.15.41) ではまだないようです (v2 ドキュメント)。

とりあえずですが、v1 でのコマンドを載せておきます。v2 しかない場合はマネジメントコンソールから設定します。

※パブリック IP がオープンアドレス (Elastic IP ではない) 場合、実行するとパブリック IPv4 アドレスがすぐに外れます。パブリック IPv4 経由での接続ができなくなるので起動中の EC2 で実行する場合は注意してください。

# AWS CLI v1 で実行
aws ec2 modify-network-interface-attribute \
  --no-associate-public-ip-address \
  --network-interface-id eni-XXXXX

マネジメントコンソールの場合

マネジメントコンソールからは “EC2” - “インスタンス” から該当の EC2 インスタンスを選択し、“アクション” メニューから “ネットワーキング” - “IP アドレスの管理” を選択します。

Select “Networking” - “Manage IP addresses”

IPv6 の “新しい IP アドレスの割り当て” を選択し、以下のように設定します。

  • 自動割り当ての場合は “空欄”
  • 手動割り当ての場合は “IPv6 アドレス”

“IPv6 のプライマリ設定” を有効にしておきます。

“パブリック IPv4 アドレスの自動割り当て” を無効にしておきます。
※この設定は保存するとパブリック IP がオープンアドレス (Elastic IP ではない) 場合、パブリック IPv4 アドレスがすぐに外れます。パブリック IPv4 経由での接続ができなくなるので起動中の EC2 で実行する場合は注意してください。

Manage IP Addresses

7. EC2 のセキュリティグループの変更

必要に応じてセキュリティグループを変更しておきます。例えば ::/0 から HTTPS を許可する場合は以下。

aws ec2 authorize-security-group-ingress \
  --group-id sg-XXXXX \
  --ip-permissions '[
    {
      "IpProtocol": "tcp",
      "FromPort": 443,
      "ToPort": 443,
      "Ipv6Ranges": [
        {
          "CidrIpv6": "::/0",
          "Description": "Allow from any"
        }
      ]
    }
  ]'

また、不要になった IPv4 のルールがあれば削除しておきます。

aws ec2 revoke-security-group-ingress \
  --group-id sg-XXXXX \
  --security-group-rule-ids sgr-XXXXX

8. その他の必要な項目

DNS の設定

DNS で名前解決をしていた場合は、A レコードではなく AAAA レコードをゾーンに追加します。IPv4 の A レコードは削除しておきます。

EC2 に SSH 等で接続する場合(EC2 Instance Connect Endpoint)

Session Manager で EC2 に接続していた場合、IPv6 になるとパブリックサブネットからは接続できなくなります(IPv6 のエンドポイントが現状まだ提供されていないため)。そこで、EC2 Instance Connect Endpoint (EICE) を使って接続するようにします。EICE は無料で使えることができ、パブリック IPv4 なしで EC2 に接続できるようになります。VPC 内にエンドポイントを作成しますので EC2 と EICE は プライベートな IPv4 で接続できるはずです(なので IPv6 only サブネットだと使えません)。

以下を参考に構成ください。

EC2 に SSH 等で接続する場合(Session Manager を使う必要がある場合)

IPv6 only サブネットやパブリックサブネットからどうしても Session Manager を使って接続しなければならない場合は、NAT Gateway が必要になりますが、サブネットの設定変更で DNS64 を有効化し、(参考 : DNS64 とは

aws ec2 modify-subnet-attribute \
  --enable-dns64 \
  --subnet-id subnet-XXXXX

ルートテーブルで 64:ff9b::/96 プレフィックス(IPv4 から IPv6 に変換されたアドレス)については、NAT Gateway を経由するようにすれば接続できそうです。

aws ec2 create-route \
  –-destination-ipv6-cidr-block 64:ff9b::/96 \
  –-nat-gateway-id nat-XXXXX \
  --route-table-id rtb-XXXXX

IPv6 only サブネットではない場合は Session Manager の VPC エンドポイントを構成してもプライベートな IPv4 を使って接続できると思います。
(参考 : Systems Manager を使用してインターネットアクセスなしでプライベート EC2 インスタンスを管理できるように、VPC エンドポイントを作成するにはどうすればよいですか?

9. EC2 起動 & 接続確認

準備ができたところで EC2 を起動します (2024/04/26 更新: AMI を取得して新しいインスタンスを起動する必要がなくなりました)。

ping で確認したい場合はセキュリティグループで v6 用の ICMP を許可して ping6 コマンドなどを使います。

curl で確認する場合は curl -6 http://....-6 オプションをつけるか、IP の場合は curl http://[24XX::1] のようにブラケットで囲みます。

名前解決できてるか確認する場合は dig example.com aaaaaaaa を指定することで AAAA レコードを問い合わせてくれます。

10. 不要になった EIP を解放 (EIP を割り当てていた場合)

EIP が不要になったら忘れずに解放しておきましょう(このための移行でしたので)。

まず、以前の EC2 との関連付けをはずします。eipassoc-XXXXX は VPC の “Elastic IPs” などから確認できます。

aws ec2 disassociate-address \
  --association-id eipassoc-XXXXX

続いて EIP を解放します。eipalloc-XXXXX は、前述の eipassoc-XXXXX とはぱっと見よく似てますが別のものです。VPC の “Elastic IP” で確認できます。

aws ec2 release-address \
  --allocation-id eipalloc-XXXXX

マネジメントコンソールの場合

マネジメントコンソールからは、まず EC2 で該当インスタンス(AMI を取得した際の元になったインスタンス)を選択して、“アクション” メニューから “ネットワーキング” - “Elastic IP アドレスの関連付けの解除” を選択します。

Select “Disassociate EIP”

よく確認して、関連付けを解除します。

Disassociate EIP

続いて、“VPC” の “Elastic IP” から解放する EIP を選択して、“アクション” メニューから “Elastic IP アドレスの解放” を選択します。

Select “Release EIP”

11. パブリック IPv4 アドレスが割り当てられていないことを確認

マネジメントコンソールで確認してみます。EC2 で該当のインスタンスを選択し、“詳細” タブを確認します。

Check neither assigned ipv4

まとめ

パブリックサブネットの EC2 を IPv4 から IPv6 に移行してみました。EC2 起動時の IPv4 自動割り当てが後から変更できないようなので AMI を取得してインスタンスを作り直さないといけないのがちょっとポイントですかね (2024/04/26 更新: 変更できるようになりました)

まだまだ AWS サービスの API エンドポイントが IPv6 に対応していないサービスが一部あるので、完全に移行するのは難しいかもしれませんが、“IPv6 に慣れておく” という意味ではできるものから移行しておくと良いかもですね。

(参考 : IPv6 をサポートする AWS サービス : https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/aws-ipv6-support.html)

最後に・・・

この投稿は個人的なものであり、所属組織を代表するものではありません。ご了承ください。