How can you redirect from HTTP to HTTPS where IAP is configured with GCP Load Balancers?

I've currently got a website hosted on Google Compute Engine that's authenticated with Identity-Aware-Proxy which sits behind a load balancer. This all works great over https, but I was wanting to make sure that http redirects to https as it currently just responds with a 404.

So, I followed https://cloud.google.com/load-balancing/docs/https/setting-up-http-https-redirect which tells you to set up a second load balancer to redirect http traffic to https.

The issue is however, that after following these instructions, when I browse to http://my-website.com I get the following error:

Error 403 (Forbidden)!!1

  1. That’s an error.

Your client does not have permission to get URL / from this server. That’s all we know.

Although the http load balancer is set up with a 301 - Moved Permanently Full path Redirect, in the browser developer tools network tab there is no redirect which happens. It just responds straight away with the 403. The URL also stays with the http:// scheme.


To summarise, here's what my setup looks like:

External HTTPS Load Balancer

  • Frontend - HTTPS, static IP, HTTPS only
  • Backend - Identity-Aware-Proxy (email authentication via Identity Platform) -> Compute Engine instance group

External HTTP Load Balancer

  • Frontend - HTTP, static IP (Same as HTTPS Load Balancer above)
  • Backend - None
  • Host and Path Rules:
    • Mode: Advanced host and path rule (URL redirect, URL rewrite)
    • Action: Redirect the client to different host/path
    • Host redirect: https://my-website.com
    • Path value: *
    • Redirect response code: 301 - Moved Permanently
    • HTTPS redirect: Enabled

Any ideas how to fix this, and not get the 403 would be much appreciated!


The way you described it looks like you have an issue with url-map because you can access the http version of your site.

To be absolutely sure double check (or create new) url-map with gcloud command:

gcloud compute url-maps describe web-map-http

creationTimestamp: '2020-12-02T03:18:27.053-08:00'
defaultUrlRedirect:
  httpsRedirect: true
  redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
fingerprint: KU2hPu1ao=
id: '50586028237895404'
kind: compute#urlMap
name: web-map-http
selfLink: https://www.googleapis.com/compute/v1/projects/xxxxx/global/urlMaps/web-map-http

When you have your URL-map ready, create a target-proxy:

gcloud compute target-http-proxies create http-lb-proxy \
   --url-map=web-map-http \
   --global

result:

gcloud compute target-http-proxies describe http-lb-proxy
creationTimestamp: '2020-12-02T03:19:39.090-08:00'
fingerprint: lgJkIY8E=
id: '3781119498457764'
kind: compute#targetHttpProxy
name: http-lb-proxy
selfLink: https://www.googleapis.com/compute/v1/projects/xxxx/global/targetHttpProxies/http-lb-proxy
urlMap: https://www.googleapis.com/compute/v1/projects/xxxx/global/urlMaps/web-map-http

and a forwarding rule:

gcloud compute forwarding-rules create http-content-rule \
   --address=lb-ipv4-1 \ # Same IP address used for HTTPS load balancer
   --global \
   --target-http-proxy=http-lb-proxy \
   --ports=80

wchich should look like:

gcloud compute forwarding-rules describe http-content-rule --global
IPAddress: 34.107.123.141
IPProtocol: TCP
creationTimestamp: '2020-12-02T03:22:38.132-08:00'
description: ''
fingerprint: L1vA0Ik9Y=
id: '888330202637841'
kind: compute#forwardingRule
loadBalancingScheme: EXTERNAL
name: http-content-rule
networkTier: PREMIUM
portRange: 80-80
selfLink: https://www.googleapis.com/compute/v1/projects/xxxx/global/forwardingRules/http-content-rule
target: https://www.googleapis.com/compute/v1/projects/xxxx/global/targetHttpProxies/http-lb-proxy

Make sure you use the same public IP for both HTTP and HTTPS LB's. Check the firewall rules if the incoming traffic doesn't get blocked.

If you do everything correct you should get the same curl output as presented in the example.