Google Cloud Platform の Load Balancing の設定は非常に簡単でありながら、同時に非常に高性能にグローバル規模での分散も可能なものです。
今回は、ロードバランサのフロント側は HTTP と HTTPS の両方での通信を可能にし、バックエンド側は HTTP のみの場合において、クライアントがどのようなプロトコルで接続してきているのか、それを判別する方法をご紹介していきます。
上の図のように、クライアントからの通信には HTTPS と HTTP の両方に対応しており、ロードバランサとバックエンドの通信は HTTP のみとなっています。
バックエンドは HTTPS で接続待機しないため証明書の登録は必要ありませんが、ロードバランサには予め取得しておいた証明書を登録しておきます。
仮にクライアントが HTTPS で接続してきたとしても、ロードバランサが暗号を解除して HTTP に変換してバックエンドに通信を繋げます。バックエンドからクライアントへの通信はロードバランサで暗号化されます。
今回は例として、クライアントの接続が HTTPS か HTTP かをバックエンド側で識別し、HTTP だった場合にはクライアントに HTTPS にリダイレクトさせる Go言語コードをご紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 にリダイレクトさせましょう。