Table of Contents
目的
今回の目的は独自ドメインを使用してRoute53にドメイン名を登録し、
S3にオリジンコンテンツを配置し、その前段にCloudFrontを配置することで、コンテンツの配信を高速化します。
CloudFrontディストリビューションを作成すると、http://d111111abcdef8.cloudfront.net
などのドメイン名をディストリビューションに割り当てますが、このドメインを代替ドメイン名 (CNAME)を追加して、独自ドメインを使用できるようにします。
また、URLをHTTPS化するために、AWS Certificate Manager (ACM)を使用し、セキュアに通信を行うための設定も行います。
構成図は以下です。

Route53とは
ひとことで言えばDNSサービスです。
- ドメイン登録
- DNSルーティング
- ヘルスチェック
上記3つの機能を組み合わせて実行する必要があります。
Route53のDNSサービスによりドメイン名とIPアドレスを紐づけることができます。
利用者からの要求に応じてドメイン名に対応するIPアドレスを探し出します。
これを「名前解決」と言います。
個々からはRoute53を使用していくにあたり、DNSの名前解決の仕組みを深堀していきたいと思います。
DNSにおける階層化と委任の仕組みについて
DNSではドメイン名に対応する形で管理範囲を階層化し、委任することで管理を分散します。
委任によって管理を任された範囲を「ゾーン」と呼びます。
DNSでは委任元 (親)と委任先 (子)の関係が仕組みとして存在します。
サブドメインを親が作成することで、そのサブドメインの管理を子に委任します。
下図の例で言うと、親となるルートがjp
のサブドメインを作成することで、jp
の管理を子に委任します。
管理をするためにはネームサーバで情報を管理します。
ネームサーバで管理している情報とは、ドメイン名とIPアドレスの対応付けを管理しています。
exxample.jp
の情報についてはjpの子に当たる、example.jp
が管理しているため、jp
の委任先であるexample.jp
を案内する。
最終的に、example.jp
のIPアドレスを管理するネームサーバーにたどり着き、example.jp = 192.168.1.1 というIPアドレスを管理しているネームサーバーからIPアドレスを返却されることで、名前解決する、というのが大枠の概要になります。

リゾルバー (Resolver)の役割
スタブリゾルバーの役割
名前解決をする際に、クライアント端末のWebブラウザなどから呼び出され、名前解決の依頼をする役割を担っています。
スタブリゾルバー自身は名前解決を行わず、フルサービスリゾルバーに名前解決を依頼します。

フルサービスリゾルバーの役割
DNSにおいて名前解決を行う役割を担っています。
スタブリゾルバーからの名前解決要求を受けて、フルサービスリゾルバーは名前解決を行います。
また、フルサービスリゾルバーは「キャッシュ」の機能も備えており、ネームサーバーに問い合わせて名前解決したIPアドレスの情報を一時的に保管しておく機能があります。
一時的に情報を保管しておくことで、名前解決をするのに改めてネームサーバーへ問い合わせることなく、フルサービスリゾルバーが名前解決をすることができるため、名前解決の時間軽減にもつながります。


では、このスタブリゾルバーとフルサービスリゾルバーをまとめると次の図のようになります。
フルサービスリゾルバは1回目のスタブリゾルバーからの要求については、各ネームサーバへの問い合わせを行いますが、2回目の要求については情報をキャッシュしているため、スタブリゾルバーからの要求に対しては、ネームサーバへの問い合わせをせずともフルサービスリゾルバーからIPアドレスを返却することができます。

Route53 名前解決
ではここまででDNSの名前解決の仕組みが理解できたかと思います。
以下の図はAWS公式ドキュメントから拝借した図ですが、Route53で名前解決をする仕組みを表しています。
DNS resolverはフルサービスリゾルバーの役割を表しているのがわかりますね。
- End userはスタブリゾルバーを呼び出します
- スタブリゾルバーは
www.example.com
の名前解決要求をフルサービスリゾルバーへ名前解決を依頼します - フルサービスリゾルバーはルートのネームサーバに
www.example.com
のIPアドレスを確認します.com
については.com
のネームサーバ に管理を委任をしています、と返却されます - フルサービスリゾルバーは
.com
ネームサーバにwww.example.com
のIPアドレスを確認します.example.com
についてはRoute53 ネームサーバで管理を委任しています、と返却されます。 - フルサービスリゾルバーはRoute53 ネームサーバに
www.example.com
のIPアドレスを確認します - Route53は
www.example.com
のIPアドレスは192.0.2.44
です、と返却されます - IPアドレスがわかったフルサービスリゾルバーはEnd userのWebブラウザにIPアドレスを返却します
- IPアドレスがわかったWebブラウザは目的のWeb Severにたいして取得したIPアドレスでRequestすることで、WebページをWebブラウザに表示することができます

Route53 handson
取得したドメインをRoute53のネームサーバに管理設定
Route53の画面を表示しホストゾーンの作成をクリックします。

ホストゾーンの作成画面にてRoute53で管理したいドメイン名を指定します。
ドメインについては様々なサイトで取得することが可能です。
僕はバリュードメインというサイトで.info
のドメインを取得しましたので、この記事ではこちらのドメインを使用していこうと思います。
バリュードメインでのドメイン取得の方法については以下を参照してください。
ホストゾーンの作成画面にて取得したドメイン名を入力し、ホストゾーンの作成をします。

AWS CLIを使用してホストゾーンを作成する場合
AWS CLI Command Reference
aws route53 create-hosted-zone \
--name <example.com> \
--caller-reference `date +"%Y-%m-%d-%H-%M-%S"`
# --name -> ドメイン名を入力します
# --caller-reference -> 作成した日付を指定することで一意の文字列とすることができます
作成が完了し、以下のように表示されればホストゾーンの作成は成功です。
{
"Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/xxxxxxxxxxxxxx",
"HostedZone": {
"Id": "/hostedzone/xxxxxxxxxxxxxx",
"Name": "awsinfracloud.info.",
"CallerReference": "2023-07-08-07-24-05",
"Config": {
:...skipping...
{
"Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/xxxxxxxxxxxxxx",
"HostedZone": {
"Id": "/hostedzone/xxxxxxxxxxxxxx",
"Name": "awsinfracloud.info.",
"CallerReference": "2023-07-08-07-24-05",
"Config": {
"PrivateZone": false
},
"ResourceRecordSetCount": 2
},
"ChangeInfo": {
"Id": "/change/C02396572N4Z773POWG2X",
"Status": "PENDING",
"SubmittedAt": "2023-07-07T22:24:07.606000+00:00"
},
"DelegationSet": {
"NameServers": [
"ns-xxx.awsdns-49.com",
"ns-xxxx.awsdns-11.org",
"ns-xxx.awsdns-04.net",
"ns-xxxx.awsdns-59.co.uk"
]
}
}
ホストゾーンの作成をすると、関連付けされたNSレコード (ネームサーバ)およびSOAレコードが表示されます。
このNSレコードを取得したドメイン先サイトにて登録します。
名前解決をRoute53で行いたいため、この作業が必要になります。

バリュードメインの管理画面にてネームサーバの変更を行う
本記事ではバリュードメインにてドメイン取得を行ったため、バリュードメインでのネームサーバの変更を行います。
別のサイトからドメインを取得した場合でも、やり方は応用できるかと思いますので、参考にしてください。
バリュードメインへログインします。
コントロールパネル画面からドメイン -> ドメインの設定 (登録済みドメイン一覧)を選択します。

ネームサーバーをクリックします。

ネームサーバの変更画面が表示されるので、先ほど作成したNSレコードを登録します。
AWS CLIコマンドで実行した場合には以下で表示されている箇所をコピペします。
"DelegationSet": {
"NameServers": [
"ns-xxx.awsdns-49.com",
"ns-xxxx.awsdns-11.org",
"ns-xxx.awsdns-04.net",
"ns-xxxx.awsdns-59.co.uk"

入力後、保存することで以下の画面が表示されます。

ドメインのネームサーバがRoute53へ反映確認
確認方法は nslookup
コマンドを使用します。
以下のようにNon-authoritative answer:
の下にRoute53のNSレコードが表示されていればOKです。
※ネームサーバ登録後に反映されるまでに少し時間がかかる場合があるので、変更されるまでは気長に待ちましょう。
$ nslookup -type=NS <対象ドメイン>
Server: 172.27.192.1
Address: 172.27.192.1#53
Non-authoritative answer:
<対象ドメイン> nameserver = ns-xxxx.awsdns-59.co.uk.
<対象ドメイン> nameserver = ns-xxx.awsdns-49.com.
<対象ドメイン> nameserver = ns-xxx.awsdns-04.net.
<対象ドメイン> nameserver = ns-xxxx.awsdns-11.org.
Authoritative answers can be found from:
CloudFrontとは
CloudFrontについては以前書いた記事がありますので、そちらをご参照ください。
また、上記記事を参考にCloudFormation (OAC) + S3の静的ウェブサイトホスティングでサイトを表示します。
AWS Certificate Manager (ACM)とは
SSL/TLS 証明書を発行し、ELBやCloudFront、Amazon API GatewayなどのACMと統合されたサービスへ証明書を適用するサービスです。
ACMでSSL/TLS証明書発行をリクエストし、上記のAWSリソースに配布します。
この証明書を発行し、CloudFrontに適用させることで、インターネットからCloudFrontまでのトラフィックをHTTPS通信にすることが可能です。
HTTP通信とHTTPS通信の違いは例えると年賀状のような手紙と封筒に入ったレターの違いです。

HTTPS通信はHTTPによるによる通信をSSL/TLSで暗号化します
HTTPSは正式にはHyper Text Transfer Protcol Secure
の略です。
SSL/TLS 証明書はWebサイトの運営者の実在性を確認し、クライアント⇔サーバ間で通信データの暗号化を行うための電子証明書で、認証局から発行されます。
SSL/TLS 証明書にはWebサイトの所有者の情報や、暗号化通信に必要な鍵、発行者の署名データが含まれています。
この証明をすることで”実在するサイト運営者によって運営されている本物のWebサイト”であることが、認証局によって認証され、ユーザーは安心してこのWebサイトは安心であると確認することができます。
AWS Certificate Manager (ACM) handson
AWS Certificate Manager (ACM)の画面へ移動し、ACMでパブリック証明書をリクエストします。
完全修飾ドメイン名に以下のように二つのドメイン名を入力します。

*.awsinfracloud.info
とワイルドカード指定しているのは、サブドメインを使用する可能性がある場合に対応するためにワイルドカード指定しています。
こうすることで、例えばhttps://krieee.awsinfracloud.info
などとサブドメイン (kyrieee)を付与したとしたも、対応できるようにしています。
注意点
AWS公式
www.example.com
のような完全修飾ドメイン名 (FQDN) やexample.com
のようなネイキッドドメインあるいは apex ドメイン名を使用できます。
また、同じドメインで複数のサイト名を保護するために、最左位置にアスタリスク (*
) をワイルドカードとして使用できます。
たとえば、*.example.com
は、corp.example.com
とimages.example.com
を保護します。
ワイルドカード名は、ACM 証明書の [件名] フィールドと [サブジェクト代替名] 拡張子に表示されます。
ワイルドカード証明書をリクエストする場合、アスタリスク (*
) はドメイン名の左側に付ける必要があり、1 つのサブドメインレベルのみを保護できます。
たとえば、*.example.com
はlogin.example.com
およびtest.example.com
を保護できますが、test.login.example.com
を保護することはできません。
また、*.example.com
は、example.com
のサブドメインのみを保護し、ネイキッドドメインまたは apex ドメイン (example.com
) は保護しないことに注意してください。
両方を保護するには、次のステップを参照してください。
https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-request-public.html
AWS公式にも記載がある通り、*.example.com
は、example.com
のサブドメインのみを保護し、
つまり、test.example.com
などは保護するが、example.com
については保護しませんよ、と言っていますので、
パブリック証明書をリクエストする際、完全修飾ドメイン名はawsinfracloud.info
と *.awsinfracloud.info
の二つを指定しています。
検証方法は「DNS 検証 – 推奨」を選択し、リクエストします。

DNS 検証 – 推奨については以下のようにAWS公式で説明されています。
ドメインネームシステム (DNS) は、ネットワークに接続されているリソースのディレクトリサービスです。DNS プロバイダーは、ドメインを定義するレコードを含むデータベースを維持します。DNS 検証を選択すると、このデータベースに追加する必要がある 1 つ以上の CNAME レコードが ACM から提供されます。これらのレコードには、ドメインを制御する証拠となる一意のキーと値のペアが含まれています。 例えば、追加の名前として example.com を使用して www.example.com ドメインの証明書をリクエストする場合、ACM によって 2 つの CNAME レコードが作成されます。各レコードは、ユーザーのドメインおよびアカウントに固有のものとして作成され、名前と値が含まれます。この値は、証明書を自動更新するために ACM が使用する AWS ドメインを指すエイリアスです。CNAME レコードを DNS データベースに追加できるのは 1 回のみです。証明書は使用中で CNAME レコードが残っている状態であれば、証明書は ACM によって自動的に更新されます。
https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/dns-validation.html
CNAMEレコードとは
CloudFrontのようなCDNを使用する場合、CNAME (Canonical Name) = 正式な名前 を使用して、別名として割り当てる手段として使用されます。
今回、独自ドメインをawsinfracloud.info
としていますが、CloudFrontを経由してオリジンへアクセスする際に、Route53が名前解決する際、CloudFrontのドメインについても把握しておく必要があります。
CloudFrontのドメインをCNAMEレコードで別名として関連付けることで、フルサービスリゾルバーは問い合わせたドメイン名にCNAMEレコードが設定されていることがわかると、その別名に対して名前解決を実行します。
リクエストするとステータスが「保留中の検証」の状態になります。

AWS CLIでACMを発行する場合
以下コマンドで証明書を発行します。
aws acm request-certificate \
--domain-name <domainname> \
--validation-method DNS \
--region us-east-1
# domain-name -> 対象のドメイン名を記載します。
# validation-method -> ドメインの所有権を確認するための方法を指定します。
# region -> リージョンを指定します。
region
の指定について
ACMで取得した証明書は作成したAWSリージョンに関連付けられます。 CloudFrontでACM証明書を使用するには、米国東部 (バージニア北部)
リージョンの証明書をリクエストしている必要があります。
と、AWS公式にも説明されているため、リージョンはus-east-1
を指定します。
以下のように表示されていれば証明書発行は成功しています。
{
"CertificateArn": "arn:aws:acm:us-east-1:xxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
}
Route53でレコードを作成をクリックします。

レコードを作成します。

Route53のドメインページにCNAMEレコードが追加されていることが確認できます。

ACMの画面においても証明書のステータスが「発行済み」に変更になるかと思います。

CloudFrontにACMで取得したSSL/TLS証明書を統合
CloudFrontの画面へ移動し、設定を編集します。

代替えドメイン名 (CNAME) – オプションに独自ドメインを入力します → 独自ドメインとCloudFrontのドメインをCNAMEレコードとして関連付けを行っています。
この関連付けを行うことで、先に申し上げたフルサービスリゾルバーは、問い合わせたドメイン名にCNAMEレコードが設定されていることがわかると、その別名に対して名前解決を実行をするので、この設定が必要となります。
カスタム SSL証明書 – オプションの選択で、ACMで取得した証明書を選択します。

これで変更を保存します。
ここまでの設定で、CloudFrontに対してHTTPSで通信ができること、独自ドメインとCloudFrontのドメインをCNAMEレコード (別名)の関連付けを行うことができました。
CloudFrontのディストリビューション名でアクセスすると、鍵マークがついていることと、鍵マークをクリックして、この接続は保護されています -> 証明書は有効ですをクリックすると、証明書の発行元がAmazonであることがわかります。


Route53のルーティング先をCloudFrontディストリビューションにするための設定をします。
Route53の画面からレコードを作成をクリックします。

クイック作成へ切り替えるをクリックします。

レコードタイプ: Aレコードを選択
エイリアス: ラジオボタンON
トラフィックのルーティング先: CloudFrontディストリビューションのエイリアス、CloudFrontのURLをhttps://
はなしで入力

これでレコードを作成します。
S3へindex.html
がアップロードされている前提でお話しますが、
この状態でCloudFrontドメインへアクセスするとエラーが出るようになりました。

次に独自ドメイン名でアクセスするとHTTPS
でアクセスできることが確認できました。

まとめ
CloudFront + Route53 + ACMを使用して独自ドメインでS3に配置したindex.htmlを表示するまでを実践してみましたが、ACMのSSl/TLS証明書の部分の理解がまだまだ浅いと感じておりますので、そもそものSSL/TLS証明書の概念を深堀りする必要があるなと感じました。
また、この構成を一つ一つ実施していくのは大変なので、CloudFormationでのIac化についても実施していこうと思います。
参考書籍:
DNSがよくわかる教科書
Amazonで株式会社日本レジストリサービス(JPRS) 渡邉結衣、佐藤新太、藤原和典, 森下泰宏のDNSがよくわかる教科書。アマゾンならポイント還元本が多数。株式会社日本レジストリサービス(JPRS) 渡邉結衣、佐藤新太、藤原和典, 森下泰宏作品ほか、お急ぎ便対象商品は当日お届けも可能。またDNSがよくわかる教科書もアマゾン配送商品なら通常配送無料。