IPv6 は今どれくらい普及しているんだろうか?と思って Google のレポートで調べてみたところ、2020-07-18 時点で日本は 34.45% でした。Google のサービスへアクセスしているログから集計しているということだったので、仕事や家庭含めてリアルな普及率のような気がします。個人的には意外にも普及しているなという印象です。

スクリーンショット 2020-07-17 19 06 42

そして AWS VPC が IPv6 対応をしてからしばらく経ちますが、こんな状況なので改めて IPv6 対応のサーバ環境を ALB + EC2 で作り動作確認をしました。

VPC を IPv6 対応にする

まず VPC を IPv6 対応にする必要があります。メニューの VPC -> CIDR の編集から VPC IPv6 CIDR を追加します。

0 1

サブネットに IPv6 CIDR を追加する

次に VPC -> サブネットから該当のサブネット全てに IPv6 CIDR を追加します。

2 3

インターネットゲートウェイのルートテーブルに IPv6 を追加する

この設定は ALB + EC2 のサーバを IPv6 で接続を受け付けるだけなら必要ないです。これは VPC 内の EC2 インスタンスが IPv6 で外のインターネットに通信しにいくための設定です。今回は IPv6 で接続ができているかどうかの動作確認ように設定をしています。

VPC -> ルートテーブルから、::/0 と IPv6 通信設定を追加します。

4

ALB と EC2 を IPv6 対応にする

EC2 インスタンスに IPv6 を割り当てる

こちらもルートテーブルと同様に IPv6 の通信動作確認用の設定になります。もしくは ALB を使わず直接 EC2 インスタンスのサーバへ IPv6 接続がしたい場合は必要になる設定です。

対象インスタンスを選択し アクション -> ネットワーキング -> IP アドレスの管理 から選択し、IPv6 アドレスを割り当てます。

5 6

EC2 インスタンスへ入り ip コマンドで IPv6 が正常に割り当てられているのを確認します。

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 06:21:6a:ef:87:9e brd ff:ff:ff:ff:ff:ff
    inet 172.31.39.22/20 brd 172.31.47.255 scope global dynamic eth0
       valid_lft 3208sec preferred_lft 3208sec
    inet6 2406:da14:8a1:a900:6413:xxxx:xxxx:xxxx/128 scope global dynamic
       valid_lft 431sec preferred_lft 131sec
    inet6 fe80::421:6aff:feef:879e/64 scope link
       valid_lft forever preferred_lft forever

inet6 2406:da14:8a1:a900:6413:xxxx:xxxx:xxxx/128 scope global dynamic で正常にグローバルな IPv6 アドレスが設定されているのが確認できました。もし、設定がされていないということであれば sudo systemctl restart network/etc/sysconfig/network-scripts/ifcfg-eth0 の設定を見直してみてください。

AmazonLinux2 のデフォルト設定のままで問題ないはずです。

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

ALB を IPv6 対応にする

ALB が IPv6 で接続できるようにするため IP アドレスタイプを dualstack にします。アベイラビリティゾーンにそれぞれサブネットで割り当てた IPv6 CIDR が自動でセットされるはずです。ALB が IPv6 で受け付けて通信をしてくれるので、内部の EC2 インスタンスはグローバルな IPv6 アドレスが割り当てられてなくても問題ありません。

7

IPv6 通信の動作確認をする

まずは、 IPv6 アドレスを持った EC2 インスタンスから IPv6 通信ができているかの確認をします。

$ ping6 -c 5 ipv6.google.com
PING ipv6.google.com(nrt20s17-in-x0e.1e100.net (2404:6800:4004:813::200e)) 56 data bytes
64 bytes from nrt20s17-in-x0e.1e100.net (2404:6800:4004:813::200e): icmp_seq=1 ttl=46 time=3.40 ms
64 bytes from nrt20s17-in-x0e.1e100.net (2404:6800:4004:813::200e): icmp_seq=2 ttl=46 time=2.84 ms
64 bytes from nrt20s17-in-x0e.1e100.net (2404:6800:4004:813::200e): icmp_seq=3 ttl=46 time=2.83 ms
64 bytes from nrt20s17-in-x0e.1e100.net (2404:6800:4004:813::200e): icmp_seq=4 ttl=46 time=2.86 ms

ping6 コマンドを使うと IPv6 で ping を打ってくれます。正常に返ってきています。

$ curl -D - -v6s -o /dev/null ipv6.google.com
* Rebuilt URL to: ipv6.google.com/
*   Trying 2404:6800:4004:813::200e...
* TCP_NODELAY set
* Connected to ipv6.google.com (2404:6800:4004:813::200e) port 80 (#0)
> GET / HTTP/1.1
> Host: ipv6.google.com

curl-6 オプションで IPv6 で通信できるので ipv6.google.com に接続をして正常にレスポンスされることが確認できます。

最後に IPv6 対応をした ALB のホストに接続をします。まずは ALB ホストの名前解決をし AAAA レコードが IPv6 で設定されているかを確認します。

$  dig sample-zaru-1111.ap-northeast-1.elb.amazonaws.com aaaa

; <<>> DiG 9.10.6 <<>> sample-zaru-1111.ap-northeast-1.elb.amazonaws.com aaaa
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16995
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sample-zaru-1111.ap-northeast-1.elb.amazonaws.com. IN AAAA

;; ANSWER SECTION:
sample-zaru-1111.ap-northeast-1.elb.amazonaws.com. 60 IN AAAA 2406:da14:8a1:a901:d9:xxxx:xxxx:xxxx
sample-zaru-1111.ap-northeast-1.elb.amazonaws.com. 60 IN AAAA 2406:da14:8a1:a900:7639:xxxx:xxxx:xxxx

dig コマンドで AAAA レコードの問い合わせをすると正常に IPv6 アドレスが返ってきました。

そして、 curl で問い合わせをしてみます。

$ curl -v6 sample-zaru-1111.ap-northeast-1.elb.amazonaws.com
* Rebuilt URL to: sample-zaru-1111.ap-northeast-1.elb.amazonaws.com/
*   Trying 2406:da14:8a1:a900:7639:xxxx:xxxx:xxxx...
* TCP_NODELAY set
* Connected to sample-zaru-1111.ap-northeast-1.elb.amazonaws.com (2406:da14:8a1:a900:7639:xxxx:xxxx:xxxx) port 80 (#0)

無事接続できました。

逆に IPv4 環境から問い合わせてみます。

$ curl -v4 sample-zaru-1111.ap-northeast-1.elb.amazonaws.com
*   Trying ::ffff:18.177.xxx.xxx...
* TCP_NODELAY set
* Connected to sample-zaru-1817772116.ap-northeast-1.elb.amazonaws.com (::ffff:18.177.xxx.xxx) port 80 (#0)

正常に IPv4 として接続ができていることが確認できました。

以上で、ALB + EC2 インスタンスを IPv6 対応し、接続確認の設定のやり方です。簡単ですね。