ひとりAdvent Calendar 14日目です。
ASP.NET Core 2.1からHTTPS対応の改善が入っています。
OpenShift上の.NET Coreでもこれをサポートするサンプルが提供されていて以下のブログで解説されています。それを紹介してみようと思います。
OpenShiftの場合、oc expose
などでアプリを公開する限りはrouterがproxyの役割を果すので、edge terminationを設定すればSSLの終端処理はrouterで行われます。その場合、routerからアプリのPodまではHTTP通信となりますが内部通信ですのでそれでも問題ないということも多いでしょう。インストーラーで指定するデフォルトのドメインの場合はrouterに証明書が配置されているはずですし、それ以外のドメインの場合はrouteの作成時に証明書を指定できます。これらの場合は今回のブログは不要です。今回のブログはアプリのPodでSSLの終端処理をしたい場合になります。OpenShiftのsecureなルート設定についてはドキュメントも参照してください。
Routes - Networking | Architecture | OpenShift Container Platform 3.11
また、アプリを公開するrouteのドメインに対応した証明書を直接ASP.NET CoreのPodで処理させる場合は、OpenShift上で動いていることは意識せず通常どおりの設定を行えばOKです。ただ、routeのドメインに対応した証明書を使いたい場合はrouterで処理させた方がアプリ側に余計なことをさせなくてすむのではないかと思います。
今回の対象は、ASP.NET CoreのPodでrouterからアプリへの通信部分を暗号化したいユースケースで、routerが提供している証明書をASP.NET Core側で利用する方法となります。
routerからPodへは<service name>.<service.namespace>.svc
という内部的なドメインで通信されます。このための証明書を(kubernetesのリソースである)secretとしてrouterが提供しており、Podにマウントできます。この証明書をASP.NET Coreで利用すればよいのですが、証明書の形式がそのままでは利用できないものとなっています。そこで、OpenShiftの.NET Coreチームよりサンプルの実装が提供されています。これを利用するためにテンプレートをインポートしましょう。全プロジェクトで利用したい場合は-n openshift
を指定してopenshiftプロジェクトに追加してください。
oc create -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore-ex/dotnetcore-2.1-https/dotnet-example-https.json
追加すると、カタログにASP.NET Core HTTPS example
というのが追加されるのでそれを作成します。パラメーターはデフォルトのままでOKです。
こんな感じにアプリが作られます。routeはhttpsで設定されているのがわかります。
Readiness ProbeとLiveness ProbeもHTTPSになっています。
で、このrouteに接続しようとするとドメイン名が違うので多くのブラウザでは警告が出るはずです。証明書は内部通信用の<service name>.<service.namespace>.svc
で、実際にアクセスしているのはrouteのドメイン(ここではxip.ioを利用)であるからです。
routeの設定を見るとPassthroughとなっておりrouterではSSL終端処理は行われず、Podまで暗号化通信しています。
Podの内部から/var/run/secrets/service-cert
を見ると証明書が配置されていることがわかります。
ASP.NET Coreからこれを利用する仕掛けとしては、openshift.csというクラスが全部やっています。
s2i-dotnetcore-ex/OpenShift.cs at dotnetcore-2.1-https · redhat-developer/s2i-dotnetcore-ex · GitHub
CreateWebHostBuilderで次のように書けば利用できます。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseOpenShiftIntegration(_ => _.CertificateMountPoint = "/var/run/secrets/service-cert") .UseStartup<Startup>();
ので、自分のASP.NET Coreプロジェクトで利用したい場合はクラスをそのまま持って来て1行だけ追加すれば動くことになります。