クロスドメイン環境でALBの固定レスポンスを利用する場合はAccess-Control-Allow-Originヘッダを忘れないようにしよう
初めに
ALB(Application Load Balancer)を普段から利用されている方はご存知の方も多いかと思いますが、ALBでは固定メッセージを返す機能があり、これを利用することで簡単なものであれば条件に応じてターゲットに転送せずALB側で通信を止め応答することが可能です。
アプリの仕様的にデプロイ時に一時的にエラーレスポンスが返ってしまう場合、セキュリティ的に特定のHTTPヘッダがついた場合のみアクセスさせたい(可能な限りターゲット通信自体を流したくない)等何らかの事情でターゲットに通信をさせたくない時に有用な設定となります。
一方で現時点の仕様だと設定できるものが「Content-Type(ヘッダ)」「メッセージボディ」「ステータスコード」くらいなので仕様的にもうちょっと色々つけたいなぁと思うと機能不足となるところです。
直近それ関係でSPAでフロント・バックエンドを別ALB(別ドメイン)の環境で固定レスポンスを利用したところAccess-Control-Allow-Origin
ヘッダがないのでメンテナンスレスポンスが使えない...というのがあったので備忘録として対応を残しておきます。
一部のヘッダはALB側で付与可能
現在ではALBで一部のヘッダは付与することが可能となっており、Access-Control-Allow-Origin
もこちらに含まれます。
昔からありそうな機能に見えて追加されたタイミングはは2024年11月と比較的最近となります(半年前を最近と呼ぶかは諸説ありますが...)。
こちらの設定はターゲットからのレスポンスのヘッダのみではなく固定レスポンスを含めた設定された「リスナー」を通る通信全てに適用されるため前述のような「固定レスポンス」のケースでも適用可能です。
リダイレクトは...ケースバイケースでしょうか?
レスポンスのヘッダーは上書きされる
先に記載したドキュメントに記載がある通り扱いとしてはHTTPヘッダの変更となります。
そのため以下のようにApache側でAccess-Control-Allow-Origin: example.com
を返すように設定しておき、
$ curl localhost -I
HTTP/1.1 200 OK
Date: Mon, 30 Jun 2025 05:06:57 GMT
Server: Apache/2.4.62 (Amazon Linux)
Access-Control-Allow-Origin: http://example.com
Last-Modified: Mon, 30 Jun 2025 04:58:19 GMT
ETag: "29-638c2e0646eca"
Accept-Ranges: bytes
Content-Length: 41
Content-Type: text/html; charset=UTF-8
このApacheに対してALBが通信するようにターゲットを設定、そしてAccess-Control-Allow-Origin: alb.example.com
を設定するとこのヘッダはALB側で上書きされます。
$ curl -I internal-cors-test-xxxxx.ap-northeast-1.elb.amazonaws.com
HTTP/1.1 200 OK
Date: Mon, 30 Jun 2025 05:09:33 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 41
Connection: keep-alive
Server: Apache/2.4.62 (Amazon Linux)
Last-Modified: Mon, 30 Jun 2025 04:58:19 GMT
ETag: "29-638c2e0646eca"
Accept-Ranges: bytes
Access-Control-Allow-Origin: http://alb.example.com
インフラ・アプリで管轄が分かれておりアプリ側のフレームワーク等の機能でここを制御している場合に、アプリ側で設定変更したのに適用されていない???ということはあるのかなと思いますのでここは注意しましょう。
※ マネジメントコンソールの設定画面上も明記されています
設定はリスナー単位
そしてこの設定はリスナー単位で行われるという点には注意する必要があります。
これで問題になる例としては複数システムで共通のALBを使い、パスやホストヘッダを見てターゲットを変える等1リスナーで複数のシステムを取り扱っている場合です。
例えば以下のようにパスごとにターゲットを振り分けそれごとにAccess-Control-Allow-Origin
ヘッダが異なる場合、リスナー側で一括で書き換えてしまうのでターゲットの値によらず常に同じ値が返って来るためこれを採用することができません。
また、これに限らず同一インスタンス内でも特定のパスだけAccess-Control-Allow-Origin
が異なるなどのケースもこれと同じことが発生しますので注意しましょう。
複数リスナーを用意してそれ毎にシステムを用意すればALBを一つにまとめつつヘッダの上書きを分離することは可能です。
フロントのシステムから呼び出すようであれば一般利用者からすればそこまで目につかないかもしれませんがあまり綺麗ではないと思うのでユースケース次第ではありそうです。
ALB以外で対応することも検討しよう
上記はあくまでALBで対応する場合となります。
後半記載したようにヘッダをパス毎に仕様に合わせて調整しようとするのは本来すべきではないので、求めるものに応じて別の手も検討しましょう。
以下はいくつかの例です。
CloudFrontのレスポンスヘッダポリシーを利用する
CloudFrontではレスポンスヘッダポリシーで任意のカスタムヘッダを追加することができます。
この設定はパスパターン単位で設定できますので先ほどのようにパス毎にヘッダを変えたいパターンでも対応することが可能です。
ただしCloudFrontが導入されていることが前提となり、ない場合はそもそもCloudFront導入をしなければならず、またアクセスを内部ネットワークに限定しているようなプライベートなシステムだと利用できないためその点は注意しましょう。
メンテナンス処理用の処理場所を用意する
いわゆるメンテナンス画面用途であれば別にターゲットを用意してしまうのが既存への影響も少なく自由度は高いところとなります。
EC2でApache/NginxといったWebサーバを用意するのも選択肢ですが、アクセス量が極端に多くなければLambda関数を利用することで必要な時にだけ立ち上がり処理するので比較的安価で利用できます。
とは言いつつもFaaSとはいえ本来のシステムとは別にアプリ・インフラ管理は多少なりとも発生するのである程度組み込んだ処理が欲しいのであれば選択肢な一方、そうでなければ管理が重いものとはなります。
終わりに
クロスドメイン環境におけるALBの固定レスポンスに関する考慮点を簡単にですがまとめてみました。
現在もでALBであれば全体適用といったシンプルなパターンであれば対応できるものとなっておりますが、やはりサービス特性上複雑なことはできないのでそれをやろうとすると別の対応を打つ必要が出てきます。
その場合の対応例として他にも2つほど例を挙げさせていただきましたが、Lambdaの例のようにある程度組み込んだ処理をしようと思うとやはり自分で色々処理を書き込むという形にはなってしまいます。
例には挙げていませんがWeb+アプリサーバが一体化しているのであれば(Apache/Nginxを利用せずSpringBoot組み込みtomcatのみ利用、mod_phpを利用したApache)、それを切り離して独立させApache側で色々設定を書き込んだ方が良い可能性もありますのでその辺りは環境特性に応じて選択して行きましょう