Setting up an HTTP-to-HTTPS redirect

This example demonstrates how to use URL redirects to redirect all requests from port 80 (HTTP) to port 443 (HTTPS).

HTTPS uses TLS (SSL) to encrypt HTTP requests and responses, making it safer and more secure. A website that uses HTTPS has https:// in the beginning of its URL instead of http://.

Architecture

To redirect HTTP traffic to HTTPS, you must do the following:

  1. (Prerequisite) You must have an external HTTPS load balancer (called here LB1) that is already serving HTTPS traffic on port 443.
  2. Create a partial external HTTP load balancer (called here LB2). The LB2 setup has the following:

    • No backend
    • The same frontend IP address used by LB1
    • A redirect configured in the URL map

This architecture is shown in the following diagram.

HTTP-to-HTTPS redirect configuration (click to enlarge)
HTTP-to-HTTPS redirect configuration

Prerequisite: Set up an external HTTPS load balancer (LB1)

If you don't already have an external HTTPS load balancer configured, use one of the following guides to complete that setup. Select a procedure for your backend type:

If you already have a functioning HTTPS load balancer, skip to Redirecting traffic to your HTTPS load balancer.

Redirecting traffic to your HTTPS load balancer

After you have verified that your external HTTPS load balancer (LB1) is working, you can create the partial external HTTP load balancer (LB2) with its frontend configured to redirect traffic to LB1.

This example uses the 301 response code. You can instead use a different response code.

To configure the redirect with gcloud, you must import a YAML file and make sure that your target HTTP proxy points to the URL map that redirects traffic. If you're using the Cloud Console, this is handled for you.

Console

Start the configuration

  1. In the Google Cloud Console, go to the Load balancing page.

    Go to Load balancing

  2. Under HTTP(S) load balancing, click Start configuration.
  3. Select From Internet to my VMs, and then click Continue.
  4. For the Name of the load balancer, enter something like http-redirect.
  5. Keep the window open to continue.

Skip the backend configuration

  1. Skip the Backend Configuration section.
    This load balancer doesn't need a backend.

Configure the redirect in the URL map

  1. In the left column of the page, click Host and path rules.
  2. Select Advanced host and path rule (URL redirect, URL rewrite).
  3. Under Action, select Redirect the client to different host/path.
  4. Leave the Prefix redirect field blank.
  5. Under Path redirect, select Prefix redirect.
  6. Leave the Path value field blank.
  7. Under Redirect response code, select 301 - Moved Permanently.
  8. Under HTTPS redirect, select Enable.
  9. Click Done.
  10. Keep the load balancer configuration page open to continue.

Configure the HTTP forwarding rule with the same IP address used in LB1

  1. On the load balancer configuration page, click Frontend configuration.
  2. Set Protocol to HTTP.
  3. Set IP address to the same IP address that you use for your HTTPS load balancer.
  4. Ensure that Port is set to 80 to allow HTTP traffic.
  5. Click Done.
  6. Keep the window open to continue.

Review the configuration

  1. In the left panel, click Review and finalize.
  2. Compare your settings to what you intended to create.
  3. If everything looks correct, click Create.

gcloud

  1. Create a YAML file /tmp/web-map-http.yaml. This example uses MOVED_PERMANENTLY_DEFAULT as the response code.

    kind: compute#urlMap
    name: web-map-http
    defaultUrlRedirect:
      redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
      httpsRedirect: True
    tests:
    - description: Test with no query parameters
      host: foobar
      path: /test/
      expectedOutputUrl: https://foobar/test/
      expectedRedirectResponseCode: 301
    - description: Test with query parameters
      host: foobar
      path: /test/?parameter1=value1&parameter2=value2
      expectedOutputUrl: https://foobar/test/?parameter1=value1&parameter2=value2
      expectedRedirectResponseCode: 301
    
  2. Validate the URL map.

    gcloud compute url-maps validate --source /tmp/web-map-http.yaml
    

    If the tests pass and the command outputs a success message, save the changes to the URL map.

  3. Create the HTTP load balancer's URL map by importing the YAML file. The name for this URL map is web-map-http.

    gcloud compute url-maps import web-map-http \
       --source /tmp/web-map-http.yaml \
       --global
    

    If you are updating an existing URL map, the following prompt appears:

    Url Map [web-map-http] will be overwritten.
    
    Do you want to continue (Y/n)?
    

    To continue, press Y.

  4. Verify that the URL map is updated. Your HTTP load balancer's URL map should look something like this:

    gcloud compute url-maps describe web-map-http
    
    creationTimestamp: '2020-03-23T10:53:44.976-07:00'
    defaultUrlRedirect:
     httpsRedirect: true
     redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
    fingerprint: 3A5N_RLrED8=
    id: '2020316695093397831'
    kind: compute#urlMap
    name: web-map-http
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/urlMaps/web-map-http
    
  5. Create a new target HTTP proxy or update an existing target HTTP proxy, using web-map-http as the URL map.

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

    OR

    gcloud compute target-http-proxies update http-lb-proxy \
       --url-map=web-map-http \
       --global
    
  6. Create a global forwarding rule to route incoming requests to the proxy. The --address flag specifies lb-ipv4-1, which is the same IP address used for the external HTTPS load balancer.

    gcloud compute forwarding-rules create http-content-rule \
       --address=lb-ipv4-1 \
       --global \
       --target-http-proxy=http-lb-proxy \
       --ports=80
    

When you are finished, the Cloud Console displays two load balancers, as follows.

Both load balancers

The Cloud Console displays information about your web-map-http load balancer as follows.

HTTP load balancer

Adding a custom header

Optionally, add the HTTP Strict-Transport-Security header to your HTTPS load balancer's backend service, as follows:

  • Header name: Strict-Transport-Security
  • Header value: max-age=31536000; includeSubDomains; preload

This setting sends the custom header to the client so that the next time the client tries to access the URL through HTTP, the browser does the redirect.

To add the custom header to the backend service configuration, use the --custom-response-header flag, as shown here:

gcloud compute backend-services update BACKEND_SERVICE_NAME_LB1 \
    --global \
    --custom-response-header='Strict-Transport-Security:max-age=31536000; includeSubDomains; preload'

For more information, see Creating custom headers.

Testing the HTTP-to-HTTPS redirect

Note the reserved IP address that you are using for both load balancers.

gcloud compute addresses describe lb-ipv4-1 \
    --format="get(address)" \
    --global

In this example, assume that the reserved IP address is 34.98.77.106. The http://34.98.77.106/ URL redirects to https://34.98.77.106/.

After a few minutes have passed, you can test this by running the following curl command.

curl -v http://hostname.com

Sample output:

* Connected to 34.98.77.106 (34.98.77.106) port 80 (#0)
> GET / HTTP/1.1
> Host: hostname.com
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer
< Location: https://hostname.com
< Content-Length: 220
< Date: Fri, 30 Jul 2021 21:32:25 GMT
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://hostname.com">here</A>.
</BODY></HTML>
* Connection #0 to host hostname.com left intact