GCPのロードバランサでクライアントがHTTPS接続かどうかを確認する方法

Google Cloud Platform の Load Balancing の設定は非常に簡単でありながら、同時に非常に高性能にグローバル規模での分散も可能なものです。

今回は、ロードバランサのフロント側は HTTP と HTTPS の両方での通信を可能にし、バックエンド側は HTTP のみの場合において、クライアントがどのようなプロトコルで接続してきているのか、それを判別する方法をご紹介していきます。

コンテンツの転載は固くお断りいたします。

構成図

上の図のように、クライアントからの通信には HTTPS と HTTP の両方に対応しており、ロードバランサとバックエンドの通信は HTTP のみとなっています。

バックエンドは HTTPS で接続待機しないため証明書の登録は必要ありませんが、ロードバランサには予め取得しておいた証明書を登録しておきます。

仮にクライアントが HTTPS で接続してきたとしても、ロードバランサが暗号を解除して HTTP に変換してバックエンドに通信を繋げます。バックエンドからクライアントへの通信はロードバランサで暗号化されます。

今回は例として、クライアントの接続が HTTPS か HTTP かをバックエンド側で識別し、HTTP だった場合にはクライアントに HTTPS にリダイレクトさせる Go言語コードをご紹介します。

識別方法とコード例


func handler(w http.ResponseWriter, r *http.Request) {
	// リクエストヘッダーの X-Forwarded-Proto の値を確認する
	fwp := r.Header.Get("X-Forwarded-Proto")

	// fwp の値は https か http の2種類
	if fwp == "http" {
		// http であれば https にリダイレクトさせる
		http.Redirect(w, r, "https://"+r.Host+r.URL.Path, 301)
		return
	}

	// ここまで辿り着くということは、クライアントのプロトコルが https なので、そのまま処理を継続する
	fmt.Print("プロトコルは HTTPS です!")
}

クライアントの接続は HTTPS か HTTP であるかは、リクエストヘッダーにある『X-Forwarded-Proto』の値を確認することで分かります。 HTTPS接続であれば『https』、HTTP接続であれば『http』がセットされています。

クライアントからの通信が HTTPS であれ HTTP であれ、ロードバランサを経由するのでバックエンドは HTTP のみで待機することになります。

なので、常時SSL対応するのであれば、『X-Forwarded-Proto』に http がセットされていたら HTTPS にリダイレクトさせましょう。