Criar cabeçalhos personalizados em mapas de URL

Nesta página, descrevemos como os cabeçalhos personalizados funcionam em mapas de URL usados por balanceadores de carga de aplicativo externos regionais, balanceadores de carga de aplicativo internos regionais e balanceadores de carga de aplicativo internos entre regiões.

Os cabeçalhos de solicitação e resposta personalizados permitem especificar cabeçalhos adicionais que o balanceador de carga pode adicionar a solicitações e respostas HTTP(S). Dependendo das informações detectadas pelo balanceador de carga, esses cabeçalhos podem incluir as seguintes informações:

  • Latência para o cliente
  • Localização geográfica do endereço IP do cliente
  • Parâmetros da conexão TLS

Antes de começar

Se necessário, atualize para a versão mais recente da CLI do Google Cloud:

gcloud components update

Como os cabeçalhos personalizados funcionam

Os cabeçalhos personalizados funcionam da seguinte maneira:

  • Quando o balanceador de carga faz uma solicitação ao back-end, ele adiciona cabeçalhos de solicitação.

    O balanceador de carga adiciona cabeçalhos de solicitação personalizados apenas às solicitações do cliente, não às sondagens de verificação de integridade. Se o back-end exige um cabeçalho específico para autorização que esteja faltando no pacote de verificação de integridade, ele poderá falhar.

  • O balanceador de carga define os cabeçalhos de resposta antes de retornar uma resposta ao cliente.

Para ativar cabeçalhos personalizados em balanceadores de carga de aplicativo externos regionais, balanceadores de carga de aplicativo internos regionais e balanceadores de carga de aplicativo internos entre regiões, especifique uma lista de nomes e valores de cabeçalho no arquivo de configuração do mapa de URL.

Os nomes de cabeçalho precisam ter as seguintes propriedades:

  • O nome do cabeçalho precisa ser uma definição válida de nome de campo de cabeçalho HTTP de acordo com a RFC 7230.
  • O nome do cabeçalho não pode ser X-User-IP.
  • O nome do cabeçalho não pode começar com X-Google, X-Goog-, X-GFE ou X-Amz-.
  • O nome do cabeçalho não pode ser Host nem authority. Host e authority são palavras-chave especiais reservadas pelo Google Cloud. Não é possível modificar esses cabeçalhos para balanceadores de carga baseados no Envoy. Em vez disso, recomendamos que você crie outros cabeçalhos personalizados (por exemplo, MyHost) para que não interfira nos nomes de cabeçalho reservados.
  • Um nome de cabeçalho não pode aparecer mais de uma vez na lista de cabeçalhos.

Os nomes de cabeçalho não diferenciam maiúsculas de minúsculas. Quando os nomes de cabeçalho são passados para um back-end HTTP/2, o protocolo HTTP/2 os codifica como minúsculas.

Os valores do cabeçalho têm as seguintes propriedades:

  • O valor do cabeçalho precisa ser uma definição válida de campo de cabeçalho HTTP, segundo a RFC 7230, com formulários obsoletos não permitidos.
  • O valor do cabeçalho não pode ficar em branco. Cabeçalhos em branco são rejeitados.
  • O valor do cabeçalho pode incluir uma ou mais variáveis, delimitadas por chaves, que se expandem para valores fornecidos pelo balanceador de carga. Para ver uma lista completa de variáveis permitidas no valor do cabeçalho, consulte Variáveis que podem aparecer no valor do cabeçalho.

Nos valores de cabeçalho, os espaços em branco iniciais e finais são insignificantes e não são passados para o back-end. Para permitir chaves nos valores de cabeçalho, o balanceador de carga interpreta duas chaves de abertura ({{) como uma única chave de abertura ({) e duas chaves de fechamento (}}) como uma única chave de fechamento (}).

Adicionar cabeçalhos de solicitação ou resposta

Para adicionar cabeçalhos de solicitação ou resposta, use a CLI gcloud a fim de editar o mapa de URL da seguinte maneira:

regional

    gcloud compute url-maps edit URL_MAP_NAME \
        --region=REGION
    

Veja a seguir um exemplo de arquivo YAML que mostra como usar variáveis em cabeçalhos personalizados:

   defaultService: regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: regions/REGION/backendServices/BACKEND_SERVICE_1
               weight: 100
               headerAction:
                 requestHeadersToAdd:
                 - headerName: X-header-1-client-region
                   headerValue: "{client_region}"
                 - headerName: X-header-2-client-ip-port
                   headerValue: "{client_ip_address}, {client_port}"
                   replace: True
                 requesteHeadersToRemove:
                 - header-3-name
                 responseHeadersToAdd:
                 - headerName: X-header-4-server-ip-port
                   headerValue: "{server_ip_address}, {server_port}"
                   replace: True
                 responseHeadersToRemove:
                 - header-5-name
                 - header-6-name
    

Observe os seguintes comportamentos:

  • Se um cabeçalho de resposta com variáveis personalizadas for resolvido em uma string vazia, ele será removido.
  • Se um cabeçalho de solicitação com variáveis personalizadas é resolvido para uma string vazia, ele é mantido com um marcador de posição de string vazio.
  • Se um cabeçalho de solicitação personalizado incluir uma variável personalizada e uma solicitação de entrada do cliente também incluir o mesmo cabeçalho, o valor do cabeçalho da solicitação do cliente será substituído pelo novo valor fornecido pelo cabeçalho personalizado do balanceador de carga.

Variáveis que podem aparecer no valor do cabeçalho

As variáveis a seguir podem aparecer em valores de cabeçalho personalizados.

Variável Descrição
client_region O país (ou região) associado ao endereço IP do cliente. Esté é um código de região Unicode CLDR, como US ou FR. Na maioria dos países, esses códigos correspondem diretamente a códigos ISO-3166-2.
client_rtt_msec Tempo estimado de retorno para transmissão entre o balanceador de carga e o cliente HTTP(S), em milissegundos. É o parâmetro de tempo de retorno suavizado (SRTT, na sigla em inglês) medido pela pilha TCP do balanceador de carga, de acordo com a RFC 2988. O RTT suavizado é um algoritmo que lida com variações e anomalias que podem ocorrer em medições de RTT.
client_ip_address O endereço IP do cliente. Geralmente, ele é igual ao endereço IP do cliente que é o penúltimo endereço no cabeçalho X-Forwarded-For, a menos que o cliente esteja usando um proxy ou o cabeçalho X-Forwarded-For tenha sido adulterado.
client_port A porta de origem do cliente.
client_encrypted true se a conexão entre o cliente e o balanceador de carga for criptografada (usando HTTPS, HTTP/2 ou HTTP/3); Caso contrário, false.
client_protocol O protocolo HTTP usado para a comunicação entre o cliente e o balanceador de carga. Um de HTTP/1.0, HTTP/1.1, HTTP/2, ou HTTP/3.
origin_request_header Reflete o valor do cabeçalho Origin na solicitação de casos de uso de compartilhamento de recursos entre origens (CORS).
server_ip_address O endereço IP do balanceador de carga a que o cliente se conecta. Isso pode ser útil quando vários balanceadores de carga compartilham back-ends comuns. Este é o mesmo que o último endereço IP no cabeçalho X-Forwarded-For.
server_port O número da porta de destino à qual o cliente se conecta.
tls_sni_hostname Indicação do nome do servidor (conforme definido na RFC 6066, em inglês), caso ele seja fornecido pelo cliente durante o handshake do TLS ou do QUIC. O nome do host é convertido para letras minúsculas e qualquer ponto à direita é removido.
tls_version Versão de TLS negociada entre o cliente e o balanceador de carga durante o handshake de SSL. Os valores possíveis incluem TLSv1, TLSv1.1, TLSv1.2 e TLSv1.3. Se o cliente se conectar usando QUIC em vez de TLS, o valor será QUIC.
tls_cipher_suite Pacote de criptografia negociado durante o handshake de TLS. O valor corresponde a quatro dígitos hexadecimais definidos pelo Registro do pacote de criptografia TLS da IANA. Por exemplo, 009C para TLS_RSA_WITH_AES_128_GCM_SHA256. Este valor fica em branco para QUIC e conexões do cliente não criptografadas.
tls_ja3_fingerprint Impressão digital TLS/SSL JA3 se o cliente se conecta usando HTTPS, HTTP/2 ou HTTP/3.

O balanceador de carga expande variáveis para strings vazias quando não consegue determinar os valores delas. Por exemplo:

  • Variáveis de localização geográfica quando a localização do endereço IP é desconhecida
  • Parâmetros TLS quando o TLS não está em uso
  • O {origin_request_header} quando a solicitação não inclui um cabeçalho Origin

Os valores geográficos são estimativas com base no endereço IP do cliente. De tempos em tempos, o Google atualiza os dados que fornecem esses valores para melhorar a precisão e refletir as mudanças geográficas e políticas. Mesmo que o cabeçalho X-Forwarded-For original contenha informações de local válidas, o Google estima os locais do cliente usando as informações do endereço IP de origem contidas nos pacotes recebidos pelo balanceador de carga.

Cabeçalhos personalizados TLS mútuos

As seguintes variáveis de cabeçalho adicionais estarão disponíveis se o TLS mútuo (mTLS) estiver configurado no TargetHttpsProxy do balanceador de carga.

Variável Descrição
client_cert_present true se o cliente tiver fornecido um certificado durante o handshake de TLS. Caso contrário, false.
client_cert_chain_verified true se a cadeia de certificados do cliente for verificada em relação a um TrustStore configurado. Caso contrário, false.
client_cert_error Strings predefinidas que representam as condições de erro. Para mais informações sobre as strings de erro, consulte os modos de validação de cliente mTLS.
client_cert_sha256_fingerprint Impressão digital SHA-256 codificada em Base64 do certificado do cliente.
client_cert_serial_number O número de série do certificado do cliente. Se o número de série for maior que 50 bytes, a string client_cert_serial_number_exceeded_size_limit será adicionada como client_cert_error e o número de série será definido como uma string vazia.
client_cert_spiffe_id

O ID do SPIFFE no campo "Nome alternativo do assunto" (SAN, na sigla em inglês). Se o valor não for válido ou exceder 2.048 bytes, o ID do SPIFFE será definido como uma string vazia.

Se o ID SPIFFE tiver mais de 2.048 bytes, a string client_cert_spiffe_id_exceeded_size_limit será adicionada a client_cert_error.

client_cert_uri_sans

Lista codificada por Base64 separada por vírgula das extensões SAN do tipo URI. As extensões do SAN são extraídas do certificado do cliente. O ID do SPIFFE não está incluído no campo client_cert_uri_sans.

Se client_cert_uri_sans for maior que 512 bytes, client_cert_uri_sans_exceeded_size_limit será adicionada como client_cert_error e a lista separada por vírgulas será definida como uma string vazia.

client_cert_dnsname_sans

Lista codificada por Base64 separada por vírgula das extensões SAN do tipo DNSName. As extensões do SAN são extraídas do certificado do cliente.

Se client_cert_dnsname_sans for maior que 512 bytes, a string client_cert_dnsname_sans_exceeded_size_limit será adicionada como client_cert_error e a lista separada por vírgulas será definida como uma string vazia.

client_cert_valid_not_before Carimbo de data/hora (formato de string de data RFC 3339) antes do qual o certificado do cliente não é válido. Por exemplo, 2022-07-01T18:05:09+00:00.
client_cert_valid_not_after Carimbo de data/hora (formato de string de data RFC 3339) após o qual o certificado do cliente não é válido. Por exemplo, 2022-07-01T18:05:09+00:00.
client_cert_issuer_dn

Campo do emissor completo codificado em Base64 do certificado.

Se o client_cert_issuer_dn tiver mais de 512 bytes, a string client_cert_issuer_dn_exceeded_size_limit será adicionada a client_cert_error e client_cert_issuer_dn será definido como uma string vazia.

client_cert_subject_dn

Campo "Assunto" completo codificado em Base64 do certificado.

Se o client_cert_subject_dn tiver mais de 512 bytes, a string client_cert_subject_dn_exceeded_size_limit será adicionada a client_cert_error e client_cert_subject_dn será definida como uma string vazia.

client_cert_leaf

O certificado de folha de cliente para uma conexão mTLS estabelecida em que o certificado passou na validação. A codificação do certificado está em conformidade com asRFC 9440: o certificado DER binário é codificado usando Base64 (sem quebras de linha, espaços ou outros caracteres fora do alfabeto Base64) e delimitado por dois pontos em ambos os lados.

Se client_cert_leaf exceder 16 KB não codificados, a string client_cert_validated_leaf_exceeded_size_limit será adicionada a client_cert_error, e client_cert_leaf será definido como uma string vazia.

client_cert_chain

A lista de certificados delimitada por vírgulas, na ordem TLS padrão, da cadeia de certificados do cliente para uma conexão mTLS estabelecida em que o certificado do cliente passou na validação, sem incluir o certificado de folha. A codificação do certificado é compatível com a RFC 9440 (link em inglês).

Se o tamanho combinadoclient_cert_leaf e client_cert_chain antes que a codificação Base64 exceda 16 KB, a stringclient_cert_validated_chain_exceeded_size_limit foi adicionado aclient_cert_error eclient_cert_chain é definido como uma string vazia.

Limitações

A limitação a seguir se aplica aos cabeçalhos personalizados usados com balanceadores de carga regionais:

  • Não é possível configurar cabeçalhos personalizados em serviços de back-end regionais usados por balanceadores de carga de aplicativo externos regionais, balanceadores de carga de aplicativo internos regionais e serviços de back-end globais usados por balanceadores de carga de aplicativo internos entre regiões.
  • As variáveis de cabeçalho personalizadas a seguir não são compatíveis com balanceadores de carga de aplicativos externos regionais:
    • cdn_cache_id
    • cdn_cache_status
    • client_region_subdivision
    • client_city
    • client_city_lat_long