Configura el redireccionamiento de HTTP a HTTPS para balanceadores de cargas de HTTP(S) internos

En este ejemplo, se muestra cómo todas las solicitudes al puerto 80 se redireccionan a sus respectivos servicios de HTTPS.

Si quieres obtener información sobre cómo configurar el redireccionamiento de HTTP a HTTPS para el balanceo de cargas externo, consulta Configura el redireccionamiento de HTTP a HTTPS para balanceadores de cargas de HTTP(S) externos.

A fin de usar redireccionamientos de HTTP a HTTPS con una dirección IP compartida, debes crear dos balanceadores de cargas, uno para el tráfico de HTTPS y otro para el tráfico de HTTP. Cada balanceador de cargas tiene su propia regla de reenvío y mapa de URL, pero comparte la misma dirección IP. Para el balanceador de cargas de HTTP, no necesitas configurar un backend porque el frontend redirecciona el tráfico al backend del balanceador de cargas de HTTPS.

En este ejemplo, se muestra cómo redireccionar todas las solicitudes del puerto 80 al puerto 443.

En un alto nivel, para redireccionar el tráfico de HTTP a HTTPS, debes hacer lo siguiente:

  1. Crea un balanceador de cargas de HTTPS interno normal con una dirección IP interna reservada y compartida.
  2. Prueba el balanceador de cargas de HTTPS interno para asegurarte de que funcione.
  3. Redirecciona el tráfico al balanceador de cargas de HTTPS interno.
    Para hacer esto, debes agregar un balanceador de cargas de HTTP interno parcial que tenga un frontend, pero que no tenga backends. El frontend recibe solicitudes y, luego, las redirecciona al balanceador de cargas de HTTPS interno. Para ello, usa el siguiente comando:
    • Una regla de reenvío con la misma dirección IP interna reservada que usa el balanceador de cargas de HTTPS (a la que se hace referencia en el paso 1)
    • Un proxy HTTP de destino
    • Un mapa de URL que redirecciona el tráfico al balanceador de cargas de HTTPS

Como se muestra en el siguiente diagrama, el balanceador de cargas de HTTPS interno es un balanceador de cargas normal con los componentes del balanceador de cargas esperados.

El balanceador de cargas de HTTP tiene la misma dirección IP que el balanceador de cargas de HTTPS, una instrucción de redireccionamiento en el mapa de URL y no tiene un backend.

Configuración de redireccionamiento de HTTP a HTTPS interno (haz clic para agrandar)
Configuración de redireccionamiento de HTTP a HTTPS interno

Crea el balanceador de cargas de HTTPS interno

Este proceso es similar a la configuración de un balanceador de cargas de HTTP(S) interno.

La configuración del balanceo de cargas de HTTP(S) interno tiene dos partes:

  • Realizar tareas de requisitos previos, como garantizar que las cuentas obligatorias tengan los permisos correctos y preparar la red de nube privada virtual (VPC)
  • Configurar los recursos del balanceador de cargas

Antes de seguir con esta guía, familiarízate con lo siguiente:

Permisos

Para seguir esta guía, debes poder crear instancias y modificar una red en un proyecto. Debes ser propietario o editor de un proyecto o tener todas las siguientes funciones de IAM de Compute Engine:

Tarea Función requerida
Crear redes, subredes y componentes del balanceador de cargas Administrador de redes
Agregar y quitar reglas de firewall Administrador de seguridad
Crea instancias Administrador de instancias

Si deseas obtener más información, consulta las siguientes guías:

Configura la red y las subredes

Necesitas una red de VPC con dos subredes: una para los backends del balanceador de cargas y la otra para los proxies del balanceador de cargas. Un balanceador de cargas de HTTP(S) interno es regional. El tráfico dentro de la red de VPC se enruta al balanceador de cargas si la fuente de tráfico está en una subred en la misma región que el balanceador de cargas.

Este ejemplo usa la siguiente red de VPC, región y subredes:

  • Red. Es una red de VPC de modo personalizado con el nombre lb-network.

  • Subred para backends. Una subred llamada backend-subnet en la región us-west1 usa 10.1.2.0/24 en su rango de IP principal.

  • Subred para proxies. Una subred llamada proxy-only-subnet en la región us-west1 usa 10.129.0.0/23 en su rango de IP principal.

Configura la red y la subred para los backends

Console

  1. Ve a la página Redes de VPC en Google Cloud Console.
    Ir a la página Redes de VPC
  2. Haz clic en Crear red de VPC.
  3. En Nombre, ingresa lb-network.
  4. En la sección Subredes, haz lo siguiente:
    • Establece Modo de creación de subred en Personalizado.
    • En la sección Nueva subred, ingresa la siguiente información:
      • Nombre: backend-subnet
      • Región:: us-west1
      • Rangos de direcciones IP: 10.1.2.0/24
    • Haz clic en Listo.
  5. Haz clic en Crear.

gcloud

  1. Crea la red de VPC personalizada con el comando gcloud compute networks create:

    gcloud compute networks create lb-network --subnet-mode=custom
    
  2. Crea una subred en la red lb-network en la región us-west1 con el comando gcloud compute networks subnets create:

    gcloud compute networks subnets create backend-subnet \
        --network=lb-network \
        --range=10.1.2.0/24 \
        --region=us-west1
    

API

Realiza una solicitud POST al método networks.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks

{
  "routingConfig": {
    "routingMode": "REGIONAL"
  },
  "name": "lb-network",
  "autoCreateSubnetworks": false
}

Realiza una solicitud POST al método subnetworks.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/us-west1/subnetworks

{
  "name": "backend-subnet",
  "network": "projects/project-id/global/networks/lb-network",
  "ipCidrRange": "10.1.2.0/24",
  "region": "projects/project-id/regions/us-west1",
}

Configura la subred de solo proxy

La subred de solo proxy es para todos los balanceadores de cargas de HTTP(S) internos en la región us-west1.

Console

Si usas Google Cloud Console, puedes esperar y crear la subred de solo proxy más adelante en la página Balanceo de cargas.

gcloud

Crea la subred de solo proxy con el comando gcloud compute networks subnets create.

gcloud compute networks subnets create proxy-only-subnet \
  --purpose=INTERNAL_HTTPS_LOAD_BALANCER \
  --role=ACTIVE \
  --region=us-west1 \
  --network=lb-network \
  --range=10.129.0.0/23

API

Crea la subred de solo proxy con el método subnetworks.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/projects/PROJECT_ID/regions/us-west1/subnetworks

{
  "name": "proxy-only-subnet",
  "ipCidrRange": "10.129.0.0/23",
  "network": "projects/project-id/global/networks/lb-network",
  "region": "projects/project-id/regions/us-west1",
  "purpose": "INTERNAL_HTTPS_LOAD_BALANCER",
  "role": "ACTIVE"
}

Configura las reglas de firewall

En este ejemplo, se usan las siguientes reglas de firewall:

  • fw-allow-ssh. Es una regla de entrada, aplicable a las instancias con balanceo de cargas, y que permite la conectividad SSH entrante en el puerto TCP 22 desde cualquier dirección. Puedes elegir un rango de IP de origen más restrictivo para esta regla; por ejemplo, puedes especificar solo los rangos de IP del sistema desde el que inicias sesiones SSH. En este ejemplo, se usa la etiqueta de destino allow-ssh.

  • fw-allow-health-check. Una regla de entrada, aplicable a las instancias en las que se realiza el balanceo de cargas, que permite todo el tráfico de TCP de los sistemas de verificación de estado de Google Cloud (en 130.211.0.0/22 y 35.191.0.0/16). En este ejemplo, se usa la etiqueta de destino load-balanced-backend.

  • fw-allow-proxies. Es una regla de entrada, aplicable a las instancias con balanceo de cargas, que permite el tráfico de TCP en los puertos 804438080, y desde los proxies administrados del balanceador de cargas de HTTP(S) interno. En este ejemplo, se usa la etiqueta de destino load-balanced-backend.

Sin estas reglas de firewall, la regla de entrada predeterminada denegada bloquea el tráfico entrante a las instancias de backend.

Las etiquetas de destino definen las instancias de backend. Sin las etiquetas de destino, las reglas de firewall se aplican a todas las instancias de backend en la red de VPC. Cuando crees las VM de backend, asegúrate de incluir las etiquetas de destino especificadas, como se muestra en Crea un grupo de instancias administrado.

Console

  1. Ve a la página Reglas de Firewall en Google Cloud Console.
    Ir a la página Reglas de firewall
  2. Haz clic en Crear regla de firewall para crear la regla que permite conexiones SSH entrantes:
    • Nombre: fw-allow-ssh
    • Red: lb-network
    • Dirección del tráfico: Entrada
    • Acción en caso de coincidencia: Permitir
    • Objetivos: Etiquetas de objetivo especificadas
    • Etiquetas de destino: allow-ssh
    • Filtro de fuente: Rangos de IP
    • Rangos de IP de origen0.0.0.0/0
    • Protocolos y puertos:
      • Elige Protocolos y puertos especificados.
      • Selecciona la casilla de verificación tcp y, luego, ingresa 22 para el número de puerto.
  3. Haz clic en Crear.
  4. Haz clic en Crear regla de firewall por segunda vez para crear la regla que permita las verificaciones de estado de Google Cloud:
    • Nombre: fw-allow-health-check
    • Red: lb-network
    • Dirección del tráfico: Entrada
    • Acción en caso de coincidencia: Permitir
    • Objetivos: Etiquetas de objetivo especificadas
    • Etiquetas de destino: load-balanced-backend
    • Filtro de fuente: Rangos de IP
    • Rangos de IP de origen: 130.211.0.0/22 y 35.191.0.0/16
    • Protocolos y puertos:
      • Elige Protocolos y puertos especificados.
      • Selecciona la casilla de verificación tcp y, luego, ingresa 80 para el número de puerto.
        Como práctica recomendada, limita esta regla solo a los protocolos y puertos que coincidan con los que usa tu verificación de estado. Si usas tcp:80 en el protocolo y el puerto, Google Cloud puede usar HTTP en el puerto 80 a fin de contactar las VM, pero no puede usar HTTPS en el puerto 443 para comunicarse con ellas.
  5. Haz clic en Crear.
  6. Haz clic en Crear regla de firewall por tercera vez para crear la regla a fin de permitir que los servidores proxy del balanceador de cargas conecten los backends:
    • Nombre: fw-allow-proxies
    • Red: lb-network
    • Dirección del tráfico: Entrada
    • Acción en caso de coincidencia: Permitir
    • Objetivos: Etiquetas de objetivo especificadas
    • Etiquetas de destino: load-balanced-backend
    • Filtro de fuente: Rangos de IP
    • Rangos de IP de origen10.129.0.0/23
    • Protocolos y puertos:
      • Elige Protocolos y puertos especificados.
      • Selecciona la casilla de verificación tcp y, luego, ingresa 80, 443, 8080 para los números de puerto.
  7. Haz clic en Crear.

gcloud

  1. Crea la regla de firewall fw-allow-ssh para permitir la conectividad SSH a las VM con la etiqueta de red allow-ssh. Cuando omites source-ranges, Google Cloud interpreta que la regla significa cualquier fuente.

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    
  2. Crea la regla fw-allow-health-check para permitir las verificaciones de estado de Google Cloud. Este ejemplo permite todo el tráfico de TCP proveniente de la verificación de estado. Sin embargo, puedes configurar un conjunto más limitado de puertos según tus necesidades.

    gcloud compute firewall-rules create fw-allow-health-check \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=load-balanced-backend \
        --rules=tcp
    
  3. Crea la regla fw-allow-proxies para permitir que los proxies del balanceador de cargas de HTTP(S) interno se conecten con los backends. Configura source-ranges en los rangos asignados de tu subred de solo proxy, por ejemplo, 10.129.0.0/23.

    gcloud compute firewall-rules create fw-allow-proxies \
      --network=lb-network \
      --action=allow \
      --direction=ingress \
      --source-ranges=source-range \
      --target-tags=load-balanced-backend \
      --rules=tcp:80,tcp:443,tcp:8080
    

API

Crea la regla de firewall fw-allow-ssh mediante una solicitud POST al método firewalls.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls

{
  "name": "fw-allow-ssh",
  "network": "projects/project-id/global/networks/lb-network",
  "sourceRanges": [
    "0.0.0.0/0"
  ],
  "targetTags": [
    "allow-ssh"
  ],
  "allowed": [
   {
     "IPProtocol": "tcp",
     "ports": [
       "22"
     ]
   }
  ],
 "direction": "INGRESS"
}

Crea la regla de firewall fw-allow-health-check mediante una solicitud POST al método firewalls.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls

{
  "name": "fw-allow-health-check",
  "network": "projects/project-id/global/networks/lb-network",
  "sourceRanges": [
    "130.211.0.0/22",
    "35.191.0.0/16"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    }
  ],
  "direction": "INGRESS"
}

Crea la regla de firewall fw-allow-proxies a fin de permitir el tráfico de TCP dentro de la subred de proxy para el método firewalls.insert y reemplaza PROJECT_ID por el ID del proyecto.

POST https://compute.googleapis.com/compute/v1/projects/{project}/global/firewalls

{
  "name": "fw-allow-proxies",
  "network": "projects/project-id/global/networks/lb-network",
  "sourceRanges": [
    "10.129.0.0/23"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "80"
      ]
    },
  {
      "IPProtocol": "tcp",
      "ports": [
        "443"
      ]
    },
    {
      "IPProtocol": "tcp",
      "ports": [
        "8080"
      ]
    }
  ],
  "direction": "INGRESS"
}

Crea los recursos del balanceador de cargas de HTTPS interno

En este ejemplo, se usan backends de máquina virtual en Compute Engine en un grupo de instancias administrado. En su lugar, puedes usar otros tipos de backend compatibles.

Crea una plantilla de instancias con un servidor HTTP

gcloud

gcloud compute instance-templates create l7-ilb-backend-template \
    --region=us-west1 \
    --network=lb-network \
    --subnet=backend-subnet \
    --tags=allow-ssh,load-balanced-backend \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --metadata=startup-script='#! /bin/bash
    apt-get update
    apt-get install apache2 -y
    a2ensite default-ssl
    a2enmod ssl
    vm_hostname="$(curl -H "Metadata-Flavor:Google" \
    http://169.254.169.254/computeMetadata/v1/instance/name)"
    echo "Page served from: $vm_hostname" | \
    tee /var/www/html/index.html
    systemctl restart apache2'

Crea un grupo de instancias administrado en la zona

gcloud

gcloud compute instance-groups managed create l7-ilb-backend \
    --zone=us-west1-a \
    --size=2 \
    --template=l7-ilb-backend-template

Crea una verificación de estado de HTTP

gcloud

gcloud compute health-checks create http l7-ilb-basic-check \
     --region=us-west1 \
     --use-serving-port

Crea un servicio de backend

gcloud

gcloud compute backend-services create l7-ilb-backend-service \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --protocol=HTTP \
    --health-checks=l7-ilb-basic-check \
    --health-checks-region=us-west1 \
    --region=us-west1

Agrega backends al servicio de backend

gcloud

gcloud compute backend-services add-backend l7-ilb-backend-service \
    --balancing-mode=UTILIZATION \
    --instance-group=l7-ilb-backend \
    --instance-group-zone=us-west1-a \
    --region=us-west1

Crea un mapa de URL

gcloud

gcloud compute url-maps create l7-ilb-service-url-map \
    --default-service=l7-ilb-backend-service \
    --region=us-west1

Crea un certificado SSL regional

En el siguiente ejemplo, se muestra cómo usar gcloud para crear un certificado SSL autoadministrado. Para obtener más información, consulta Usa certificados SSL autoadministrados y Usa certificados SSL administrados por Google.

gcloud

gcloud compute ssl-certificates create CERTIFICATE_NAME \
    --certificate=CERTIFICATE_FILE \
    --private-key=PRIVATE_KEY_FILE \
    --region=us-west1

Usa el certificado SSL regional para crear un proxy de destino

gcloud

gcloud compute target-https-proxies create l7-ilb-https-proxy \
    --url-map=l7-ilb-service-url-map \
    --region=us-west1 \
    --ssl-certificates=l7-ilb-cert

Reserva una dirección IP compartida para las reglas de reenvío

gcloud

gcloud beta compute addresses create \
    --addresses=10.1.2.99 \
    --region=us-west1 \
    --subnet=backend-subnet \
    --purpose=SHARED_LOADBALANCER_VIP

Crea una regla de reenvío de HTTPS

gcloud

gcloud compute forwarding-rules create l7-ilb-https-forwarding-rule \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --network=lb-network \
    --subnet=backend-subnet \
    --address=10.1.2.99 \
    --ports=443 \
    --region=us-west1 \
    --target-https-proxy=l7-ilb-https-proxy \
    --target-https-proxy-region=us-west1

Prueba el balanceador de cargas de HTTPS

En este punto, el balanceador de cargas está listo (incluido el servicio de backend, el mapa de URL y la regla de reenvío). Prueba este balanceador de cargas para verificar que funcione como se esperaba.

Crea una instancia de VM de cliente para probar la conectividad.

gcloud

gcloud compute instances create l7-ilb-client-us-west1-a \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --network=lb-network \
    --subnet=backend-subnet \
    --zone=us-west1-a \
    --tags=allow-ssh

Conéctate a la VM cliente mediante SSH.

gcloud

gcloud compute ssh l7-ilb-client-us-west1-a \
    --zone=us-west1-a

Usa Curl para conectarte al balanceador de cargas de HTTPS.

curl -k -s 'https://10.1.2.99:443' --connect-to 10.1.2.99:443

Resultado de muestra:

Page served from: l7-ilb-backend-850t

Envía 100 solicitudes y verifica que todas las cargas estén balanceadas.

{
  RESULTS=
  for i in {1..100}
  do
      RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.99:443)"
  done
  echo "***"
  echo "*** Results of load-balancing to 10.1.2.99: "
  echo "***"
  echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
  echo
}

Resultado de muestra:

***
*** Results of load-balancing to 10.1.2.99:
***
     51  l7-ilb-backend-https-850t
     49  l7-ilb-backend-https-w11t
    100 Page served from

Redirecciona el tráfico al balanceador de cargas de HTTPS

El balanceador de cargas de HTTP tiene una dirección IP compartida que redirecciona el tráfico del puerto 80 al puerto 443.

Crea un nuevo mapa de URL para redireccionar el tráfico

Crea un archivo YAML con la configuración de redireccionamiento del tráfico.

echo "defaultService: regions/us-west1/backendServices/l7-ilb-backend-service
kind: compute#urlMap
name: l7-ilb-redirect-url-map
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- name: matcher1
  defaultUrlRedirect:
        hostRedirect: 10.1.2.99:443
        pathRedirect: /
        redirectResponseCode: PERMANENT_REDIRECT
        httpsRedirect: True
        stripQuery: True" > /tmp/url_map.yaml

Importa el archivo YAML a un mapa de URL nuevo.

gcloud

gcloud compute url-maps import l7-ilb-redirect-url-map \
    --source /tmp/url_map.yaml \
    --region us-west1

Crea el proxy de destino del balanceador de cargas de HTTP

gcloud

gcloud compute target-http-proxies create l7-ilb-http-proxy \
    --url-map=l7-ilb-redirect-url-map \
    --url-map-region=us-west1 \
    --region=us-west1

Crea una regla de reenvío nueva y la dirección IP compartida

gcloud

gcloud compute forwarding-rules create l7-ilb-forwarding-rule \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --network=lb-network \
    --subnet=backend-subnet \
    --address=10.1.2.99 \
    --ports=80 \
    --region=us-west1 \
    --target-http-proxy=l7-ilb-http-proxy \
    --target-http-proxy-region=us-west1

Prueba el redireccionamiento del tráfico

Conéctate a la VM cliente.

gcloud

gcloud compute ssh l7-ilb-client-us-west1-a \
    --zone=us-west1-a

Envía una solicitud HTTP a 10.1.2.99 en el puerto 80, espera un redireccionamiento del tráfico.

curl -L -k 10.1.2.99

Un resultado de muestra.

Page served from: l7-ilb-backend-w11t

Puedes agregar -vvv para ver más detalles.

curl -L -k 10.1.2.99 -vvv

* Rebuilt URL to: 10.1.2.99/
*   Trying 10.1.2.99...
* TCP_NODELAY set
* Connected to 10.1.2.99 (10.1.2.99) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.1.2.99
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< location: https://10.1.2.99:443/
< date: Fri, 07 Aug 2020 05:07:18 GMT
< via: 1.1 google
< content-length: 0
<
* Curl_http_done: called premature == 0
* Connection #0 to host 10.1.2.99 left intact
* Issue another request to this URL: 'https://10.1.2.99:443/'
*   Trying 10.1.2.99...
* TCP_NODELAY set
* Connected to 10.1.2.99 (10.1.2.99) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
...
...
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: O=Google TESTING; CN=test_cert_1
*  start date: Jan  1 00:00:00 2015 GMT
*  expire date: Jan  1 00:00:00 2025 GMT
*  issuer: O=Google TESTING; CN=Intermediate CA
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x561a6b0e3ea0)
> GET / HTTP/1.1
> Host: 10.1.2.99
> User-Agent: curl/7.52.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< date: Fri, 07 Aug 2020 05:07:18 GMT
< server: Apache/2.4.25 (Debian)
< last-modified: Thu, 06 Aug 2020 13:30:21 GMT
< etag: "2c-5ac357d7a47ec"
< accept-ranges: bytes
< content-length: 44
< content-type: text/html
< via: 1.1 google
<
Page served from: l7-ilb-backend-https-w11t
* Curl_http_done: called premature == 0
* Connection #1 to host 10.1.2.99 left intact

¿Qué sigue?