VPCを学ぶ - IPv6のEC2を作る-

# 概要

IPv6 CIDR ブロックを選択したVPC、サブネットを作成して属するEC2を作ってみた。
t2インスタンスはv6未対応で、t3インスタンスで作った。
そしてまぁやっぱりインターネットゲートウェイをアタッチしてないので、グローバルIPv6アドレスが割り振られているが、sshできないEC2インスタンスができたぽい。
インターネットゲートウェイをアタッチしてルーティングを設定したらsshできた。内側から外へIPv6で通信できることも確認できた。加えてグローバルIPv4アドレスがなかったらその方式ではインターネットに向かっての通信はできないことも確認できた。


# VPCを作る

リージョンを米国（バージニア北部）としておく。

1. VPCダッシュボードへゆく
1. 「お使いのVPC」を選択
1. 右の「VPCを作成」ボタンを押す

## VPCの設定パラメータ

### 作成するリソース
VPCのみ

### 名前タグ

learning-v6-{日付} とでもしておく

例) `learning-v6-20250605`

### IPv4 CIDR ブロック

IPv4 CIDR の手動入力
(IPAM〜については便利機能なのでいったんここではパス)

#### IPv4 CIDR

`10.0.0.0/16`


#### IPv6 CIDR ブロック

ここについて前回は「IPv6 CIDR ブロックなし」を選んだが、選択していく。

とりあえず IPv6については別途知識をつけるとして、ここでは選択肢3 「Amazon 提供の IPv6 CIDR ブロック」を選択する。

とりあえずここでの知識としてはIPv4でもそのようにv6でも「グローバルなIPアドレスを自分で適当に決めてマシンに設定すればよいというものではない」とだけ知っておけばよい。

**選択肢1 IPv6 CIDR ブロックなし**

これを選ばないという話

**選択肢2 IPAM 割り当ての IPv6 CIDR ブロック**

またIPAMがでてきたが、IPAMとは IP Address Manager の略で、AWSの提供する便利機能のことである。

もうちょっとプリミティブなところを学びたいので、この選択肢はパスする。

**選択肢3 Amazon 提供の IPv6 CIDR ブロック**

これを選択してAWSよりプレフィックスをもらう。

**選択肢4 IPv6 CIDR 所有 (ユーザー所有)**

こんなことができるんだなあ。とりあえず持っていないと思うんでパス。

#### ネットワークボーダーグループ

選択肢が  **us-east-1** しかないのでこれを選んでおく。

#### テナンシー

「デフォルト」を選んでおく。

#### VPCを作成

「VPCを作成」ボタンを押す。


# サブネットを作る

リージョンを米国（バージニア北部）としておく。

1. VPCダッシュボードへゆく
1. 左のメニューから「サブネット」を選択
1. 右上の「サブネットを作成」ボタンを押す

## サブネットを作成 パラメータ

### VPC ID

先ほど作ったVPCを選択する(例: `learning-v6-20250605` )

### サブネットの設定

**サブネット名**

`learning-subnet-v6-20250605` とでもしておく。

**アベイラビリティーゾーン**

先頭の `us-east-1a` を選んでおく

**IPv4CIDRブロック**

v6ありのVPCにしている場合(?)、「IPv4 CIDRがありません」という選択肢があるので、これを選んでみる。

**IPv6CIDRブロック**

ドロップダウンの先頭を選んでおく
（ここでは `2600:1f18:697f:8c00::/56` となっている)

**IPv6 サブネット CIDR ブロック**

初期値で `2600:1f18:697f:8c00::/56` となっており　4,722.3Q IPsと表記されている。Qとは Quadrillion の略であり、つまるところ単位でいう京(億、兆の上)である。

そんなに多くても困るよお、、、ということで `2600:1f18:697f:8c00::/64` まで落としても 18.4Q なので、あんまかわらない？

とりあえず初期値の `/56` としておく。

**タグ**

そのまま


# EC2インスタンス の作成

1. EC2ダッシュボードに移動
1. 左のメニューからインスタンス
1. 右のオレンジンの「インスタンスを起動」ボタンを押す

## インスタンスを起動 のパラメータ

### 名前とタグ

`learning-v6-ec2-20250605` とでもしておく。

### アプリケーションおよびOSイメージ

Amazon Linux 2023 AMI のままでOK、他もデフォルト

### インスタンスタイプ

t2.micro がデフォルトで選択されているが、このインスタンスタイプ、まさかのIPv6 専用サブネットには未対応なのである。

しょうがないので `t3.nano` を選択する。

なのに、インスタンスタイプの比較、でIPv6まわりを表示すると「Yes」とか書いてある。しかしながら、IPv6専用サブネットに指定するにはハイパーバイザにNitroが採用されているものしか選べないらしい。

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#instance-hypervisor-type

ハイパーバイザ Nitro とは何か→ https://aws.amazon.com/jp/ec2/nitro/


### キーペア

前作ったものを指定すればよい。
私だったら `learning-vpc-keypair-25-424` だった。

### ネットワーク設定

「編集」ボタンを押す。

**VPC**

今回作った `learning-v6-20250605` なんかを選択する。

**サブネット**

先ほど作成したものを選択。私なら `learning-subnet-v6-20250605` 。

**パブリックIPの自動割り当て**

無効化されているのでそのまま

**IPv6 IP を自動で割り当てる**

今回は **有効化** を選択する。

**ファイアウォール(セキュリティグループ)**

「セキュリティグループを作成」を選ぶ

名前は `lerning-sg-launch-wizard-20250605` としておく。
インバウンドセキュリティグループのルールはいったんそのままにしておき、sshを通すようにしておく。

### その他

以降はそのままにして右側の「インスタンスを起動」ボタンを押す。

# EC2インスタンス に ssh を試みる

1. EC2ダッシュボードに移動
1. 左のメニューからインスタンス
1. 先ほど作った `learning-v6-ec2-20250605` を選択する

「パブリック IPv4 アドレス」が「-」
「プライベート IPv4 アドレス」が空欄
「パブリック DNS」が「-」

となっているのが確認できる。

IPv6は値が設定されているのでそれをコピーする。

さてそこで接続しようとしたが、そもそも今、これを書いている環境では IPv6 に対応したネットワーク環境にない！

## 自分の環境がIPv6に対応しているか確認する方法

一番簡単なのは curl に `-6` オプションをつける。

### IPv6通信ができる場合

```
[pharaohkj] $ curl -v -6 http://google.com
* Host google.com:80 was resolved.
* IPv6: 2404:6800:4004:827::200e
* IPv4: (none)
*   Trying [2404:6800:4004:827::200e]:80...
* Connected to google.com (2404:6800:4004:827::200e) port 80
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-OtpOnXIO_IN2lhtlXoaLhw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
< Date: Wed, 11 Jun 2025 00:35:35 GMT
< Expires: Fri, 11 Jul 2025 00:35:35 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact
```

### IPv6通信できない場合

名前はひけるが、接続できぬ。

```
~ $ curl -v -6 http://google.com
* Host google.com:80 was resolved.
* IPv6: 2607:f8b0:4004:c17::66, 2607:f8b0:4004:c17::71, 2607:f8b0:4004:c17::8b, 2607:f8b0:4004:c17::8a
* IPv4: (none)
*   Trying [2607:f8b0:4004:c17::66]:80...
* Immediate connect fail for 2607:f8b0:4004:c17::66: Network is unreachable
*   Trying [2607:f8b0:4004:c17::71]:80...
* Immediate connect fail for 2607:f8b0:4004:c17::71: Network is unreachable
*   Trying [2607:f8b0:4004:c17::8b]:80...
* Immediate connect fail for 2607:f8b0:4004:c17::8b: Network is unreachable
*   Trying [2607:f8b0:4004:c17::8a]:80...
* Immediate connect fail for 2607:f8b0:4004:c17::8a: Network is unreachable
* Failed to connect to google.com port 80 after 2 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to google.com port 80 after 2 ms: Couldn't connect to server
```

# sshしてみる

キーは前作ったものを指定。アドレスは前述の手順でコピーしたものを指定してトライ。

```
[pharaohkj] $ ssh -i ~/Downloads/learning-vpc-keypair-25-424.pem ec2-user@2600:1f18:697f:8c5c:XXXX:XXXX:XXXX:XXXX
```

つながらない。応答がない。そもそもこのVPCにはインターネットゲートウェイをまだアタッチしていない。

# インターネットゲートウェイをVPCにアタッチする

1. AWSのダッシュボードに行く
1. VPCで検索してそのダッシュボードに行く
1. 左のメニューから「インターネットゲートウェイ」を選択
1. 右側「インターネットゲートウェイの作成」ボタンを押して作成画面へ

## インターネットゲートウェイの作成 パラメータ

### インターネットゲートウェイの設定

**名前タグ**

名前を `learning-v6-igw-20250611` とでもしておく。

### インターネットゲートウェイの作成

「インターネットゲートウェイの作成」ボタンを押して作成する。

## 作ったIGWをアタッチ

1. AWSのダッシュボードに行く
1. VPCで検索してそのダッシュボードに行く
1. 左のメニューから「インターネットゲートウェイ」を選択
1. 先ほど作成した `learning-v6-igw-20250611` を選択
1. 画面が遷移するので、そこで「アクション」ボタンを押す
1. ドロップダウンで操作がでてくるので「VPCにアタッチ」を選択
1. 画面が遷移するので「使用可能な VPC」のパラメータに先ほど作成したVPCを検索して選択(名前タグが表示されるので、私の場合は `learning-v6-20250605` と表示されたものを選択
1. 「インターネットゲートウェイのアタッチ」ボタンを押す

## ルーティングを確認&設定する

1. VPCダッシュボードへ行く
1. ダッシュボードからサービスを検索「VPC」
1. 左のメニューから「お使いのVPC」
1. 先ほど作ったもののVPC ID ( `learning-v6-20250605` ) をクリックして進む
1. 最下段から「リソースマップ」のタブを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50220/05c811ca-91f7-47e6-9ebc-c4de6e05f525.png)

確認の画像で確認できるとおり、今回も自動で作成された「ルートテーブル」と自動で指定されたサブネットからそれが接続されていることが確認できる。

しかし、今回も先ほど作成したigwとサブネットとルートテーブルが接続されていない。

### ルートテーブルの確認と編集

1. VPCダッシュボードへ行く
1. ダッシュボードからサービスを検索「VPC」
1. 左のメニューから「ルートテーブル」
1. 自動でできたもののルートテーブルIDを選択する
  1. このIDがわからない場合、「ルートテーブルの確認」で調べることができる
1. 採用されているVPC IDと名前タグがそこにも記載されている

ここに「ルート」という項目がでており 10.0.0.0/16 はlocalとなっているまでは前回といっしょ。
それに加えて `2600:1f18:697f:8c00::/56` も local となっていて、2行になっている。

v4部分は前回と同じ

1. 「ルートを編集」ボタンを押す
1. 現在の設定が2行あるのを確認したら「ルートを追加」ボタンを押す
1. 新しい行が追加される
  1. 送信先には 0.0.0.0/0 を指定
  1. ターゲットにはインターネットゲートウェイを選択し、先ほど作成したigw idを指定する(マウスで選択すれば選択肢がでてくる)
1. 「ルートを追加」ボタンをさらに押す
1. 新しい行が追加される
  1. 送信先には `::/0` を指定(これの意味がわからんという場合にはIPv6を再入門せよ)
  1. ターゲットにはインターネットゲートウェイを選択し、先ほど作成したigw idを指定する(マウスで選択すれば選択肢がでてくる)
1. 「変更を保存」ボタンを押す


### ルートテーブルの再確認

1. VPCダッシュボードへ行く
  1. ダッシュボードからサービスを検索「VPC」
1. 左のメニューから「お使いのVPC」
1. 先ほど作ったもののVPC IDをクリックして進む
1. 最下段から「リソースマップ」のタブを選択する

先ほどと違い、ルートテーブルとigwが接続されているのが確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50220/323fa3a3-e3a3-4c6c-9a5c-5e62d9c3485c.png)

# 再度sshしてみる

キーは前作ったものを指定。アドレスは前述の手順でコピーしたものを指定してトライ。

今回はちゃんと接続された。パブリックIPv4なしで通信できた。

```
[pharaohkj] $ ssh -i ~/Downloads/learning-vpc-keypair-25-424.pem ec2-user@2600:1f18:697f:8c5c:XXXX:XXXX:XXXX:XXXX
...
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
```

# 内側から外側も試しておく

`curl -6` で試す。ちゃんと内側からインターネットにアクセスもできている。

```
[ec2-user@i-0912454cb25xxxxxx ~]$ curl -v -6 http://google.com
* Host google.com:80 was resolved.
* IPv6: 2607:f8b0:4004:c06::8b, 2607:f8b0:4004:c06::65, 2607:f8b0:4004:c06::64, 2607:f8b0:4004:c06::71
* IPv4: (none)
*   Trying [2607:f8b0:4004:c06::8b]:80...
* Connected to google.com (2607:f8b0:4004:c06::8b) port 80
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-ZdtLzgavwjCikp7I9nCivg' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
< Date: Wed, 11 Jun 2025 10:40:45 GMT
< Expires: Fri, 11 Jul 2025 10:40:45 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact
```

# `ip a`

`ens5` にはグローバルなIPアドレス( `2600:〜` )とローカルなIPアドレス( `fe80::〜` )が設定されている。

v4アドレスは、、、これはなんかDHCPがいないやつみたいなのがついてる。もしかしてv4通信ができない？

```
[ec2-user@i-0912454cb25xxxxxx ~]$ 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 noprefixroute
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 12:11:8b:9e:ac:f7 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname eni-009f4c29ca80ffecc
    altname device-number-0.0
    inet 169.254.163.99/32 metric 512 scope global dynamic ens5
       valid_lft 2650sec preferred_lft 2650sec
    inet6 2600:1f18:697f:8c5c:XXXX:XXXX:XXXX:XXXX/128 scope global dynamic noprefixroute
       valid_lft 414sec preferred_lft 104sec
    inet6 fe80::1011:8bff:fe9e:acf7/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever
```

# 内側から外側を試す2

接続できない。そりゃそうで、v4ルートでインターネットにアクセスしたかったらグローバルIPアドレスのアタッチがマストであることを確認できた。

```
[ec2-user@i-0912454cb2576b4bb ~]$ curl -v -4 http://google.com
* Host google.com:80 was resolved.
* IPv6: (none)
* IPv4: 142.250.31.100, 142.250.31.139, 142.250.31.101, 142.250.31.138, 142.250.31.102, 142.250.31.113
*   Trying 142.250.31.100:80...
* Immediate connect fail for 142.250.31.100: Network is unreachable
*   Trying 142.250.31.139:80...
* Immediate connect fail for 142.250.31.139: Network is unreachable
*   Trying 142.250.31.101:80...
* Immediate connect fail for 142.250.31.101: Network is unreachable
*   Trying 142.250.31.138:80...
* Immediate connect fail for 142.250.31.138: Network is unreachable
*   Trying 142.250.31.102:80...
* Immediate connect fail for 142.250.31.102: Network is unreachable
*   Trying 142.250.31.113:80...
* Immediate connect fail for 142.250.31.113: Network is unreachable
* Failed to connect to google.com port 80 after 1 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to google.com port 80 after 1 ms: Couldn't connect to server
```