web-dev-qa-db-ja.com

Spring Boot + Kubernetesでフォワードヘッダーが機能しない

バックグラウンド

最近、SpringアプリをSpring Boot(Tomcatが埋め込まれている)に移行しました。現在、Kubernetesに移行しています。 Kubernetesへの移行の一環として、Apache構成を独自のサービスに分離し、Kubernetesにデプロイして、SpringBootアプリのプロキシとして機能させます。

私の現在のセットアップは、世界中からのリクエストを受け入れるLoadBalancerサービスを備えたApacheです。これにより、これらのリクエストが取得され、ClusterIPサービスを備えたSpringBootアプリに転送されます。

また、注意することが重要です。私のApacheはすべてのhttpをhttpsにリダイレクトします。

問題

Spring Bootアプリがクライアントにリダイレクトを返すときは常に、応答のロケーションヘッダーはhttpsではなくhttpです(httpsを介して行われたリクエストのみがApacheプロキシを介してアプリに送信されます)。

ログインしていないユーザーは、次の場所に移動します。

https://example.com/admin

認証されていない場合、管理ページはユーザーをログインページにリダイレクトします。これは、次のリダイレクトの1つである必要があります。

https://example.com/login

ただし、現状では、私のアプリはユーザーを次の場所にリダイレクトします。

http://example.com/login

そして、ユーザーはApacheによって次の場所に再度リダイレクトされます。

https://example.com/login

私が試したこと

ログをチェックして、アプリが受信するリクエストにX-Forwarded-Proto: httpsヘッダーが含まれていることを確認しました。これは、私が理解していることから、リダイレクト応答httpsの場所ヘッダーを作成する必要があります。

いくつかのStackOverflowの投稿で述べたように、server.use-forward-headers=trueファイルにapplication.propertiesを追加しようとしましたが、何もしませんでした。また、server.Tomcat.protocol-header=X-Forwarded-Protoを追加しようとしましたが、これも何もしませんでした(そして、私が読んだものから、とにかくデフォルトです)。

その他の注意事項

  • 私のクラスターのnetworkCIDRは、TomcatのRemoteIPValveの内部プロキシのリストに含まれています。
  • X-Forwarded-Forも影響がないようですので、問題はすべてのフォワードヘッダーにあると思います
8
Mazen Ammar

私はそれを考え出した。私の間違いは、networkCIDRrequest.getRemoteAddr()によって返されたIPアドレスであり、実際にはk8sの内部クラスターIPであると想定していたことです。これは、リクエストがクラスター内にあるApacheから送信されていることを考えると理にかなっています。内部クラスターIPは内部プロキシのリストに含まれていなかったため、RemoteIPValveはフォワードヘッダーを利用していませんでした。

RemoteIpValveで指定されたデフォルト値と内部クラスターIPを使用してserver.Tomcat.internal-proxiesプロパティをapplication.propertiesに追加することにより、すべてが正常に機能しました。

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-customize-Tomcat-behind-a-proxy-serverを参照してください

7
Mazen Ammar