Configurar a segurança do serviço com o Envoy

Use as instruções deste guia para configurar a autenticação e autorização para serviços implantados com o Cloud Service Mesh e os proxies do Envoy. Para concluir informações sobre a segurança do serviço do Cloud Service Mesh, consulte Segurança do serviço do Cloud Service Mesh.

Requisitos

Antes de configurar a segurança do serviço do Cloud Service Mesh com o Envoy, verifique se a configuração atende aos seguintes pré-requisitos:

Preparar para a configuração

As seções a seguir descrevem as tarefas que você precisa concluir antes da configuração Serviço de segurança do Cloud Service Mesh. São elas:

  • Como atualizar a Google Cloud CLI
  • Como configurar variáveis
  • Como ativar as APIs necessárias para que o Cloud Service Mesh funcione com o Service Authority Service

Atualizar a ferramenta de linha de comando gcloud

Para atualizar a Google Cloud CLI, execute o seguinte comando na máquina local:

gcloud components update

Configurar variáveis

Defina as variáveis a seguir para que você possa copiar e colar o código com valores consistentes ao trabalhar no exemplo deste documento. Use os valores a seguir:

  • PROJECT_ID: substitui o ID do projeto.
  • CLUSTER_NAME: substitua o nome do cluster que você quer, por exemplo, secure-td-cluster.
  • ZONE: substitua a zona em que o cluster está localizado.
  • GKE_CLUSTER_URL: substitui https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
  • WORKLOAD_POOL: substitui PROJECT_ID.svc.id.goog
  • K8S_NAMESPACE: substitui default.
  • DEMO_CLIENT_KSA: substitua o nome da conta de serviço de cliente do Kubernetes.
  • DEMO_SERVER_KSA: substitua o nome da conta de serviço do Kubernetes do servidor.
  • PROJNUM: substitui o número do projeto, que você pode determinar no Console do Google Cloud ou com este comando:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"
    
  • SA_GKE: substitui service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

  • CLUSTER_VERSION: substitui a versão mais recente disponível. Você pode encontrar essa informação nas notas da versão do canal rápido. A versão mínima necessária é 1.21.4-gke.1801. Esta é a versão do cluster do GKE a ser usada neste exemplo.

Defina os valores aqui:

# Substitute your project ID
PROJECT_ID=PROJECT_ID

# GKE cluster name and zone for this example.
CLUSTER_NAME=CLUSTER_NAME
ZONE=ZONE

# GKE cluster URL derived from the above
GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME"

# Workload pool to be used with the GKE cluster
WORKLOAD_POOL="PROJECT_ID.svc.id.goog"

# Kubernetes namespace to run client and server demo.
K8S_NAMESPACE=K8S_NAMESPACE
DEMO_CLIENT_KSA=DEMO_CLIENT_KSA
DEMO_SERVER_KSA=DEMO_SERVER_KSA

# Compute other values
# Project number for your project
PROJNUM=PROJNUM

CLUSTER_VERSION=CLUSTER_VERSION
SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

Ative as APIs

Usar o gcloud services enable para ativar todas as APIs necessárias para configurar o Cloud Service Mesh com o Certificate Authority Service.

gcloud services enable \
   container.googleapis.com \
   cloudresourcemanager.googleapis.com \
   compute.googleapis.com \
   trafficdirector.googleapis.com \
   networkservices.googleapis.com \
   networksecurity.googleapis.com \
   privateca.googleapis.com \
   gkehub.googleapis.com

Criar ou atualizar um cluster do GKE

A segurança do serviço do Cloud Service Mesh depende do serviço da AC com o GKE. O cluster do GKE precisa atender aos seguintes requisitos, além dos requisitos de configuração:

  • Use uma versão de cluster mínima de 1.21.4-gke.1801. Se você precisar de recursos que estejam em uma versão posterior, poderá encontrá-la no canal de lançamento rápido.
  • O cluster do GKE precisa ser ativado e configurado com certificados de malha, conforme descrito em Como criar autoridades certificadoras para emitir certificados.
  1. Crie um cluster que use a federação de identidade da carga de trabalho para o GKE. Se você estiver atualizando um cluster existente, pule para a próxima etapa. O valor fornecido para --tags precisa corresponder ao nome transmitido à sinalização --target-tags para o comando firewall-rules create na seção Como configurar o Cloud Service Mesh com componentes do Cloud Load Balancing.

    # Create a GKE cluster with GKE managed mesh certificates.
    gcloud container clusters create CLUSTER_NAME \
      --release-channel=rapid \
      --scopes=cloud-platform \
      --image-type=cos_containerd \
      --machine-type=e2-standard-2 \
      --zone=ZONE \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --enable-mesh-certificates \
      --cluster-version=CLUSTER_VERSION \
      --enable-ip-alias \
      --tags=allow-health-checks \
      --workload-metadata=GKE_METADATA
    

    A criação do cluster pode levar vários minutos para ser concluída.

  2. Se você estiver usando um cluster atual, ative a federação de identidade da carga de trabalho para o GKE e Certificados de malha do GKE. Verifique se o cluster foi criado com a sinalização --enable-ip-alias, que não pode ser usada com o comando update.

    gcloud container clusters update CLUSTER_NAME \
      --enable-mesh-certificates
    
  3. Execute o comando a seguir para alternar para o novo cluster como o cluster padrão para os comandos kubectl:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --zone ZONE
    

Como implantar em um ambiente com vários clusters

Para implantar em um ambiente de vários clusters, siga o procedimento geral descrito nesta seção. Essas instruções presumem que os pods do cliente estejam em execução em um cluster e os pods de servidor estejam em execução no outro cluster.

  1. Crie ou atualize os clusters usando as instruções na seção anterior.

  2. Capture os intervalos de endereços IP do pod para cada cluster usando o seguinte comando:

    gcloud compute firewall-rules list \
      --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \
      --format="value(sourceRanges)"
    

    Por exemplo, para clusters chamados cluster-a e cluster-b, os comandos retornam resultados como os seguintes:

    cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node
    cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
    
  3. Crie regras de firewall da VPC que permitam que os clusters se comuniquem uns com os outros. Por exemplo, o comando a seguir cria uma regra de firewall que permite que os endereços IP do pod cluster-a se comuniquem com os nós cluster-b:

    gcloud compute firewall-rules create per-cluster-a-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-b-acd14479-node"
    

    O comando a seguir cria uma regra de firewall que permite que os endereços IP do pod cluster-b se comuniquem com nós cluster-a:

    gcloud compute firewall-rules create per-cluster-b-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-a-9cd18751-node"
    

Registrar clusters com uma frota

Registre o cluster que você criou ou atualizou em Como criar um cluster do GKE com uma frota. Registrar o cluster facilita a configuração de clusters em vários projetos.

Essas etapas podem levar até dez minutos para serem concluídas.

  1. Registre seu cluster na frota:

    gcloud container fleet memberships register CLUSTER_NAME \
      --gke-cluster=ZONE/CLUSTER_NAME \
      --enable-workload-identity --install-connect-agent \
      --manifest-output-file=MANIFEST-FILE_NAME
    

    Substitua as variáveis da seguinte maneira:

    • CLUSTER_NAME: o nome do cluster.
    • ZONE: a zona do cluster.
    • MANIFEST-FILE_NAME: o caminho em que esses comandos gerar o manifesto para registro.

    Quando o processo de registro for bem-sucedido, você verá uma mensagem como a seguinte:

    Finished registering the cluster CLUSTER_NAME with the fleet.
  2. Aplique o arquivo de manifesto gerado ao cluster:

    kubectl apply -f MANIFEST-FILE_NAME
    

    Quando o processo do aplicativo for bem-sucedido, você verá mensagens como estas:

    namespace/gke-connect created
    serviceaccount/connect-agent-sa created
    podsecuritypolicy.policy/gkeconnect-psp created
    role.rbac.authorization.k8s.io/gkeconnect-psp:role created
    rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created
    role.rbac.authorization.k8s.io/agent-updater created
    rolebinding.rbac.authorization.k8s.io/agent-updater created
    role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created
    rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    role.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    secret/http-proxy created
    deployment.apps/gke-connect-agent-20210416-01-00 created
    service/gke-connect-monitoring created
    secret/creds-gcp create
    
  3. Consiga o recurso de assinatura do cluster:

    kubectl get memberships membership -o yaml
    

    A saída precisa incluir o pool de identidade do Workoad atribuído pela frota, em que PROJECT_ID é o ID do projeto:

    workload_identity_pool: PROJECT_ID.svc.id.goog
    

    Isso significa que o cluster foi registrado com sucesso.

Criar autoridades certificadoras para emitir certificados

Para emitir certificados para os pods, crie um pool de serviço de CA e as seguintes autoridades certificadoras (CAs):

  • CA raiz. Essa é a raiz da confiança de todos os certificados de malha emitidos. Use uma CA raiz atual, se tiver uma. Crie a CA raiz no nível enterprise, que é destinado à emissão de certificados de longa duração e de baixo volume.
  • CA subordinada. Essa CA emite certificados para cargas de trabalho. Crie a CA subordinada na região em que o cluster está implantado. Crie a CA subordinada no nível devops, que se destina à emissão de certificados de curta duração e de grande volume.

Criar uma CA subordinada é opcional, mas é altamente recomendável criá-la em vez de usar a CA raiz para emitir certificados de malha do GKE. Se você decidir usar a CA raiz para emitir certificados de malha, verifique se o modo de emissão baseado em configuração padrão permanece permitido.

A CA subordinada pode estar em uma região diferente do cluster, mas é altamente recomendável criá-la na mesma região do cluster para otimizar o desempenho. No entanto, é possível criar as CAs raiz e subordinadas em diferentes regiões sem qualquer impacto no desempenho ou na disponibilidade.

Estas regiões são compatíveis com o serviço de CA:

Nome da região Descrição da região
asia-east1 Taiwan
asia-east2 Hong Kong
asia-northeast1 Tóquio
asia-northeast2 Osaka
asia-northeast3 Seul
asia-south1 Mumbai
asia-south2 Délhi
asia-southeast1 Singapura
asia-southeast2 Jacarta
australia-southeast1 Sydney
australia-southeast2 Melbourne
europe-central2 Varsóvia
europe-north1 Finlândia
europe-southwest1 Madri
europe-west1 Bélgica
europe-west2 Londres
europe-west3 Frankfurt
europe-west4 Países Baixos
europe-west6 Zurique
europe-west8 Milão
europe-west9 Paris
europe-west10 Berlim
europe-west12 Turim
me-central1 Doha
me-central2 Damã
me-west1 Tel Aviv
northamerica-northeast1 Montreal
northamerica-northeast2 Toronto
southamerica-east1 São Paulo
southamerica-west1 Santiago
us-central1 Iowa
us-east1 Carolina do Sul
us-east4 Norte da Virgínia
us-east5 Columbus
us-south1 Dallas
us-west1 Oregon
us-west2 Los Angeles
us-west3 Salt Lake City
us-west4 Las Vegas

A lista de locais compatíveis também pode ser verificada executando o seguinte comando:

gcloud privateca locations list
  1. Conceda o roles/privateca.caManager do IAM a indivíduos que criam um pool de CAs e uma CA. Para MEMBER, o formato correto é user:userid@example.com. Se essa pessoa for o usuário atual, é possível conseguir o ID do usuário atual com o comando shell $(gcloud auth list --filter=status:ACTIVE --format="value(account)").

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.caManager
    
  2. Conceda o papel role/privateca.admin para o serviço de CA a indivíduos que precisam modificar as políticas do IAM, em que MEMBER é um indivíduo que precisa desse acesso, especificamente, qualquer pessoa que execute as etapas abaixo. que concedem os papéis privateca.auditor e privateca.certificateManager:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.admin
    
  3. Crie o pool de serviço de CA raiz.

    gcloud privateca pools create ROOT_CA_POOL_NAME \
      --location ROOT_CA_POOL_LOCATION \
      --tier enterprise
    
  4. Crie uma CA raiz.

    gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \
      --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \
      --key-algorithm="ec-p256-sha256" \
      --max-chain-length=1 \
      --location ROOT_CA_POOL_LOCATION
    

    Para essa configuração de demonstração, use os seguintes valores para as variáveis:

    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_NAME=pkcs2-ca
    • ROOT_CA_POOL_LOCATION=us-east1
    • ROOT_CA_ORGANIZATION="TestCorpLLC"
  5. Crie o pool subordinado e a CA subordinada. Verifique se o modo de emissão baseado em configuração padrão permanece permitido.

    gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --tier devops
    
    gcloud privateca subordinates create SUBORDINATE_CA_NAME \
      --pool SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --issuer-pool ROOT_CA_POOL_NAME \
      --issuer-location ROOT_CA_POOL_LOCATION \
      --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \
      --key-algorithm "ec-p256-sha256" \
      --use-preset-profile subordinate_mtls_pathlen_0
    

    Para essa configuração de demonstração, use os seguintes valores para as variáveis:

    • SUBORDINATE_CA_POOL_NAME="td-ca-pool"
    • SUBORDINATE_CA_POOL_LOCATION=us-east1
    • SUBORDINATE_CA_NAME="td-ca"
    • SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_POOL_LOCATION=us-east1
  6. Conceda o papel privateca.auditor do IAM para a CA raiz para permitir o acesso da conta de serviço do GKE:

    gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \
     --location ROOT_CA_POOL_LOCATION \
     --role roles/privateca.auditor \
     --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  7. Conceda o papel privateca.certificateManager do IAM para o pool da CA subordinado para permitir o acesso pela conta de serviço do GKE:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --role roles/privateca.certificateManager \
      --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  8. Salve a seguinte configuração YAML WorkloadCertificateConfig para informar ao cluster como emitir certificados de malha:

    apiVersion: security.cloud.google.com/v1
    kind: WorkloadCertificateConfig
    metadata:
      name: default
    spec:
      # Required. The CA service that issues your certificates.
      certificateAuthorityConfig:
        certificateAuthorityServiceConfig:
          endpointURI: ISSUING_CA_POOL_URI
    
      # Required. The key algorithm to use. Choice of RSA or ECDSA.
      #
      # To maximize compatibility with various TLS stacks, your workloads
      # should use keys of the same family as your root and subordinate CAs.
      #
      # To use RSA, specify configuration such as:
      #   keyAlgorithm:
      #     rsa:
      #       modulusSize: 4096
      #
      # Currently, the only supported ECDSA curves are "P256" and "P384", and the only
      # supported RSA modulus sizes are 2048, 3072 and 4096.
      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
      # Optional. Validity duration of issued certificates, in seconds.
      #
      # Defaults to 86400 (1 day) if not specified.
      validityDurationSeconds: 86400
    
      # Optional. Try to start rotating the certificate once this
      # percentage of validityDurationSeconds is remaining.
      #
      # Defaults to 50 if not specified.
      rotationWindowPercentage: 50
    
    

    Substitua:

    • O ID do projeto em que o cluster é executado:
      PROJECT_ID
    • O URI totalmente qualificado da CA que emite os certificados de malha (ISSUING_CA_POOL_URI). Pode ser a CA subordinada (recomendado) ou a CA raiz. O formato é:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
  9. Salve a seguinte configuração YAML TrustConfig para informar ao cluster como confiar nos certificados emitidos:

    apiVersion: security.cloud.google.com/v1
    kind: TrustConfig
    metadata:
      name: default
    spec:
      # You must include a trustStores entry for the trust domain that
      # your cluster is enrolled in.
      trustStores:
      - trustDomain: PROJECT_ID.svc.id.goog
        # Trust identities in this trustDomain if they appear in a certificate
        # that chains up to this root CA.
        trustAnchors:
        - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
    

    Substitua:

    • O ID do projeto em que o cluster é executado:
      PROJECT_ID
    • O URI totalmente qualificado do pool de CA raiz (ROOT_CA_POOL_URI). O formato é:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
  10. Aplique as configurações ao cluster:

    kubectl apply -f WorkloadCertificateConfig.yaml
    kubectl apply -f TrustConfig.yaml
    

Configurar o gerenciamento de identidade e acesso

Para criar os recursos necessários à configuração, você precisa ter o papel compute.NetworkAdmin. Esse papel contém todas as permissões necessárias para criar, atualizar, excluir, listar e usar (ou seja, mencionar isso em outros recursos) os recursos necessários. Se você for o editor-proprietário do projeto, terá esse papel automaticamente.

networksecurity.googleapis.com.clientTlsPolicies.use e networksecurity.googleapis.com.serverTlsPolicies.use não são aplicados quando você faz referência a esses recursos no serviço de back-end.

Se essas permissões forem aplicadas no futuro e você estiver usando o função compute.NetworkAdmin, não haverá problemas quando essa verificação é aplicada.

Se você estiver usando papéis personalizados e essa verificação for aplicada no futuro, certifique-se de incluir a respectiva permissão .use. Caso contrário, no futuro, você verá que o papel personalizado não tem as permissões necessárias para se referir a clientTlsPolicy ou serverTlsPolicy pelo serviço de back-end ou pela política de endpoint.

As instruções a seguir permitem que a conta de serviço padrão acesse a API Cloud Service Mesh Security e crie as contas de serviço do Kubernetes.

  1. Configurar o IAM para permitir que a conta de serviço padrão acesse a API de segurança do Cloud Service Mesh.

    GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
       --filter='displayName:Compute Engine default service account')
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:${GSA_EMAIL} \
      --role roles/trafficdirector.client
    
  2. Configure contas de serviço do Kubernetes. As implantações de cliente e servidor nas seções a seguir usam os nomes do servidor do Kubernetes e as contas de serviço do cliente.

    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA
    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
    
  3. Permita que as contas de serviço do Kubernetes personifiquem a conta de serviço padrão do Compute Engine criando uma vinculação de política do IAM entre as duas. Essa vinculação permite que a conta de serviço do Kubernetes atue como a conta de serviço padrão do Compute Engine.

    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL}
    
    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser  \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
    
  4. Anotar as contas de serviço do Kubernetes para associá-las ao do Compute Engine.

    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_SERVER_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    
    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_CLIENT_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    

Configurar o Cloud Service Mesh

Use as instruções a seguir para instalar o injetor do sidecar, configurar um serviço de teste e concluir outras tarefas de implantação.

Instalar o injetor do sidecar do Envoy no cluster

Use as instruções nas duas seções a seguir da configuração do Cloud Service Mesh para pods do GKE com a injeção automática do Envoy para implantar e ativar a injeção de arquivo secundário do Envoy no cluster:

Conclua os dois conjuntos de instruções antes de configurar um serviço de teste.

Configurar um serviço de teste

Depois de instalar o injetor do sidecar do Envoy, use estas instruções para configurar um serviço de teste para sua implantação.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml

kubectl apply -f service_sample.yaml

O arquivo service_sample.yaml contém o podspec para o aplicativo do servidor de demonstração. Há algumas anotações específicas para a segurança do Cloud Service Mesh.

Metadados de proxy do Cloud Service Mesh

O podspec especifica a anotação proxyMetadata:

spec:
...
      annotations:
        cloud.google.com/proxyMetadata: '{"app": "payments"}'
...

Quando o pod é inicializado, o proxy sidecar seleciona essa anotação e o transmite para o Cloud Service Mesh. O Cloud Service Mesh pode usar essas informações para enviar a configuração filtrada:

  • Mais adiante neste guia, a política de endpoint especifica uma correspondência de endpoint.
  • O correspondente de endpoint especifica que apenas os clientes que apresentam um rótulo com nome app e valor payments recebem a configuração filtrada.

Usar certificados e chaves de malha assinados pelo serviço CA;

O podspec especifica a anotação enableManagedCerts:

spec:
...
      annotations:
        ...
        cloud.google.com/enableManagedCerts: "true"
...

Quando o pod é inicializado, o serviço de CA assina certificados e as chaves são automaticamente montadas no sistema de arquivos do proxy secundário local.

Como configurar a porta de interceptação do tráfego de entrada

O podspec especifica a anotação em includeInboundPorts:

spec:
...
      annotations:
        ...
        cloud.google.com/includeInboundPorts: "8000"
...

Essa é a porta em que o aplicativo do servidor escuta conexões. Quando o pod é inicializado, o proxy sidecar coleta essa anotação e a transmite para o Cloud Service Mesh. O Cloud Service Mesh pode usar essas informações para retornar a configuração filtrada, que intercepta todo o tráfego de entrada para essa porta e pode aplicar políticas de segurança a ela.

A porta de verificação de integridade precisa ser diferente da porta do aplicativo. Caso contrário, as mesmas políticas de segurança serão aplicadas a conexões de entrada com a porta de verificação de integridade, o que pode fazer com que as conexões sejam recusadas e isso faz com que o servidor seja marcado incorretamente como não íntegro.

Configurar serviços do GKE com NEGs

Os serviços do GKE precisam ser expostos por grupos de endpoints de rede (NEGs) para que você possa configurá-los como back-ends de um back-end do Cloud Service Mesh serviço. O pacote service_sample.yaml fornecido com este guia de configuração usa o nome do NEG service-test-neg na seguinte anotação:

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

Não é necessário mudar o arquivo service_sample.yaml.

Salvar o nome do NEG

Salve o nome do NEG na variável NEG_NAME:

NEG_NAME="service-test-neg"

Implantar um aplicativo cliente no GKE

Execute o comando a seguir para iniciar um cliente de demonstração com um proxy Envoy como um arquivo secundário, que é necessário para demonstrar os recursos de segurança.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml

kubectl apply -f client_sample.yaml

A podspec do cliente inclui apenas a anotação enableManagedCerts. Isso é necessário para ativar os volumes necessários dos certificados e chaves de malha gerenciados do GKE assinados pela instância de serviço de CA.

Configurar verificação de integridade, regra de firewall e recursos de serviço de back-end

Nesta seção, você cria a verificação de integridade, a regra de firewall e os recursos de serviço de back-end do Cloud Service Mesh.

  1. Crie a verificação de integridade.

    gcloud compute health-checks create http td-gke-health-check \
      --use-serving-port
    
  2. Crie a regra de firewall para permitir os intervalos de endereços IP do verificador de integridade.

    gcloud compute firewall-rules create fw-allow-health-checks \
       --action ALLOW \
       --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --rules tcp
    
  3. Crie o serviço de back-end e associe a verificação de integridade a ele.

    gcloud compute backend-services create td-gke-service \
      --global \
      --health-checks td-gke-health-check \
      --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  4. Adicione o NEG criado anteriormente como um back-end ao serviço de back-end.

    gcloud compute backend-services add-backend td-gke-service \
      --global \
      --network-endpoint-group ${NEG_NAME} \
      --network-endpoint-group-zone ZONE \
      --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

Configurar os recursos Mesh e HTTPRoute.

Nesta seção, você criará os recursos Mesh e HTTPRoute.

  1. Crie a especificação do recurso Mesh e salve-a em um arquivo chamado mesh.yaml.

    name: sidecar-mesh
    interceptionPort: 15001
    

    O padrão da porta de interceptação será 15001 se você não especificá-la no arquivo mesh.yaml.

  2. Crie o recurso Mesh usando a especificação mesh.yaml.

    gcloud network-services meshes import sidecar-mesh \
      --source=mesh.yaml \
      --location=global
    
  3. Crie a especificação HTTPRoute e salve-a em um arquivo chamado http_route.yaml.

    É possível usar PROJECT_ID ou PROJECT_NUMBER.

    name: helloworld-http-route
    hostnames:
    - service-test
    meshes:
    - projects/PROJNUM/locations/global/meshes/sidecar-mesh
    rules:
    - action:
       destinations:
       - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
    
  4. Crie o recurso HTTPRoute usando a especificação no arquivo http_route.yaml.

    gcloud network-services http-routes import helloworld-http-route \
      --source=http_route.yaml \
      --location=global
    

A configuração do Cloud Service Mesh foi concluída e já pode ser definido e políticas de autenticação e autorização.

Configurar a segurança serviço a serviço

Siga as instruções nas seções a seguir para configurar a segurança de serviço a serviço.

Ativar mTLS na malha

Para configurar o mTLS na malha, é preciso proteger o tráfego de saída ao serviço de back-end e proteger o tráfego de entrada para o endpoint.

Formato para referências de políticas

Observe o seguinte formato obrigatório para se referir ao TLS do servidor, ao TLS de cliente e às políticas de autorização:

projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]

Exemplo:

projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy

Como proteger o tráfego de saída para o serviço de back-end

Para proteger o tráfego de saída, crie primeiro uma política de cliente de TLS que faça o seguinte:

  • Usa google_cloud_private_spiffe como o plug-in para clientCertificate, que programa o Envoy para usar certificados de malha gerenciados do GKE como a identidade do cliente.
  • Usa google_cloud_private_spiffe como o plug-in para serverValidationCa, que programa o Envoy para usar certificados de malha gerenciados do GKE para validação do servidor.

Em seguida, anexe a política de TLS do cliente ao serviço de back-end. Essa ação faz o seguinte:

  • Aplica a política de autenticação da política de TLS do cliente às conexões de saída para os endpoints do serviço de back-end.
  • O SAN (Subject Alternative Names) instrui o cliente a declarar a identidade exata do servidor ao qual ele está se conectando.
  1. Crie a política de TLS do cliente em um arquivo client-mtls-policy.yaml:

    name: "client-mtls-policy"
    clientCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importe a política de TLS do cliente:

    gcloud network-security client-tls-policies import client-mtls-policy \
        --source=client-mtls-policy.yaml --location=global
    
  3. Anexe a política de TLS do cliente ao serviço de back-end. Isso impõe a autenticação mTLS em todas as solicitações de saída do cliente para este serviço de back-end.

    gcloud compute backend-services export td-gke-service \
        --global --destination=demo-backend-service.yaml
    

    Anexe as seguintes linhas ao demo-backend-service.yaml:

    securitySettings:
      clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
      subjectAltNames:
        - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
    
  4. Importe os valores:

    gcloud compute backend-services import td-gke-service \
        --global --source=demo-backend-service.yaml
    
  5. Como opção, execute o seguinte comando para verificar se a solicitação falhou. Essa é uma falha esperada, porque o cliente espera certificados do endpoint, mas o endpoint não é programado com uma política de segurança.

    # Get the name of the Podrunning Busybox.
    BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # Command to execute that tests connectivity to the service service-test.
    TEST_CMD="wget -q -O - service-test; echo"
    
    # Execute the test command on the pod.
    kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
    

    Você vê uma saída como esta:

    wget: server returned error: HTTP/1.1 503 Service Unavailable
    

Proteger o tráfego de entrada para o endpoint

Para proteger o tráfego de entrada, primeiro crie uma política de TLS de servidor que:

  • Usa google_cloud_private_spiffe como o plug-in para serverCertificate, que programa o Envoy para usar certificados de malha gerenciados do GKE como a identidade do servidor.
  • Usa google_cloud_private_spiffe como o plug-in para clientValidationCa, que programa o Envoy para usar certificados de malha gerenciados do GKE para validação do cliente.
  1. Salve os valores da política de TLS do servidor em um arquivo chamado server-mtls-policy.yaml.

    name: "server-mtls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    mtlsPolicy:
      clientValidationCa:
      - certificateProviderInstance:
          pluginInstance: google_cloud_private_spiffe
    
  2. Crie a política de TLS do servidor:

    gcloud network-security server-tls-policies import server-mtls-policy \
        --source=server-mtls-policy.yaml --location=global
    
  3. Crie um arquivo chamado ep_mtls.yaml que contenha o correspondente de endpoint e anexe a política de TLS do servidor.

    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: MATCH_ALL
        metadataLabels:
        - labelName: app
          labelValue: payments
    name: "ep"
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy
    type: SIDECAR_PROXY
    
  4. Importar a correspondência de endpoints.

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Validar a configuração

Execute o comando curl. Se a solicitação for concluída com êxito, você verá x-forwarded-client-cert na saída. O cabeçalho é impresso apenas quando a conexão é mTLS.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

Você verá uma saída como esta:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: 10.48.0.6
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Observe que o cabeçalho x-forwarded-client-cert é inserido pelo Envoy do servidor e contém sua própria identidade (servidor) e a identidade do cliente de origem. Como vemos as identidades do cliente e do servidor, isso é um sinal de uma conexão mTLS.

Configurar o acesso no nível do serviço com uma política de autorização

Estas instruções criam uma política de autorização que permite solicitações enviadas pela conta DEMO_CLIENT_KSA em que o nome do host é service-test, a porta é 8000 e o método HTTP é GET: Antes de criar políticas de autorização, leia com cuidado em Restringir o acesso usando autorização.

  1. Crie uma política de autorização criando um arquivo chamado authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        ports:
        - 8000
        methods:
        - GET
    
  2. Importe a política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    
  3. Atualize a política do endpoint para fazer referência à nova política de autorização anexando o seguinte ao arquivo ep_mtls.yaml:

    authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
    

    A política de endpoint agora especifica que o mTLS e a política de autorização precisam ser aplicadas a solicitações de entrada para pods cujos proxies secundários do Envoy apresentam o rótulo app:payments.

  4. Importe a política:

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Validar a configuração

Execute os seguintes comandos para validar a configuração.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

A resposta esperada é semelhante a esta:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: redacted
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Execute os seguintes comandos para testar se a política de autorização está recusando corretamente as solicitações inválidas:

# Failure case
# Command to execute that tests connectivity to the service service-test.
# This is an invalid request and server will reject because the server
# authorization policy only allows GET requests.
TEST_CMD="wget -q -O - service-test --post-data='' ; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

A resposta esperada é semelhante a esta:

<RBAC: access denied HTTP/1.1 403 Forbidden>

Configurar políticas de autorização em arquivos secundários no GKE

Esta seção mostra como configurar diferentes tipos de políticas de autorização em sidecars do Cloud Service Mesh no GKE.

Antes de criar uma política de autorização, é necessário instalar a CustomResourceDefinition (CRD) GCPAuthzPolicy:

curl https://github.com/GoogleCloudPlatform/gke-networking-recipes/blob/main/gateway-api/config/mesh/crd/experimental/gcpauthzpolicy.yaml \
| kubectl apply -f -

Política de autorização para negar solicitações

Quando uma carga de trabalho precisa fazer apenas chamadas de saída, como cron job, é possível configurar uma política de autorização para negar qualquer entrada HTTP solicitações para a carga de trabalho. O exemplo a seguir nega solicitações HTTP recebidas para a carga de trabalho example-app.

Siga estas etapas para criar e aplicar a política de autorização de negação:

  1. Para criar uma política personalizada, crie um arquivo chamado deny-all-authz-policy.yaml:

    cat >deny-all-authz-policy.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: my-workload-authz
      namespace: ns1
    spec:
    targetRefs:
    - kind: Deployment
      name: example-app
    httpRules:
    - to:
        operations:
        - paths:
          - type: Prefix
            value: "/"
    action: DENY
    EOF
    
  2. Aplique a política:

    kubectl apply -f deny-all-authz-policy.yaml
    

Política de autorização para permitir solicitações

Também é possível configurar uma política de permissão que permita somente solicitações que correspondam a uma critérios específicos, rejeitando o restante. O exemplo a seguir configura uma política de autorização na implantação example-app para permitir apenas solicitações mTLS de pods com a identidade spiffee://cluster.local/ns1/pod1.

Siga estas etapas para criar e aplicar a política de autorização de permissão:

  1. Crie uma política personalizada criando um arquivo chamado allow-authz-policy.yaml:

    cat >allow-authz-policy.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: my-workload-authz
      namespace: ns1
    spec:
    targetRefs:
    - kind: Deployment
      name: example-app
    httpRules:
    - from:
        sources:
        - principals:
          - type: Exact
            value: "spiffee://cluster.local/ns1/pod1"
    action: ALLOW
    EOF
    
  2. Aplique a política:

    kubectl apply -f allow-authz-policy.yaml
    

Configurar a segurança do gateway de entrada

Nesta seção, supomos que você tenha concluído a seção de segurança de serviço a serviço, incluindo a configuração do cluster do GKE com o injetor de arquivo secundário, criando uma autoridade de certificação e criando uma política de endpoint.

Nesta seção, você implantará um proxy Envoy como um gateway de entrada que encerra as conexões TLS e autoriza solicitações de clientes internos de um cluster.

Como encerrar o TLS em um gateway de entrada (clique para ampliar)
Como encerrar o TLS em um gateway de entrada (clique para ampliar)

Para configurar um gateway de entrada para encerrar o TLS, faça o seguinte:

  1. Implantar um serviço do Kubernetes acessível por meio de um endereço IP interno do cluster.
    1. A implantação consiste em um proxy Envoy autônomo que é exposto como um Kubernetes e se conecta ao Cloud Service Mesh.
  2. Crie uma política de TLS do servidor para encerrar o TLS.
  3. Crie uma política de autorização para autorizar solicitações recebidas.

Implantar um serviço de gateway de entrada no GKE

Execute o seguinte comando para implantar o serviço de gateway de entrada no GKE:

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml

kubectl apply -f gateway_sample.yaml

O arquivo gateway_sample.yaml é a especificação para o gateway de entrada. As seções a seguir descrevem algumas adições à especificação.

Como desativar a injeção de sidecar do Cloud Service Mesh

A especificação gateway_sample.yaml implanta um proxy Envoy como o único contêiner. Nas etapas anteriores, o Envoy foi injetado como um sidecar em um contêiner de aplicativo. Para evitar que vários Envoys processem solicitações, desative a injeção de sidecar neste serviço do Kubernetes usando a instrução a seguir:

sidecar.istio.io/inject: "false"

Montar o volume correto

A especificação gateway_sample.yaml ativa o volume gke-workload-certificates. Esse volume também é usado na implantação do sidecar, mas ele é adicionado automaticamente pelo injetor do sidecar quando ele vê a anotação cloud.google.com/enableManagedCerts: "true". O volume gke-workload-certificates contém os certificados SPIFFE gerenciados pelo GKE e as chaves assinados pela instância do serviço de CA que você configurou.

Configurar o endereço IP interno do cluster

Configure o gateway de entrada com um serviço do tipo ClusterInternal. Isso cria um nome de host DNS com resolução interna para mesh-gateway. Quando um cliente envia uma solicitação para mesh-gateway:443, o Kubernetes encaminha imediatamente a solicitação para a porta de implantação do Envoy do gateway de entrada 8080.

Ativar o TLS em um gateway de entrada

Use estas instruções para ativar o TLS em um gateway de entrada.

  1. Crie um recurso de política de TLS do servidor para encerrar conexões TLS com os valores em um arquivo chamado server-tls-policy.yaml:

    description: tls server policy
    name: server-tls-policy
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importe a política de TLS do servidor:

    gcloud network-security server-tls-policies import server-tls-policy \
        --source=server-tls-policy.yaml --location=global
    
  3. Crie um novo destino Gateway e salve-o no arquivo td-gke-gateway.yaml. Isso anexa a política de TLS do servidor e configura o gateway de entrada do proxy do Envoy para encerrar o tráfego TLS de entrada.

    name: td-gke-gateway
    scope: gateway-proxy
    ports:
    - 8080
    type: OPEN_MESH
    serverTLSPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
    
  4. Importe o gateway:

    gcloud network-services gateways import td-gke-gateway \
      --source=td-gke-gateway.yaml \
      --location=global
    
  5. Crie e salve um novo HTTPRoute chamado td-gke-route, que referencia o gateway e encaminha todas as solicitações para td-gke-service.

    name: td-gke-route
    hostnames:
    - mesh-gateway
    gateways:
    - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway
    rules:
    - action:
        destinations:
        - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"
    
  6. Importe o HTTPRoute.

    gcloud network-services httproutes import td-gke-route \
      --source=td-gke-route.yaml \
      --location=global
    
    
  7. Se quiser, atualize a política de autorização nos back-ends para permitir solicitações quando todas as condições a seguir forem atendidas:

    • Solicitações enviadas por DEMO_CLIENT_KSA. A implantação do gateway de entrada usa a conta de serviço DEMO_CLIENT_KSA.
    • Solicitações com o host mesh-gateway ou service-test
    • Porta: 8000

    Não é necessário executar esses comandos, a menos que você tenha configurado uma para seus back-ends. Se não houver política de autorização no endpoint ou não contiver correspondência principal de host ou de origem na política de autorização, a solicitação será permitida sem esta etapa. Adicione esses valores a authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        - mesh-gateway
        ports:
        - 8000
        methods:
        - GET
    
  8. Importe a política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    

Valide a implantação do gateway de entrada

Você usa um novo contêiner chamado debug para enviar solicitações ao gateway de entrada para validar a implantação.

Na especificação a seguir, a anotação "sidecar.istio.io/inject":"false" impede que o injetor de sidecar do Cloud Service Mesh injete automaticamente um proxy sidecar. Não há arquivos secundários para ajudar o contêiner debug no roteamento de solicitação. O contêiner precisa se conectar ao gateway de entrada para roteamento.

A especificação inclui a sinalização --no-check-certificate, que ignora a validação do certificado do servidor. O contêiner debug não tem os certificados de validação da autoridade de certificação necessários para os certificados válidos assinados pelo serviço de CA que são usados pelo gateway de entrada para encerrar o TLS.

Em um ambiente de produção, recomendamos que você faça o download do certificado de validação do serviço de CA e ative-o ou instale-o no cliente. Depois de instalar o certificado de validação, remova a opção --no-check-certificate do comando wget.

Execute este comando:

kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"

Você vê uma saída semelhante a esta:

GET / HTTP/1.1
Host: 10.68.7.132
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-envoy-expected-rq-timeout-ms: 15000
x-envoy-internal: true
x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef
x-forwarded-for: 10.64.0.53
x-forwarded-proto: https
content-length: 0
user-agent: Wget

Execute o comando de teste negativo a seguir:

# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"

Você verá uma saída semelhante a esta

wget: error getting response: Connection reset by peer

Execute o comando de teste negativo a seguir:

# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"

Você verá uma saída semelhante a esta:

HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden

Exclua a implantação

Como opção, é possível executar esses comandos para excluir a implantação criada usando este guia.

Para excluir o cluster, execute este comando:

gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet

Para excluir os recursos criados, execute estes comandos:

gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
    --location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
   --location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
    --location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
    --location=global --quiet

Limitações

A segurança do serviço do Cloud Service Mesh é compatível apenas com o GKE. Não é possível implantar a segurança do serviço com o Compute Engine.

Solução de problemas

Nesta seção, você verá como corrigir problemas encontrados durante a configuração do serviço de segurança.

Falhas de conexão

Se a conexão falhar com um erro upstream connect ou disconnect/reset before headers, examine os registros do Envoy, onde é possível ver uma das seguintes mensagens de registro:

gRPC config stream closed: 5, Requested entity was not found

gRPC config stream closed: 2, no credential token is found

Se você vir esses erros no registro do Envoy, é provável que o token da conta de serviço esteja ativado de forma incorreta, esteja usando um audience diferente ou ambos.

Para mais informações, consulte Mensagens de erro nos registros do Envoy indicam um problema de configuração.

Pods não criados

Para solucionar esse problema, consulte Como solucionar problemas de implantações automáticas de pods do GKE.

O Envoy não se autentica com o Cloud Service Mesh

Quando o Envoy (envoy-proxy) se conecta ao Cloud Service Mesh para buscar o xDS ele usa a federação de identidade da carga de trabalho para o GKE e a VM do Compute Engine conta de serviço padrão (a menos que o bootstrap tenha sido alterado). Se a autenticação falhar, o Envoy não entrará no estado pronto.

Não foi possível criar um cluster com --workload-identity-certificate-authority flag

Se você vir esse erro, verifique se está executando a versão mais recente da Google Cloud CLI:

gcloud components update

Os pods permanecem em estado pendente

Se os pods permanecerem em estado pendente durante o processo de configuração, aumente os recursos de CPU e memória para os pods na especificação de implantação.

Não foi possível criar um cluster com a sinalização --enable-mesh-certificates

Verifique se você está executando a versão mais recente da CLI gcloud:

gcloud components update

A sinalização --enable-mesh-certificates funciona apenas com gcloud beta.

Os pods não são iniciados

Os pods que usam certificados de malha do GKE poderão falhar ao iniciar se o provisionamento de certificados estiver falhando. Isso pode acontecer quando:

  • A WorkloadCertificateConfig ou TrustConfig estiver configurada incorretamente ou ausente.
  • As CSRs não forem aprovadas.

Verifique se o provisionamento de certificados está falhando verificando os eventos do pod.

  1. Verifique o status do pod:

    kubectl get pod -n POD_NAMESPACE POD_NAME
    

    Substitua:

    • POD_NAMESPACE: o namespace do pod.
    • POD_NAME: o nome do pod.
  2. Verifique os eventos recentes do pod:

    kubectl describe pod -n POD_NAMESPACE POD_NAME
    
  3. Se o provisionamento de certificados estiver falhando, você verá um evento com Type=Warning, Reason=FailedMount, From=kubelet e um campo Message que começa com MountVolume.SetUp failed for volume "gke-workload-certificates". O campo Message contém informações de solução de problemas.

    Events:
      Type     Reason       Age                From       Message
      ----     ------       ----               ----       -------
      Warning  FailedMount  13s (x7 over 46s)  kubelet    MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
    
  4. Veja as etapas de solução de problemas a seguir se o pod não iniciar por causa de objetos configurados incorretamente ou devido a CSRs recusadas.

WorkloadCertificateConfig ou TrustConfig está configurada incorretamente

Verifique se você criou os objetos WorkloadCertificateConfig e TrustConfig corretamente. É possível diagnosticar configurações incorretas em um desses objetos usando kubectl.

  1. Recupere o status atual.

    Para obter WorkloadCertificateConfig:

    kubectl get WorkloadCertificateConfig default -o yaml
    

    Para obter TrustConfig:

    kubectl get TrustConfig default -o yaml
    
  2. Inspecione a saída do status. Um objeto válido terá uma condição com type: Ready e status: "True".

    status:
      conditions:
      - lastTransitionTime: "2021-03-04T22:24:11Z"
        message: WorkloadCertificateConfig is ready
        observedGeneration: 1
        reason: ConfigReady
        status: "True"
        type: Ready
    

    Para objetos inválidos, status: "False" será exibido. Os campos reason e message apresentam mais detalhes sobre a solução de problemas.

As CSRs não foram aprovadas

Se algo der errado durante o processo de aprovação da CSR, verifique os detalhes do erro nas condições type: Approved e type: Issued da CSR.

  1. Liste CSRs relevantes usando kubectl:

    kubectl get csr \
      --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
    
  2. Escolha uma CSR que seja Approved e não Issued ou que não seja Approved.

  3. Veja detalhes sobre a CSR selecionada usando o kubectl:

    kubectl get csr CSR_NAME -o yaml
    

    Substitua CSR_NAME pelo nome da CSR escolhida.

Uma CSR válida tem uma condição com type: Approved e status: "True" e um certificado válido no campo status.certificate:

status:
  certificate: <base64-encoded data>
  conditions:
  - lastTransitionTime: "2021-03-04T21:58:46Z"
    lastUpdateTime: "2021-03-04T21:58:46Z"
    message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
    reason: AutoApproved
    status: "True"
    type: Approved

As informações sobre solução de problemas para CSRs inválidos aparecem nos campos message e reason.

Os aplicativos não podem usar as credenciais mTLS emitidas

  1. Verifique se o certificado expirou:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  2. Verifique se o tipo de chave que você usou é compatível com o aplicativo.

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
    
  3. Verifique se a CA emissora usa a mesma família de chaves que a chave de certificado.

    1. Veja o status da instância do serviço de CA (Visualização):

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Substitua:

      • ISSUING_CA_TYPE: o tipo de CA emissora, que precisa ser subordinates ou roots.
      • ISSUING_CA_NAME: o nome da CA emissora.
      • ISSUING_CA_LOCATION: a região da CA emissora.
    2. Verifique se o keySpec.algorithm na saída é o mesmo algoritmo de chave definido no manifesto YAML WorkloadCertificateConfig. A saída é assim:

      config:
        ...
        subjectConfig:
          commonName: td-sub-ca
          subject:
            organization: TestOrgLLC
          subjectAltName: {}
      createTime: '2021-05-04T05:37:58.329293525Z'
      issuingOptions:
        includeCaCertUrl: true
      keySpec:
        algorithm: RSA_PKCS1_2048_SHA256
       ...
      

Os certificados são recusados

  1. Verifique se o aplicativo de peering usa o mesmo pacote de confiança para verificar o certificado.
  2. Verifique se o certificado expirou:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  3. Verifique se o código do cliente, se não estiver usando a API Reload Credentials do gRPC Go, atualiza periodicamente as credenciais do sistema de arquivos.

  4. Verifique se as cargas de trabalho estão no mesmo domínio de confiança que a CA. Os certificados de malha do GKE suportam a comunicação entre as cargas de trabalho em um único domínio de confiança.