В моей структуре приложения используются GKE и CloudFlare. Выглядит это так:
CloudFlare -> GKE -> Ingress -> My app running nginx
Я использую гибкий SSL в CloudFlare, поэтому только соединение между пользователем и CloudFlare использует HTTPS, все остальные используют HTTP. Я знаю, что CloudFlare устанавливает X-Forwarded-Proto
к https
в этой ситуации, но когда я вижу заголовки, которые получает мое приложение nginx, оно получает X-Forwarded-Proto: http
.
Я почти уверен, что это происходит где-то между балансировщиком нагрузки GKE и Ingress, поскольку я вижу, что CF-Visitor: {"scheme": "https"}
заголовок, настроенный CloudFlare, установлен на HTTPS. Насколько я понимаю, это означает, что CloudFlare установил X-Forwarded-Proto
к https
, но по ходу дела он был перезаписан.
К сожалению, мне не удалось получить журналы заголовков из GKE Load Balancer (похоже, они не регистрируют X-Forwarded-*
заголовки вообще), поэтому я не могу на 100% подтвердить, что CloudFlare действительно устанавливает заголовки, но я был бы очень удивлен, если это не так.
Если это правда, Google Cloud перезаписывает X-Forwarded-Proto
заголовок с http
. Как мне этого избежать?
Редактировать: Я настроил вход nginx вместо gce после https://cloud.google.com/community/tutorials/nginx-ingress-gke, а X-Forwarded-Proto
установлен на https
как и ожидалось. Это еще один сигнал, что это gce
входной контроллер, который перезаписывает X-Forwarded-Proto
заголовок.
Как описано в Эта статья Cloudflare добавляет заголовок X-Forwarded-Proto, который может быть HTTP или HTTPS в зависимости от протокола, который пользователь использовал для посещения сайта. Если вы считаете, что значение X-Forwarded-Proto должно быть сохранено, но было изменено GCLB, я бы рекомендовал открыть для этого запрос функции на Система отслеживания проблем Google.
Вы можете создать промежуточное ПО:
# 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
Объект JSON, содержащий только один ключ, называемый схемой. Значение идентично значению X-Forwarded-Proto (HTTP или HTTPS). CF-Visitor актуален только при использовании гибкого SSL.