AWSにおけるドメインリダイレクト手法について整理してみた

![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/c67df94d-358f-dcba-9316-e0bda32f1224.png)

:::note info
本サイトの「ドメイン」は「Zone Apex」を意味します。
ホスト名を含むFQDNではないためご注意ください。
:::

# 概要
ドメインリダイレクトの仕組みをAWSサービスで実装する機会があり、そもそもAWSサービスでドメインリダイレクトを実装するときの手法って何があるか調べたので備忘録としてまとめておきます。

# ドメインリダイレクトとは
ユーザーからブラウザで、あるドメイン(例. oldsite.com)にアクセスした際、別のドメイン(例. newsite.com)へリクエストを自動転送する仕組みです。
イメージはこんな感じです。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/875bcfce-e10a-83bb-b03c-ddc7b0b07ed3.png)

最終的には、ユーザーから見ると初めにアクセスしたドメインとは異なるドメインのURLへアクセスすることになります。「サーバー移行して既存のドメインを変更したけど、ユーザーからは既存のドメインでアクセスさせたい」などの要望がある場合に利用を検討するかと思います。


# CNAMEとの違い
以下のサイトが非常にイメージが湧く内容だったので載せさせていただきます:bow_tone1:
結論、同一ドメインにおけるホストの別名を定義するためのレコードであり、別ドメインへのリダイレクトはできません。

https://regardie.dev/post-4054

https://stilltalkintv.com/post-3657/


# AWSにおける実現方法
### S3 静的ウェブサイトホスティングのリダイレクト機能
S3の機能の一つである、**静的ウェブサイトホスティング**(S3に配置した静的ファイルをWEBサイトとして公開する機能)のオプションとして用意されている**リダイレクト機能**を使用する方法です。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/b4c2f657-238c-1b78-a424-d56568e985f2.png)

バケットのプロパティタブの設定にある「静的ウェブサイトホスティング」を有効化することで発行される、AWSリージョン固有の**ウェブサイトエンドポイントへのリクエストに対してのみ**、別のバケットもしくはドメインにリダイレクトすることができます。
```bash
# ウェブサイトエンドポイント形式(リージョンにより形式が異なる)
http://bucket-name.s3-website-Region.amazonaws.com
# or
http://bucket-name.s3-website.Region.amazonaws.com
```
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/97cce9f0-07e0-4002-ab55-3260c17d005f.png)

#### リダイレクト設定は大きく3つ
##### バケット全体(ウェブサイトエンドポイント)に対する設定
ウェブサイトエンドポイントへの全てのリクエストがリダイレクトされる設定です。URLにどんなPathが含まれていても、リダイレクト先として設定したホスト名にリダイレクトされます。
ホスティングタイプは「オブジェクトのリクエストをリダイレクトする」になります。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/82726fb5-0308-4310-872f-82c5344bca8c.png)

##### リクエスト条件に応じた設定(リダイレクトルール)
Json形式のリダイレクトルールにマッチするリクエストがウェブサイトエンドポイントにされた時、リダイレクト先として設定したホスト名にリダイレクトされます。
ルールとしては、「URLのPath(オブジェクトキー)」「URLのPath(Prefix)」「ウェブサイトエンドポイントへのリクエストに対するレスポンスコード」があります。
リダイレクトルールに一致しないリクエストは、通常のウェブサイトエンドポイントへのリクエストとして処理されます。
ホスティングタイプは「静的ウェブサイトをホストする」になります。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/ff32a803-db53-495b-982d-0d1f37f63446.png)

##### 個々のオブジェクトに対する設定(オブジェクトメタデータ)
オブジェクトごとにリダイレクトを設定する方式です。ホスティングタイプは「静的ウェブサイトをホストする」になります。
オブジェクトに対してユーザー定義タイプのメタデータを付与することで、設定した値のホスト名にリダイレクトされます。オブジェクトを含めたリクエストがウェブサイトエンドポイントにされた時、リダイレクト先として設定したホスト名にリダイレクトされます。
```bash
# キー: 値
x-amz-website-redirect-location: https://www.example.com
```

メタデータは、オブジェクトアップロード時のオプションで付与できます。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/5db99abe-73a8-4dae-acd0-a0ec75308be9.png)

既存のオブジェクトに対しても付与は可能ですが、5GB未満の場合はコピーアクションを使用して付与することが可能です。詳細は公式ドキュメントを参照してみてください。

#### 難点：ウェブサイトエンドポイントへのリクエストはHTTPのみサポート
ドキュメントに記載がある通り、**ウェブサイトエンドポイントへのリクエストはHTTPのみサポート**されており、HTTPSでのリクエストができません。つまり、ユーザーからウェブサイトエンドポイント間の通信はHTTPとなり、盗聴のリスクがあります。
そのため後述しますが、**ユーザーのリクエストをHTTPS化**する場合は、ユーザーとウェブサイトエンドポイントの間に**Amazon CloudFront**(後述)もしくは**Amazon API Gateway**(省略)を挟む必要があります。
>Amazon S3 ウェブサイトエンドポイントは HTTPS またはアクセスポイントをサポートしていません。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteEndpoints.html

### CloudFront + S3 静的ウェブサイトホスティングのリダイレクト機能
S3静的ウェブサイトホスティングのリダイレクト機能を使用しつつ、ユーザーからのリクエストをHTTPS化する際の構成です。CloudFrontのCustom Originにウェブサイトエンドポイントを指定します。
CloudFrontにてリダイレクトの設定をするわけではなく、SSL終端した通信をウェブサイトエンドポイントに転送するのみです。
![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/2d74d2c3-5b5f-4010-a27f-38f0c3789e5b.png)

#### 難点：Origin Access Identity(OAI)/Origin Access Control(OAC)が使えないのでバケットポリシーでCloudFront経由のアクセスだけに絞れない
OAI/OACについての詳細は割愛しますが、**ウェブサイトエンドポイントに対するOAI/OACは設定できません。**
**OAI/OACが設定できるのはREST APIエンドポイントのみです。**

:::note info
REST APIエンドポイントとは、バケット固有で存在するHTTPSアクセス時に使用するURLのことです。
![画像6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/5b4105c6-1548-48c2-8ad9-37d993c57a32.png)
:::

:::note warn
バケットポリシーの`Principal`や`Condition`でのCloudFront経由のみのアクセスに制御することは現状厳しい。
少しでもセキュリティ強度を上げる方法としては、CloudFrontでカスタムヘッダーを付与しバケットポリシーの`Condition`で制御することくらいですが完全ではありません。
:::

### Amazon CloudFront Edge Computing
CloudFrontはキャッシュを使った静的・動的コンテンツの高速配信を可能にするサービスです。
キャッシュを保持する場所は、エッジロケーションに加えリージョン別エッジキャッシュでも保持する多段構成となっています。
後述する2つの機能は、適用できる場所が異なります。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/2c3b6383-13f8-4173-9193-e2ad14b141d0.png)

#### CloudFront Functions
CloudFront Functionsは、エッジロケーションにおけるビューワーリクエスト及びビューワーレスポンスに対して処理を実行します。実行可能時間が1ミリ秒未満という制約はありますが、リダイレクトさせるだけの軽量な処理であれば問題はないと思います。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/2f52b68f-152e-4771-bb86-cdd9a39efb87.png)

#### CloudFront + Lambda@Edge
Lamda@Edgeは、リージョン別エッジキャッシュにおけるビューワー及びオリジンのリクエスト/レスポンスに対して処理を実行します。CloudFront Functionsでは処理しきれないような高度な処理が必要な場合に利用を検討するかと思います。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/81c2a40e-59fd-4c1f-91b9-f496775c6016.png)


### Application Load Balancing
ALBのリスナーに紐づけるリスナールールでリダイレクト設定する方法です。
設定詳細は割愛しますが、リクエストのPathに対してや、全てのリクエストに対してリダイレクトの設定をすることが可能です。
![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/dbe446a0-b6df-47a5-9992-3052ed72a58b.png)

# まとめ
今回はAWSにおけるドメインリダイレクト手法について簡潔ではありますが整理してみました！
ちょっとボリューミーではありますが、少しでも誰かの役に立てば幸いです。

# 参考文献
### リファレンス
* [AWS re:Post - Route 53 でドメインを別のドメインにリダイレクトする方法を教えてください。-](https://repost.aws/ja/knowledge-center/route-53-redirect-to-another-domain)
* [Amazon Simple Storage Service (S3) ユーザーガイド - ウェブサイトエンドポイント -](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteEndpoints.html)
* [Amazon Simple Storage Service (S3) ユーザーガイド - (オプション) ウェブページリダイレクトの設定 -](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/how-to-page-redirect.html)
* [Amazon Simple Storage Service (S3) ユーザーガイド - オブジェクトメタデータの使用 -](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html)
* [Amazon Simple Storage Service (S3) ユーザーガイド - Amazon S3 コンソールでのオブジェクトメタデータの編集 -](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/add-object-metadata.html)
* [Amazon CloudFront](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2024_AmazonCloudFront-EdgeComputing_0630_v1.pdf)
* [Amazon CloudFront 開発者ガイド - 関数を使用してエッジでカスタマイズする -](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/edge-functions.html)
* [Elastic Load Balancing アプリケーションロードバランサー - Application Load Balancer のリスナー -](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-listeners.html)

### ブログ
* [Regardie's Salesforce Blog -ドメイン移管時のリダイレクト設定まとめ-](https://regardie.dev/post-4054)
* [レンタルサーバー 賢者の選択 -CNAMEレコードはどんな時に使う？別サーバーにリダイレクトできる？-](https://stilltalkintv.com/post-3657/)
* [S3のリダイレクト機能を改めて整理してみた](https://dev.classmethod.jp/articles/s3-static-website-hosting-redirect-configuring/#toc-)
* [[再検証] Amazon CloudFront のカスタムオリジンとして Amazon S3 のウェブサイトエンドポイントを指定した場合のアクセス制御について検証してみた](https://dev.classmethod.jp/articles/re-amazon-cloudfront-custom-origin-access-control-verification-with-amazon-s3-website-endpoint/)
* [CloudFrontとS3で作成する静的サイト構成の私的まとめ](https://dev.classmethod.jp/articles/s3-cloudfront-static-site-design-patterns-2022/)