Cloudfrontでリバースプロキシする

どうも二人目です。

リプレースなどで、Webサーバに持たせていたリバースプロキシの機能をcloudfrontに持たせたいパターンがあると思います。

私はこれでいくつかハマったポイントがありますので、まとめようと思います。

①HTTPS通信エラー


最初にハマったのがこれです。
cloudfrontのorigin設定に対抗サイトの情報を設定してhttps通信を試しましたが、502:Bad Gatewayのエラー発生しました。

エラー内容を見ると、SSLハンドシェイクに失敗しているようでした。
原因が分からなかったですが、この記事を見つけ解決しました。

Cloudfront-Origin間のHTTPS通信エラー原因と対策(502:Bad Gateway)

https://qiita.com/kaojiri/items/4e2d2f112acfca14970e

原因はHostヘッダーを透過させていたことが原因でした。

この設定を行うと、Cloudfront経由でOriginにアクセスした場合、
CloudfrontはHostヘッダーにCloudfront自身のDNS名をセットしてOriginにアクセスすることになるそうです。

先ほどのサイトの説明が分かりやすかったのでこちらも引用させて頂きます。

なので、対応策としてHostヘッダーの透過を無効化しました。

②パス問題

cloudfrontのビヘイビアの振り分け設定で、特定のパスだけプロキシするような設定をしてみました。

こんな感じのプロキシを実現したかったです。
 https://aaa.com/hoge ⇒ https://hoge.com/

ApacheのProxyで実現するとしたらこんな感じです。

SSLProxyEngine On
ProxyPreserveHost On
ProxyPass /hoge/ https://hoge.com/
ProxyPassReverse /hoge/ https://hoge.com/

でも、オリジンに”hoge.com”を設定したところ以下のような挙動になってしまいました。

https://aaa.com/hoge ⇒ https://hoge.com/hoge

どうやらパスがプロキシ先に引き継がれてしまうようです。
これについてcloudfrontの設定で解決させようと思いましたが、パスの消込をする設定箇所は見つかりませんでした。

これの解決方法として、Lambda@Edgeでパスの消込を行いました。

Lambda ではこんな感じでパスの消込を行いました。

ソースコードは URL の先頭のパスを書き換えを行っています。

'use strict';

exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
request.uri = request.uri.replace(/^\/hoge/g, '');
callback(null, request);
};


後はビヘイビアの設定項目からLambda@Edgeに紐付けてあげればOKです。

これで無事パスは引き継がれなくなりました!


cloudfrontは意外と出来ることが少ないので、Lambda@Edgeも活用していきましょう。

この記事が気に入ったらサポートをしてみませんか?