1つのCloudFront ALB EC2で複数のホスト(サイト)を扱いたい
 hiren
hiren実現したい構成例

 hiren
hiren複数の CloudFront Distribution ー 複数の ALB ー 複数の EC2 で構成する方がシンプルで良いが、費用面などの要因から全てのサービスを単一リソースで作成しなければいけない場合、可能なのか?
 hiren
hiren#検証
環境
$ ec2-metadata --ami-id
ami-id: ami-090d95e264aea197c
$ cat /etc/system-release
Amazon Linux release 2023.5.20241001 (Amazon Linux)
$ uname -a
example.ap-northeast-1.compute.internal 6.1.109-118.189.amzn2023.aarch64 #1 SMP Tue Sep 10 08:58:40 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux
CloudFront ⇒ ALB ⇒ EC2 間の Security Group 設定は適切に行われている前提
ドメインのレコード設定や、ACMの証明書取得も一部割愛します
 hiren
hiren今回は一旦 Web サーバーを Apache にする。
以下など参考にインストール
$ httpd -v
Server version: Apache/2.4.62 (Amazon Linux)
Server built:   Jul 23 2024 00:00:00
 hiren
hiren複数ドメインのサイトを扱えるように、httpd に VirtualHost の設定を追記する
<VirtualHost *:80>
  ServerName hoge.example.com
  ServerAlias example.com *.example.com # CloudFront ⇒ ALB 間で Host ヘッダーを転送する場合は不要
  DocumentRoot /var/www/hoge
</VirtualHost>
<VirtualHost *:80>
  ServerName huga.example.org
  ServerAlias example.org *.example.org # CloudFront ⇒ ALB 間で Host ヘッダーを転送する場合は不要
  DocumentRoot /var/www/huga
</VirtualHost>
 hiren
hirenアクセスログにアクセス元ホスト名が出力されるようデフォルト設定に追記修正
<IfModule log_config_module>
-    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" combined
</IfModule>
 hiren
hirenバーチャルホストの各ホストにページを作成
# mkdir /var/www/hoge
# mkdir /var/www/huga
# echo "hoge.example.com" > /var/www/hoge/index.html
# echo "huga.example.org" > /var/www/huga/index.html
 hiren
hiren設定に問題が無い事を確認して再起動(or 停止してたら起動)
# apachectl configtest
Syntax OK
systemctl restart httpd
 hiren
hirennginxならこれ参考に設定すれば良さそう
 hiren
hirenALB の Host ヘッダー保持設定を設定する
ロードバランサー>属性>パケット処理>ホストヘッダーを保持 を オン に設定

 hiren
hirenALB の HTTPS リスナーの証明書リストに複数ドメイン分の ACM 証明書を追加する
ロードバランサー>リスナーとルール>対象のHTTPSリスナー>SNI の SSL 証明書を追加する

対象の証明書を全て選択して「保留中として以下を含める」ボタンをクリック

「保留中の証明書を追加」ボタンをクリック

 hiren
hiren複数のドメイン名を別の名前として持つ証明書をバージニア北部リージョンの ACM で1つだけ作成する
キーアルゴリズムは CloudFront でも使える RSA 2048 か  ECDSA P 256 を指定

 hiren
hirenCloudFront のディストリビューションに複数ドメイン分の 代替ドメイン名(CNAMEs) と前項で作成した カスタム SSL 証明書 を設定

 hiren
hirenオリジンドメイン(カスタムドメインで)ALBに繋がるオリジンを作る
オリジングループを作る(用途外だけど)⇒不要だったけど分からなくなるからあった方がいいかも?
ビヘイビアのオリジンリクエストポリシーにALLViewerを設定する(Hostヘッダーを転送するポリシーであれば何でも良い)
 hiren
hiren無限ループしてしまうため CloudFront に向けている DNS レコードとは別のレコード名で ALB の DNS 名 への DNS レコードを作成する
設定例
| レコード名 | タイプ | 値 | 
|---|---|---|
| hoge.example.com | A(Alias)or CNAME | d1abcdefg2hijk.cloudfront.net | 
| alb.examole.com | A(Alias)or CNAME | example-1234567890.ap-northeast-1.elb.amazonaws.com | 
オリジンドメインに、 ALB に繋がるカスタムドメインを指定して、オリジンを作成する

オリジンタイプを Custom origin ではなく Elastic Load Balancing になるように ALB を直接指定してしまうと、HTTP 502 ERROR が返されアクセスが失敗してしまいます。
ALB デフォルトの DNS 名 には証明書が紐づいていないためです。
CloudFront ⇒ ALB 間のリスナープロトコルに HTTP を含む場合は問題無いが、 HTTPS のみの場合に発生します。
参考:CloudFrontとALB間のHTTPS接続がうまくいかなかった件
 hiren
hirenパスパターンが デフォルト (*) のビヘイビアのオリジンに、前項で作成したオリジンを指定し、オリジンリクエストポリシーに ALLViewer を設定する(恐らく Host ヘッダーを転送するポリシーであれば何でも良い筈)

Host ヘッダーを転送するオリジンリクエストポリシーを指定しない場合、Host ヘッダーがオリジンに指定したドメイン名に置き換えられてリクエストが転送される。
例)hoge.example.com ⇒ alb.examole.com
そのため、バーチャルホストの設定をクライアントのリクエスト時ドメイン名のみで指定している場合、マッチしなくなる。
 hiren
hiren通信的には必要無いが、構成上オリジンが一つで何故複数ドメインのリクエストが処理できるのか分かり辛いので、もう一つ分までであれば※オリジンを作成して、2つのオリジンを追加したオリジングループを作成し、デフォルトビヘイビアのオリジンをオリジングループに変更することは可能
※オリジングループに追加できるオリジンは2つまでのため
オリジングループの用途はフェイルオーバーのため、用途外利用にはなるが、動作は変わらない
 hiren
hiren1つの CloudFront ALB EC2 で複数のホスト(サイト)を扱うことができた!


10.0.1.30 - - [25/Nov/2024:08:40:02 +0000] "GET / HTTP/1.1" 200 17 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" "hoge.example.com"
10.0.0.28 - - [25/Nov/2024:08:40:04 +0000] "GET / HTTP/1.1" 200 17 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" "huga.example.org"
 hiren
hirenCloudFront ⇒ ALB を HTTPS にしてるところが難易度を一段階上げてたと思う
 hiren
hiren参考