はじめに
記事を見ていただいて、ありがとうございます!
Webエンジニアをしているsannoと申します。
AWSでパブリックIPv4アドレスに対する課金が2024/2/1から開始されますね。
仮にパブリックIPv4アドレスを今後も使い続ける場合に、どれぐらいのコストアップになるでしょうか。
0.005$/h/パブリックIPv4アドレスなので31days/monthで計算すると、0.005*24*31=3.72$/month/パブリックIPv4アドレスのコストアップになります。
これを高いと考えるか安いと考えるかはまちまちだと思いますが、ランニングコストは低い方が良いというのは共通の認識ではないでしょうか。
ですので、今回はパブリックIPv4アドレスを使わずにEC2でWebサーバーを構築する方法について、解説してみたいと思います。
EC2にIPv6アドレスを設定し、かつIPv4/IPv6どちらのリクエストも受けられるWebサーバーの構成となります。
良かったら見ていってください。
それでは構築してゆきましょう!
構成

環境
# 自身のPC
$ ssh -V
OpenSSH_9.0p1, LibreSSL 3.3.6
# EC2インスタンス内
$ dnf --version
4.12.0
Installed: dnf-0:4.12.0-2.amzn2023.0.4.noarch at Fri Nov 10 19:54:21 2023
Built : Amazon Linux at Tue Jan 31 01:01:11 2023
Installed: rpm-0:4.16.1.3-12.amzn2023.0.6.x86_64 at Fri Nov 10 19:54:03 2023
Built : Amazon Linux at Mon Apr 17 16:53:56 2023
# EC2インスタンス内
$ nginx -v
nginx version: nginx/1.24.0
構築
コンソール
VPC
IPv6が使えるVPCを作成します。
vpcで検索して”VPC”を選択します。

“お使いのVPC”を選択します。

“VPCを作成”を選択します。

IPv4 CIDR ブロックは”IPv4 CIDR の手動入力”を選択します。
CIDRブロックは/16で作成します。
IPアドレスの管理を厳密に行いたい場合は、以下の記事などを参考にVPC IP Address Manager管理のものを選択してください。
IPv6 CIDR ブロックは”Amazon 提供の IPv6 CIDR ブロック”を選択します。
こちらもIPアドレスを厳密に管理したい場合や、自身が所持しているIPv6を使いたい場合は他のものを選択してください。
IPv6 CIDR ブロックのそれぞれの設定について知りたい場合は、以下の記事など参照してみてください。
“VPCを作成”を選択します。


インターネットゲートウェイ
VPCにアタッチするインターネットゲートウェイを作成します。
vpcで検索して”VPC”を選択します。

“インターネットゲートウェイ”を選択します。

“インターネットゲートウェイの作成”を選択します。

名前を任意のものにして、”インターネットゲートウェイの作成”を選択します。

もう一度インターネットゲートウェイを開き、作成したインターネットゲートウェイを選択してアクションから”VPCにアタッチ”を選択します。

IPv6用に作成したVPCを選択して、”インターネットゲートウェイのアタッチ”を選択します。

サブネット
WebサーバーのEC2を含めるパブリックサブネットを作成します。
vpcで検索して”VPC”を選択します。

“サブネット”を選択します。

“サブネットを作成”を選択します。

IPv6用に作成したVPCを選択します。

アベイラビリティーゾーンは任意の場所で良いのですが、もう一つALBのターゲットの設定の部分で使うパブリックサブネットを作成するので、区別しやすく”1a”を選択します。
IPv4 subnet CIDR blockは”Manual Input”を選択して、/24にします。
IPv6だけで構成するのでIPv4の設定はいらないのではと思われるかもしれません。
ですが、ALBを使う場合にターゲットとして指定するサブネットの設定のところでエラーになるので、IPv4 subnet CIDR blockを設定する必要があります。
設定しないと、”Not enough IP space available in subnet-oooob. ELB requires at least 8 free IP addresses in each subnet.” のエラーになります。
IPv6 VPC CIDR blockは/56を選択します。
IPv6 subnet CIDR blockは/64を選択します。
執筆時点ですとIPv6 subnet CIDR blockの指定できるCIDR blockの範囲は限定されていましたので、その点は気をつけて設計してみてください。
IPv6 subnet CIDR blockの指定できるCIDR blockの範囲については、以下の記事などを参考にしてみてください。
また、厳密にIPv6の設計を考えたい場合は、以下の記事など参考にしてみてください。


“サブネットを作成”を選択します。

ALBの設定時に使うため、さきほど作成したパブリックサブネットとは異なるアベイラビリティーゾーンを設定するパブリックサブネットも作成します。
基本的に設定値はさきほどのパブリックサブネットと同じですが、IPv4 subnet CIDR blockとIPv6 subnet CIDR blockは被らないように気をつけてください。


ルートテーブル
パブリックサブネットにアタッチするルートテーブルを作成します。
vpcで検索して”VPC”を選択します。

“ルートテーブル”を選択します。

“ルートテーブルを作成”を選択します。

VPCはIPv6用に作成したVPCを選択して、”ルートテーブルを作成”を選択します。

作成したルートテーブルを編集したいので、もう一度ルートテーブルの画面を開き、アクションから”ルートの編集”を選択します。

パブリックサブネット内のWebサーバーからインターネットに出るルートを定義します。
ローカル内のいずれの宛先でもない場合にはインターネットゲートウェイを宛先にするルートです。
送信先:/0で、IPv6用に作成したVPCにアタッチしているインターネットゲートウェイをターゲットとするルートを追加します。
“変更を保存”を選択します。

作成したルートテーブルをサブネットにアタッチします。
もう一度ルートテーブルの画面を開き、アクションから”サブネットの関連付けを編集”を選びます。

IPv6用に作成したパブリックサブネットを選択し、”関連付けを保存”を選択します

セキュリティグループ
2つのセキュリティーグループを作成します。
作成する必要があるのは、ALBにアタッチするものとEC2のWebサーバーにアタッチするものです。
vpcで検索して”VPC”を選択します。

“セキュリティグループ”を選択します。

“セキュリティーグループを作成”を選択します。

最初にALBにアタッチするセキュリティーグループを作成します

エンドユーザーからのWebサーバーへのアクセスをALBが捌きます。
エンドユーザーがどのような環境からアクセスするかは不確定なので、HTTP/HTTPSとIPv4/IPv6の2*2=4通りの組み合わせでインバウンドルールを設定します。

アウトバウンドルールはとりあえず、すべての通信を許可を設定します。
ルールを厳格にしたほうが良いよと警告が出ていますが、今回はそのままゆきます。
設定ができたら、”セキュリティーグループを作成”を選択します。

次はWebサーバーのEC2用のセキュリティーグループを作成しましょう。
もう一度セキュリティーグループを開き作成します。

インバウンドルールは、さきほど作成したALBのセキュリティーグループをソースで選択し、ALB->EC2はHTTP通信にするのでHTTPの許可を設定します。
また、EC2インスタンスにSSHで接続して各種設定を行いたいので、そのインバウンドルールも追加します。
同じ環境から自分しかSSHでアクセスしないのであれば、マイIPで自身の環境のグローバルIPを設定すれば良いと思います。

アウトバウンドルールは今回も、すべての通信を許可を設定します。
設定ができたら、”セキュリティーグループを作成”を選択します。

EC2
Webサーバー用のEC2を作成します。
ec2で検索して”EC2″を選択します。

“インスタンス”を選択します。

“インスタンスを起動”を選択します。

Webサーバー用のEC2インスタンスを作成します。

AMIは”Amazon Linux 2023″を選択します。
“Amazon Linux 2″は2025/6/30にEOLなので、”Amazon Linux 2023″を選択しました。

今回は検証用なので、インスタンスタイプは安価な”t3.nano”を選択します。
SSHでEC2インスタンスに接続できるようにキーペアを作成します。
“新しいキーペアの作成”を選択します。

キーペアのタイプは”ED25519″で、プライベートキーファイル形式は”.pem”を選択します。
“RSA”か”ED25519″かは、以下の記事などを参考に皆さんの環境合ったものを選択してください。
また、プライベートキーファイル形式はOpenSSHで接続したいので”.pem”にしましたが、こちらも皆さんの環境合ったものを選択してください。
今回はSSH接続を選択しましたが、セキュリティー的にはEC2インスタンスのアクセスはSSHを使わずにセッションマネージャー等を使う方が良いと思います。
ですが、現時点でセッションマネージャを使うにはIPv4をEC2インスタンスに設定する必要があります。
(将来的にはIPv6だけで使えるようになるかもしれません)
今回は極力IPv4は使わないということと、最小の構成にしたいので、SSHでEC2インスタンスに接続するようにします。
もし、IPv4をEC2インスタンスに設定したくない、けれどもセッションマネージャーで接続したいという方は以下の記事等を参考にしてみてください。
設定ができたら、”キーペアの作成”を選択します。

VPC, サブネット, セキュリティーグループはIPv6用で先に用意していたものを選択します。
IPv6 IP を自動で割り当てるは”有効化”を設定します。

高度なネットワーク設定の部分で一つ大切な設定があります。
プライマリ IPv6 IP を割り当てる の設定の部分で、ここは”はい”に設定しておきましょう。
ここを設定しないと、ターゲットグループの設定のところでこのEC2インスタンスが選択できなくなってしまうので、忘れず設定しておきましょう。

ストレージを設定はデフォルトの設定のままにします。

設定ができたら、”インスタンス”を選択します。

SSHでEC2インスタンスに接続できることも確認しておきましょう。
キーぺア作成の時に作成した公開鍵のパーミッションを変更します。
chmod 400 key.pem
SSHを行います。
SSH接続でEC2インスタンスのIPv6アドレスが必要なので確認しておきましょう。

SSHコマンドを実行し、以下のような表示がされれば正常に接続できています。
ssh -i key.pem ec2-user@[ec2インスタンスのIPv6アドレス]
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
Last login: Wed Nov 29 13:25:04 2023 from ooooo::
[ec2-user@i-ooooo ~]$
Nginx
EC2インスタンスがWebサーバーとして機能するためにNginxの設定を行います。
Nginxの設定はEC2インスタン内で行います。
“dnf”でNginxのインストールを行います。
“amazon-linux-extras”を使う方法もありますが、Amazon Linux 2023ではデフォルトはインストールされていないので”dnf”を使います。
$ sudo dnf -y update # パッケージリストの更新
$ sudo dnf install nginx
...
Total download size: 1.0 M
Installed size: 3.4 M
$ Is this ok [y/N]: y # これでインストールして良いか聞かれるのでy 96 kB/s | 308 kB 00:03
...
Complete!
$ nginx -v # Nginx がインストールできたか確認
nginx version: nginx/1.24.0
Nginx設定ファイルの設定を行います。
Nginx設定ファイルについて知りたい方は、以下の記事などを参考にしてみてください。
NginxでIPv6にてHTTP通信できるようにするためには、以下のようなlistenの設定が必要です。
listen [::]:8000;
listen [::1];
環境にもよると思いますが、この設定は”nginx.conf”あるいは”nginx.conf.default”にデフォルトで設定されていることもあります。
ですので、自分で設定を追加する前にすでに設定が存在するか確認してみると良いと思います。
$ view /etc/nginx/nginx.conf
$ view /etc/nginx/nginx.conf.default
# いずれかのファイルに以下の設定があるか無ければ追加する
# この設定の場合は80番ポートのHTTPでIPv4/IPv6ともに通信できる
http {
...
server {
listen 80;
listen [::]:80;
...
}
}
Nginx設定ファイルが設定できたら、Nginxを起動しましょう
$ sudo systemctl start nginx.service
以下のようにプロセスが確認できれば、Nginxが起動しています。
$ ps -aux | grep nginx
root 1709 0.0 0.3 29808 1364 ? Ss 23:03 0:00 nginx: master process /usr/sbin/nginx
nginx 1710 0.0 0.7 41532 3224 ? S 23:03 0:00 nginx: worker process
nginx 1711 0.0 0.7 41532 3220 ? S 23:03 0:00 nginx: worker process
ACM
独自ドメインのHTTPS通信でWebサーバーにアクセスできるようにしたいので、ACMでSSL/TLS 証明書の発行を行います。
もし、すでに別の方法でSSL/TLS 証明書の発行を行なっている場合は、ACMでの操作は不要です。
acmで検索して”Certificate Manager”を選択します。

“証明書をリクエスト”を選択します。

“パブリック証明書をリクエスト”を選択して、”次へ”を選択します。

検証方法は”DNS検証”を選択します。
Route 53でネームサーバーの設定をしているのならば、管理をしやすいので”DNS検証”がおすすめです。

キーアルゴリズムについては”ECDSA P 384″を選択します。
以下の記事などを参考に、皆さんの環境に合ったキーアルゴリズム選択してみてください。
設定ができたら、”リクエスト”を選択します。

検証方法で”DNS検証”を選択している場合は、検証もしてしまいましょう。
“証明書を一覧”から該当の証明書IDを選択します。

“Route 53でレコードを作成”を選択します。

“レコードを作成”を選択します。

“証明書を一覧”から、該当の証明書のステータスが”発行済み”になっていれば検証が完了しています。

ターゲットグループ
ALBのターゲットグループを作成します。
ec2で検索して”EC2″を選択します。

“ターゲットグループ”を選択します。

“ターゲットグループの作成”を選択します。

ターゲットタイプの選択はEC2インスタンスをターゲットとするので、”インスタンス”を選択します。

プロトコル : ポートはALB->EC2はHTTPで通信するようにするので、”HTTP”を選択します。
IP アドレスタイプは”IPv6″を選択します。

プロトコルバージョンは”HTTP1″を選択します。
リクエストプロトコルとプロトコルバージョンの対応は、以下の記事などを参考にしてみてください。

ヘルスチェックは、今回は検証用なのでデフォルト設定のままにします。
設定ができたら、”次へ”を選択します。

使用可能なインスタンスのうち、WebサーバーのEC2インスタンスを選択します。
ALB->EC2はHTTPで通信するようにするので選択したインスタンスのポートは80にします。
“保留中として以下を含める”を選択します。

ターゲットを確認でWebサーバーのEC2インスタンスを保留中に含めたら、”ターゲットグループの作成”を選択します。

ALB
ALBを作成します。
ec2で検索して”EC2″を選択します。

“ロードバランサー”を選択します。

“ロードバランサーの作成”を選択します。

ロードバランサーのタイプは”Application Load Balancer”で作成します。

ALBはインターネットからリクエストを受け付けるので、スキームは”インターネット向け”を選択します。
IPアドレスタイプは、IPv4とIPv6のどちらからのリクエストも受けられるように”Dualstack”を選択します。

VPCはipv6用に作成したVPCを選択します。
サブネットはEC2のWebサーバーにアタッチしているものと、仮で他AZに作成したサブネットを選択します。

セキュリティーグループはALB用に作成したセキュリティーグループを選択します。
リスナーはHTTPSのみのルールを設定します。
HTTPSリスナーのデフォルトアクションは、WebサーバーのEC2インスタンスをターゲットに設定したターゲットグループを設定します。
なお、HTTPのリクエストについては後ほどリダイレクト設定を行うので、リスナーの設定はしません。

デフォルト SSL/TLS サーバー証明書についてはACMで設定したものを選択します。

以降はデフォルトの設定のままとします。

設定ができたら、”ロードバランサーの作成”を選択します。

ALBが設定できたところで、HTTP->HTTPSのリダイレクト設定もしておきます。
ec2で検索して”EC2″を選択します。

“ロードバランサー”を選択します。

作成したALBを選択し、てリスナーとルール”の中のリスナーの追加”を選択します。

リスナーの設定でプロトコルは”HTTP”を選択します。

アクションのルーティングは”URLにリダイレクト”を選択します。
URL にリダイレクトは”URI部分”を選択します。
プロトコルは”HTTPS”を選択します。
ステータスコードは”301″を選択します。

設定ができたら、”追加”を選択します。

Route 53
独自ドメインでアクセスできるようにRoute 53の設定をします。
最初にホストゾーンの作成を行いますが、ACMの設定でDNS検証を選択していた場合はすでにホストゾーンは作成できていると思うので、新しく作成せずにそれを使用してください。
route53で検索して”Route 53″を選択します。

“ホストゾーン”を選択します。

“ホストゾーンの作成”を選択します。

ドメイン名は設定する独自ドメインを指定します。
タイプは”パブリックホストゾーン”を選択します。

設定ができたら、”ホストゾーンの作成”を選択します。

ホストゾーンの一覧に戻り、DNSレコードの設定を行います。
作成したホストゾーン名を選択します。

“レコードを作成”を選択します。

IPv4のAレコードとIPv6のAAAAレコードを設定します。
Aレコードの設定をします。
レコード名のサブドメインはなしで設定します。
レコードタイプは”A”を選択します。
エイリアスを選択して、トラフィックのルーティング先は作成したALBを選択します。
ルーティングポリシーは”シンプルルーティング”を選択します。

次にAAAAレコードの設定をします。
レコード名のサブドメインはなしで設定します。
レコードタイプは”AAAA”を選択します。
エイリアスを選択して、トラフィックのルーティング先は作成したALBを選択します。
ルーティングポリシーは”シンプルルーティング”を選択します。
レコードの設定ができたら、”レコードの作成”を選択します。

設定確認
設定ができたら、Webサーバーまで通信ができているか確認してみましょう。
まずはブラウザで確認してみましょう。
ブラウザから独自ドメインのURLを入力して以下のようなページが表示できれば、正しく設定できています。

http://[自身の独自ドメイン]を入力した場合にHTTP->HTTPSにリダイレクトできていることも確認しましょう。
以下のようにHTTPSにリダイレクトできていれば、正しく設定できています。

IPv4/IPv6いずれのリクエストでも受けられることも確認しましょう。
確認はcurlで行います。
curlの–ipv4と–ipv6のオプションを使うことで、ホスト名を解決するときにIPv4あるいはIPv6アドレスのみを使用します。
以下のようにWelcome to nginxのページが返ってきていれば正しく設定できています。
$ curl --ipv4 https://[自身の独自ドメイン]
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
$ curl --ipv6 https://[自身の独自ドメイン]
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
これで設定は完了です、お疲れさまでした。
おわりに
IPv4の枯渇が問題になりIPv6は開発されました。
おそらくIPv4の枯渇は今後さらに加速し、それに伴ってIPv6の普及も加速するのではないでしょうか。
そんな将来に備えて、IPv4からIPv6への移行を進めていった方が良いのではないかと思います。
パブリックIPv4の課金開始を一つのきっかけに、ぜひ皆さんもIPv6への移行を進めてみてください。
最後まで記事を読んでいただいて、ありがとうございました!!
コメント