Esta página explica como proteger um gateway usando vários recursos de segurança:
Políticas de SSL para garantir que o gateway use os protocolos e algoritmos seguros necessários
Certificados para proteger o tráfego de cliente para gateway e de gateway para back-ends com TLS
Política de segurança do Google Cloud Armor para proteger os Serviços contra ataques DDoS
- Identity-Aware Proxy (IAP) para fornecer uma camada de autenticação e autorização antes de permitir o acesso a um serviço
Para saber mais sobre segurança de gateway, consulte Segurança de gateway.
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Ativar a API Google Kubernetes Engine. Ativar a API Google Kubernetes Engine
- Se você quiser usar a Google Cloud CLI para essa tarefa,
instale e, em seguida,
inicialize a
CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão
mais recente executando
gcloud components update
.
Requisitos do GKE Gateway Controller
- Para o Standard, o GKE versão 1.24 ou posterior.
- Para o Autopilot, o GKE versão 1.26 ou posterior.
- Google Cloud CLI versão 407.0.0 ou mais recente.
- A API Gateway é compatível apenas com clusters nativos da VPC.
- Se você estiver usando o GatewayClasses interno, ative uma sub-rede somente proxy.
- O cluster precisa ter o complemento
HttpLoadBalancing
ativado. - Se você estiver usando o Istio, será necessário fazer upgrade do Istio para uma das seguintes versões:
- 1.15.2 ou mais recente
- 1.14.5 ou mais recente
- 1.13.9 ou mais recente
- Se você estiver usando a VPC compartilhada, será necessário atribuir o papel
Compute Network User
à conta de serviço do GKE referente ao projeto de serviço no projeto host.
Restrições e limitações
Além das restrições e limitações do controlador de gateway do GKE, as seguintes limitações se aplicam especificamente à segurança do gateway:
- As configurações de TLS que usam um certificado SSL ou gerenciador de certificados em gateways não são compatíveis com a versão 1.28.4-gke.1083000 do GKE. Use um secret do Kubernetes como solução alternativa para essa versão do GKE.
- Não é possível usar a anotação
networking.gke.io/certmap
com umtls.certificateRefs
no mesmo recurso de gateway. Se você referenciar umCertificateMap
em um gateway, o GKE o tratará como um erro.
- O Gerenciador de certificados é compatível com certificados SSL autogerenciados e gerenciados pelo Google. Os certificados gerenciados pelo Google são compatíveis com gateways regionais e globais.
- Ao usar certificados SSL gerenciados pelo Google, é necessário criar os certificados SSL fora do GKE antes de anexá-los ao gateway.
Não é possível usar o mesmo serviço de back-end para um gateway regional e global se você estiver fazendo referência a uma política de segurança de back-end do Google Cloud Armor na
GCPBackendPolicy
. É preciso criar dois serviços e políticas separados para esse caso de uso.O controlador de gateway não é compatível com o recurso
ManagedCertificate
.O controlador Gateway não é compatível com a anotação
networking.gke.io/managed-certificates
.O campo
appProtocol
na configuração do serviço aceita apenas letras maiúsculas para o valor do protocolo (HTTP
,HTTPS
ouHTTP2
). O uso de letras minúsculas resulta no uso de HTTP como protocolo com os back-ends.
Para uma lista de campos compatíveis com a API Gateway e recursos do GatewayClass disponíveis no GKE, consulte Recursos adicionais do GatewayClass.
Proteger um gateway usando um secret do Kubernetes
Neste exemplo, você configura um gateway usando um secret do Kubernetes.
Armazenar um certificado em um secret do Kubernetes
É possível usar um certificado emitido e validado pela autoridade de certificação (CA, na sigla em inglês) ou criar um certificado autoassinado. As etapas a seguir usam um certificado autoassinado.
Criar uma chave privada
openssl genrsa -out PRIVATE_KEY_FILE 2048
Substitua
PRIVATE_KEY_FILE
pelo nome do arquivo de chave privada, comoprivate-key.pem
. Para mais informações, consulte Selecionar ou criar uma chave privada.Crie um arquivo de configuração OpenSSL.
cat <<EOF >CONFIG_FILE [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = store.example.com [sans_list] DNS.1 = store.example.com EOF
Substitua
CONFIG_FILE
pelo nome do novo arquivo de configuração, comoconfig-file.cnf
.Crie um arquivo de solicitação de assinatura de certificado (CSR):
openssl req -new -key PRIVATE_KEY_FILE \ -out CSR_FILE \ -config CONFIG_FILE
Substitua
CSR_FILE
pelo nome do novo arquivo CSR, comocert.pem
. Para saber mais, consulte Criar uma CSR.Assinar a CSR:
openssl x509 -req \ -signkey PRIVATE_KEY_FILE \ -in CSR_FILE \ -out CERTIFICATE_FILE \ -extfile CONFIG_FILE \ -extensions extension_requirements \ -days 30
Substitua
CERTIFICATE_FILE
pelo caminho e nome do arquivo gerado pelo comando, comocert-file.pem
. Para mais informações, consulte Assinar o CSR.Crie um secret TLS do Kubernetes usando a chave e o arquivo de certificado que você criou:
kubectl create secret tls store-example-com \ --cert=CERTIFICATE_FILE \ --key=PRIVATE_KEY_FILE
O GKE salva o certificado e a chave como um recurso do Kubernetes que pode ser anexado ao gateway.
Crie um gateway e um HTTPRoute
Salve o seguinte manifesto como
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: store-example-com
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implanta um balanceador de carga de aplicativo externo global.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.tls
: faz referência ao secret do Kubernetes criado na etapa anterior.
Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Salve o seguinte manifesto como
store-external-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
Esse manifesto descreve um HTTPRoute que corresponde ao tráfego para
store.example.com
e o envia ao serviçostore-v1
.Aplique o manifesto ao cluster:
kubectl apply -f store-external-route.yaml
Verifique o gateway
Verifique se o gateway funciona enviando uma solicitação pela Internet.
Consiga o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado será assim:
203.0.113.12
Essa saída é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode se conectar a ela.
Acesse o domínio do gateway usando
curl
:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
Substitua:
GATEWAY_IP_ADDRESS
: o endereço IP do balanceador de carga do gateway.CERTIFICATE_FILE
: o arquivo de certificado que você gerou. Salve esse arquivo na máquina que está usando para se conectar ao gateway. O certificado é necessário para autenticar o gateway porque ele usa um certificado autoassinado.
A opção
--resolve
resolve o nome de domínio para o endereço IP do gateway, que é necessário porque o DNS não está configurado para este domínio.O resultado será assim:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08" # Several lines of output omitted here. }
Essa saída inclui um handshake de TLS bem-sucedido seguido por uma resposta do aplicativo. A conexão TLS é encerrada no gateway e o aplicativo responde ao cliente de forma segura.
Proteger um gateway usando um certificado SSL
Neste exemplo, você configura um gateway com um certificado SSL gerenciado pelo Google.
Criar um certificado SSL
Crie um recurso
SslCertificate
global gerenciado pelo Google:gcloud compute ssl-certificates create store-example-com \ --domains=store.example.com \ --global
Crie um gateway e um HTTPRoute
Salve o seguinte manifesto como
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-com
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implanta um balanceador de carga de aplicativo externo global.protocol:HTTPS
eport:443
: necessários para ativar o TLS.tls.mode:Terminate
: encerra o TLS usando seu certificado SSL.
Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Salve o seguinte manifesto HTTPRoute como
store-external-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
Implantar o HTTPRoute no cluster:
kubectl apply -f store-external-route.yaml
A implantação do gateway pode levar vários minutos.
Verifique o gateway
Consiga o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado será assim:
203.0.113.12
Essa saída é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode se conectar a ela.
Atualize um registro A ou AAAA para direcionar seu domínio ao endereço IP do gateway.
Essa etapa é necessária apenas se você estiver configurando um certificado SSL gerenciado pelo Google. Se você estiver configurando um certificado autogerenciado, pule esta etapa.
Depois que os registros DNS forem atualizados, pode levar até 10 minutos para o balanceador de carga começar a usar o certificado gerenciado pelo Google.
Verifique se o gateway está funcionando enviando uma solicitação pela Internet usando
curl
:curl https://store.example.com -v
O resultado será assim:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
Essa saída inclui um handshake de TLS bem-sucedido e uma resposta do aplicativo. O TLS é encerrado no gateway corretamente, e o aplicativo responde ao cliente de forma segura.
Proteger um gateway usando o Gerenciador de certificados
Neste exemplo, você configura um gateway usando o Gerenciador de certificados.
Criar um Certificate
Gateway global
Para criar um gateway global, faça referência a um recurso de mapa de certificados que contenha um ou mais certificados. Você precisa criar pelo menos um certificado e adicioná-lo como uma entrada ao seu mapa de certificados.
Para criar um certificado, primeiro crie uma chave privada e um arquivo de certificado.
Para criar um recurso
Certificate
, carregue o certificado e a chave autogerenciados:gcloud certificate-manager certificates create store-example-com-cert \ --certificate-file="cert.pem" \ --private-key-file="PRIVATE_KEY_FILE"
Crie um
CertificateMap
:gcloud certificate-manager maps create store-example-com-map
Crie um
CertificateMapEntry
que atribua o certificado aCertificateMap
:gcloud certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
Gateway regional
Para um gateway regional, crie um Certificate
que será especificado diretamente ao criar o gateway. Ao contrário de um gateway global, não é necessário criar um CertificateMap
ao qual os certificados são atribuídos.
Criar uma chave privada e um certificado.
Crie um recurso
Certificate
fazendo upload do arquivo de certificado e da chave:
gcloud certificate-manager certificates create "CERTIFICATE_NAME" \
--certificate-file="CERTIFICATE_FILE" \
--private-key-file="PRIVATE_KEY_FILE" \
--location="REGION"
Substitua:
CERTIFICATE_NAME
: o nome do certificado, por exemplo,store-example-com-cert
.CERTIFICATE_FILE
: o nome do arquivo de certificado, por exemplo,cert.pem
.PRIVATE_KEY_FILE
: o nome do arquivo de chave privada, comoprivate-key.pem
. Para mais informações, consulte Selecionar ou criar uma chave privada.REGION
: o nome da região em que você está configurando o gateway, por exemplo,us-central1
.
Crie um gateway e um HTTPRoute
Gateway global
Para criar um gateway de peering, conclua as seguintes etapas:
Salve o seguinte manifesto como
cert-map-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implanta um balanceador de carga de aplicativo externo global.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.
Não há uma seção TLS porque o TLS está configurado com o Gerenciador de certificados usando a anotação
networking.gke.io/certmap
.Aplique o manifesto ao cluster:
kubectl apply -f cert-map-gateway.yaml
A implantação do gateway pode levar vários minutos.
Para criar um HTTPRoute, salve o manifesto a seguir como
cert-map-http-route.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: foo namespace: default spec: parentRefs: - name: external-http hostnames: - foo.example.com rules: - matches: - path: value: / backendRefs: - name: foo-v1 port: 8080
Aplique o manifesto ao cluster:
kubectl apply -f cert-map-http-route.yaml
Gateway regional
Ao criar um gateway regional, é possível especificar certificados gerenciados pelo Gerenciador de certificados e certificados gerenciados pelo Compute Engine.
Para criar um gateway externo regional, salve o seguinte manifesto como
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: gateway namespace: corp spec: gatewayClassName: gke-17-regional-external-managed listeners: - name: gateway-pre-shared-certmap protocol: HTTPS port: 443 tls: mode: Terminate options: networking.gke.io/cert-manager-certs: store-example-com-cert1, store-example-com-cert2 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName
:gke-l7-regional-external-managed
: implanta um balanceador de carga de aplicativo externo regional.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.options
:networking.gke.io/cert-manager-certs
: certificados gerenciados pelo gerenciador de certificados.
Para criar um gateway interno regional, no exemplo anterior, altere o valor de
gatewayClassName
paragke-17-rilb
. Isso implanta um balanceador de carga de aplicativo interno.Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Para criar um HTTPRoute, salve o manifesto a seguir como
store-external-route.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: backendRefs: - name: store-v1 port: 8080
Esse manifesto descreve um HTTPRoute que corresponde ao tráfego para
store.example.com
e encaminha o tráfego para o serviçostore-v1
.Aplique o manifesto ao cluster:
kubectl apply -f store-external-route.yaml
Verifique o gateway
Consiga o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado será assim:
203.0.113.12
Essa saída é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode se conectar a ela.
Atualize um registro A ou AAAA para direcionar seu domínio ao endereço IP do gateway.
Essa etapa é necessária apenas se você estiver configurando um certificado SSL gerenciado pelo Google. Se você estiver configurando um certificado autogerenciado, pule esta etapa.
Depois que os registros DNS forem atualizados, pode levar até 10 minutos para o balanceador de carga começar a usar o certificado gerenciado pelo Google.
Acesse o domínio do gateway usando
curl
:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
Substitua:
GATEWAY_IP_ADDRESS
: o endereço IP do balanceador de carga do gateway.CERTIFICATE_FILE
: o arquivo de certificado que você gerou. Salve esse arquivo na máquina que está usando para se conectar ao gateway. O certificado é necessário para autenticar o gateway porque ele usa um certificado autoassinado.
O resultado será assim:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
Essa saída inclui um handshake de TLS bem-sucedido e uma resposta do aplicativo. O TLS é encerrado no gateway corretamente, e o aplicativo responde ao cliente de forma segura.
Proteger o balanceador de carga para o tráfego de aplicativos usando TLS
É possível criptografar o tráfego do balanceador de carga para pods de back-end usando
o campo ports[].appProtocol
. Os campos aceitos para appProtocol
são: HTTP
, HTTPS
e HTTP2
.
O manifesto a seguir descreve um serviço que especifica que o balanceador de carga precisa usar o tráfego HTTPS para se comunicar com os pods de back-end:
apiVersion: v1
kind: Service
metadata:
name: store-v2
spec:
selector:
app: store
version: v2
ports:
- port: 8080
targetPort: 8080
appProtocol: HTTPS
O balanceador de carga não verifica o certificado usado pelos pods de back-end. É sua responsabilidade garantir que o certificado usado nos pods de back-end seja válido.
Proteger o cliente para o tráfego do balanceador de carga usando políticas de SSL
Quando os aplicativos são expostos por meio de um gateway externo que usa HTTPS, é importante usar os protocolos mais recentes ou especificar a versão mínima de SSL ou TLS. É possível proteger o cliente para o tráfego do balanceador de carga usando políticas de SSL.
Para saber mais sobre as políticas de SSL que podem ser anexadas ao gateway e como criá-las, consulte Configurar políticas de SSL para proteger o cliente para o tráfego do balanceador de carga.
Proteja seus back-ends usando o Google Cloud Armor
As políticas de segurança do Google Cloud Armor ajudam a proteger seus aplicativos com balanceamento de carga contra ataques baseados na Web. Depois
de configurar uma política de segurança do Google Cloud Armor,
você pode referenciá-la em um GCPBackendPolicy
aplicado aos serviços do Kubernetes.
Para configurar as políticas do Google Cloud Armor com gateway, consulte Configurar a política de segurança do Google Cloud Armor para proteger seus serviços de back-end.
Autenticar solicitações para seus back-ends usando o Identity-Aware Proxy
O Identity-Aware Proxy ajuda a proteger seus back-ends contra
tráfego indesejado autenticando clientes que enviam solicitações aos seus
aplicativos e aplicando a autorização de tráfego com base em papéis. Depois de ativar o Identity-Aware Proxy para GKE, é possível referenciar suas credenciais do OAuth em um GCPBackendPolicy
aplicado aos serviços do Kubernetes.
Para configurar o Identity-Aware Proxy com o gateway, consulte Configurar o Identity-Aware Proxy.
A seguir
- Saiba mais sobre segurança do gateway.