私のアプリ構造はGKEとCloudFlareを使用しています。次のようになります。
CloudFlare -> GKE -> Ingress -> My app running nginx
私はCloudFlareで柔軟なSSLを使用しているため、ユーザーとCloudFlare間の接続のみがHTTPSを使用し、残りのすべてがHTTPを使用します。この状況でCloudFlareがX-Forwarded-Proto
をhttps
に設定することは知っていますが、nginxアプリが受信しているヘッダーを確認すると、X-Forwarded-Proto: http
を取得します。
CloudFlareによって構成されたCF-Visitor: {"scheme": "https"}
ヘッダーがHTTPSに設定されていることがわかるので、これはGKEのロードバランサーとIngressの間のどこかで発生すると確信しています。私の理解では、これはCloudFlareがX-Forwarded-Proto
をhttps
に設定したことを意味しますが、途中で上書きされました。
残念ながら、GKEロードバランサーからヘッダーログを取得できなかったため(X-Forwarded-*
ヘッダーはまったく記録されていないようです)、CloudFlareが実際にヘッダーを設定していることを100%確認できません。でも、そうでなかったらかなりびっくりするでしょう。
その場合、Google CloudはX-Forwarded-Proto
ヘッダーをhttp
で上書きしています。どうすれば回避できますか?
編集:https://cloud.google.com/community/tutorials/nginx-に従って、gceの代わりにnginxイングレスを設定しましたingress-gke 、およびX-Forwarded-Proto
がhttps
に設定されています。これは、X-Forwarded-Proto
ヘッダーを上書きしているのがgce
イングレスコントローラーであることを示す別の信号です。
この記事 で説明されているように、CloudflareはX-Forwarded-Protoヘッダーを追加します。これは、ユーザーがサイトにアクセスするために使用したプロトコルに応じて、HTTPまたはHTTPSになります。 X-Forwarded-Protoの値を維持する必要があるが、GCLBによって変更されたと思われる場合は、 Google issue tracker でこの機能のリクエストを開くことをお勧めします。
ミドルウェアを作成できます。
# frozen_string_literal: true
require 'json'
class CloudflareProxy
def initialize(app)
@app = app
end
def call(env)
return @app.call(env) unless env['HTTP_CF_VISITOR']
env['HTTP_X_FORWARDED_PROTO'] = JSON.parse(env['HTTP_CF_VISITOR'])['scheme']
@app.call(env)
end
end
config/application.rb
で使用:
config.middleware.use CloudflareProxy
CF-Visitor
ヘッダーの参照:
CF-Visitor
スキームと呼ばれるキーを1つだけ含むJSONオブジェクト。値はX-Forwarded-Proto(HTTPまたはHTTPS)と同じです。 CF-Visitorは、Flexible SSLを使用している場合にのみ関連します。