Esta página explica como pode proteger um gateway através de várias funcionalidades de segurança:
Políticas SSL para garantir que o gateway está a usar os protocolos e os 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 a segurança da gateway, consulte o artigo Segurança da gateway.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute
gcloud components update
para obter a versão mais recente.
Requisitos do GKE Gateway Controller
- A API Gateway é suportada apenas em clusters nativos de VPC.
- Se estiver a usar as GatewayClasses internas, tem de ativar uma sub-rede apenas de proxy.
- O seu cluster tem de ter o suplemento
HttpLoadBalancing
ativado. - Se estiver a usar o Istio, tem de atualizar o Istio para uma das seguintes versões:
- 1.15.2 ou posterior
- 1.14.5 ou posterior
- 1.13.9 ou posterior.
Se estiver a usar a VPC partilhada, no projeto anfitrião, tem de atribuir a função
Compute Network User
à conta de serviço do GKE para o projeto de serviço.Certifique-se de que tem um cluster do Autopilot ou Standard existente. Se precisar de um, crie um cluster do Autopilot.
Restrições e limitações
Além das restrições e limitações do controlador do GKE Gateway, aplicam-se as seguintes limitações especificamente à segurança do Gateway:
As configurações de TLS que usam um certificado SSL ou o Gestor de certificados em gateways não são suportadas com a versão 1.28.4-gke.1083000 do GKE. Use um segredo do Kubernetes como solução alternativa para esta versão do GKE.
Não pode usar a anotação
networking.gke.io/certmap
com umtls.certificateRefs
no mesmo recurso Gateway. Se fizer referência a umCertificateMap
num Gateway, o GKE trata isto como um erro.O Gestor de certificados suporta certificados autogeridos e geridos pela Google. Os certificados geridos pela Google são compatíveis com gateways regionais e gateways globais.
Quando usar certificados SSL geridos pela Google, tem de criar os certificados SSL fora do GKE antes de os anexar ao gateway.
Não pode usar o mesmo serviço como back-end para um gateway regional e global se estiver a fazer referência a uma política de segurança de back-end do Google Cloud Armor no seu
GCPBackendPolicy
. Tem de criar dois serviços e políticas separados para este exemplo de utilização.O controlador Gateway não suporta o recurso
ManagedCertificate
.O controlador de gateway não suporta a anotação
networking.gke.io/managed-certificates
.
Para uma lista dos campos da API Gateway suportados e das capacidades dos recursos GatewayClass disponíveis no GKE, consulte as capacidades da GatewayClass.
Proteja um gateway com um Secret do Kubernetes
Neste exemplo, vai configurar um gateway com um secret do Kubernetes.
Armazene um certificado num secret do Kubernetes
Pode usar um certificado emitido e validado pela sua autoridade de certificação (AC) ou criar um certificado autoassinado. Os passos seguintes usam um certificado autoassinado.
Crie uma chave privada:
openssl genrsa -out PRIVATE_KEY_FILE 2048
Substitua
PRIVATE_KEY_FILE
pelo nome do ficheiro de chave privada, comoprivate-key.pem
. Para mais informações, consulte o artigo Selecione ou crie uma chave privada.Crie um ficheiro de configuração do Open SSL:
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 ficheiro de configuração, comoconfig-file.cnf
.Crie um ficheiro de pedido 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 ficheiro CSR, comocert.pem
. Para mais informações, consulte o artigo Crie um CSR.Assine o 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 ficheiro que o comando gera, comocert-file.pem
. Para mais informações, consulte Assine o CSR.Crie um segredo TLS do Kubernetes com a chave e o ficheiro de certificado que criou:
kubectl create secret tls store-example-com \ --cert=CERTIFICATE_FILE \ --key=PRIVATE_KEY_FILE
O GKE guarda o certificado e a chave como um recurso do Kubernetes que pode anexar ao seu Gateway.
Crie um gateway e um HTTPRoute
Guarde 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: # Directly reference the Kubernetes Secret containing the TLS certificate and private key. - name: store-example-com # The name of the TLS secret.
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implementa um balanceador de carga de aplicações externo global.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.tls
: faz referência ao segredo do Kubernetes criado no passo anterior.
Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Guarde 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 # Link this route to the 'external-http' Gateway. hostnames: - "store.example.com" # Match traffic for this hostname. rules: - backendRefs: # Define where to forward the traffic. - name: store-v1 port: 8080
Este manifesto descreve uma HTTPRoute que corresponde ao tráfego para
store.example.com
e o envia para o serviçostore-v1
.Aplique o manifesto ao cluster:
kubectl apply -f store-external-route.yaml
Valide o gateway
Verifique se o gateway funciona enviando um pedido através da Internet.
Obtenha o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado é semelhante ao seguinte:
203.0.113.12
Este resultado é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode estabelecer ligação ao mesmo.
Aceda ao domínio da Gateway através de
curl
:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
Substitua o seguinte:
GATEWAY_IP_ADDRESS
: o endereço IP do balanceador de carga do gateway.CERTIFICATE_FILE
: o ficheiro de certificado que gerou. Tem de guardar este ficheiro no computador que está a usar para se ligar ao gateway. O certificado é necessário para autenticar o gateway porque o gateway usa um certificado autoassinado.
A opção
--resolve
resolve o nome do domínio para o endereço IP do gateway, o que é necessário porque o DNS não está configurado para este domínio.O resultado é semelhante ao seguinte:
... * 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 # This block shows the certificate details presented by the Gateway. # The value of the 'common name' field matches the requested hostname. * 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. }
Este resultado inclui um handshake TLS bem-sucedido seguido de uma resposta da aplicação. A ligação TLS é terminada no gateway e a aplicação responde ao cliente de forma segura.
Proteja um gateway com um certificado SSL
Neste exemplo, configura um gateway com um certificado SSL gerido pela Google.
Crie um certificado SSL
Crie um recurso global
SslCertificate
gerido pela Google:gcloud compute ssl-certificates create store-example-com \ --domains=store.example.com \ --global
Crie um gateway e um HTTPRoute
Guarde 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 # Terminate TLS using your SSL certificate. options: networking.gke.io/pre-shared-certs: store-example-com # Specify the Google Cloud SSL certificate resource name.
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implementa um balanceador de carga de aplicações externo global.protocol:HTTPS
eport:443
: necessários para ativar o TLS.tls.mode:Terminate
: termina o TLS através do seu certificado SSL.
Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Guarde 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
Implemente o HTTPRoute no seu cluster:
kubectl apply -f store-external-route.yaml
A implementação do gateway pelo GKE pode demorar vários minutos.
Valide o gateway
Obtenha o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado é semelhante ao seguinte:
203.0.113.12
Este resultado é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode estabelecer ligação ao mesmo.
Atualize um registo A ou AAAA para direcionar o seu domínio para o endereço IP do gateway.
Este passo só é necessário se estiver a configurar um certificado SSL gerido pela Google. Se estiver a configurar um certificado autogerido, pode ignorar este passo.
Após a atualização dos registos de DNS, o balanceador de carga pode demorar até 10 minutos a começar a usar o certificado gerido pela Google.
Verifique se o gateway está a funcionar enviando um pedido através da Internet com
curl
:curl https://store.example.com -v
O resultado é semelhante ao seguinte:
... * 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" }
Este resultado inclui um handshake TLS bem-sucedido e uma resposta da aplicação. O TLS é terminado corretamente no gateway e a aplicação responde ao cliente de forma segura.
Proteja um gateway com o Certificate Manager
Neste exemplo, configura um gateway através do Gestor de certificados.
Crie um Certificate
Gateway global
Para criar um gateway global, faz referência a um recurso de mapa de certificados que contém um ou mais certificados. Tem de criar, pelo menos, um certificado e adicioná-lo como uma entrada ao seu mapa de certificados.
Para criar um certificado, comece por criar uma chave privada e um ficheiro de certificado.
Crie um recurso
Certificate
carregando o seu certificado e chave autogeridos: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 aoCertificateMap
: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, cria um Certificate
que é especificado diretamente quando cria o gateway. Ao contrário de um gateway global, não precisa de criar um CertificateMap
ao qual os certificados são atribuídos.
Crie um recurso
Certificate
carregando o ficheiro de certificado e a chave:
gcloud certificate-manager certificates create "CERTIFICATE_NAME" \
--certificate-file="CERTIFICATE_FILE" \
--private-key-file="PRIVATE_KEY_FILE" \
--location="REGION"
Substitua o seguinte:
CERTIFICATE_NAME
: o nome do seu certificado, por exemplo,store-example-com-cert
.CERTIFICATE_FILE
: o nome do ficheiro de certificado, por exemplo,cert.pem
.PRIVATE_KEY_FILE
: o nome do ficheiro de chave privada, comoprivate-key.pem
. Para mais informações, consulte o artigo Selecione ou crie uma chave privada.REGION
: o nome da região na qual está a configurar o gateway, por exemplo,us-central1
.
Crie um gateway e um HTTPRoute
Gateway global
Para criar um gateway global, conclua os seguintes passos:
Guarde 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 # No TLS section is included here because TLS is handled by the certmap annotation.
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName: gke-l7-global-external-managed
: implementa um balanceador de carga de aplicações externo global.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.
Não existe uma secção TLS porque o TLS está configurado com o Certificate Manager através da anotação
networking.gke.io/certmap
.Aplique o manifesto ao cluster:
kubectl apply -f cert-map-gateway.yaml
A implementação do gateway pelo GKE pode demorar vários minutos.
Para criar um HTTPRoute, guarde o seguinte manifesto 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
Quando cria um gateway regional, pode especificar certificados geridos pelo Certificate Manager e certificados geridos pelo Compute Engine.
Para criar um gateway externo regional, guarde o seguinte manifesto como
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: gateway namespace: corp spec: gatewayClassName: gke-l7-regional-external-managed listeners: - name: gateway-pre-shared-certmap protocol: HTTPS port: 443 tls: mode: Terminate # TLS is terminated at the Gateway. options: # Specifies a comma-separated list of Certificate Manager certificates to use for TLS termination. networking.gke.io/cert-manager-certs: store-example-com-cert1, store-example-com-cert2 # These certificates are directly managed by Certificate Manager. allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All
Este manifesto descreve um Gateway com as seguintes propriedades:
gatewayClassName
:gke-l7-regional-external-managed
: implementa um balanceador de carga de aplicações externo regional.protocol: HTTPS
eport: 443
: necessários para ativar o TLS.options
:networking.gke.io/cert-manager-certs
: certificados geridos pelo Gestor de certificados.
Para criar um gateway interno regional, no exemplo anterior, altere o valor de
gatewayClassName
paragke-l7-rilb
. Isto implementa um balanceador de carga de aplicações interno.Aplique o manifesto ao cluster:
kubectl apply -f external-gateway.yaml
Para criar um HTTPRoute, guarde o seguinte manifesto 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
Este manifesto descreve uma 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
Valide o gateway
Obtenha o endereço IP do gateway:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
O resultado é semelhante ao seguinte:
203.0.113.12
Este resultado é um endereço IP público, o que significa que qualquer cliente com acesso à Internet pode estabelecer ligação ao mesmo.
Atualize um registo A ou AAAA para direcionar o seu domínio para o endereço IP do gateway.
Este passo só é necessário se estiver a configurar um certificado SSL gerido pela Google. Se estiver a configurar um certificado autogerido, pode ignorar este passo.
Após a atualização dos registos de DNS, o balanceador de carga pode demorar até 10 minutos a começar a usar o certificado gerido pela Google.
Aceda ao domínio da Gateway através de
curl
:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
Substitua o seguinte:
GATEWAY_IP_ADDRESS
: o endereço IP do balanceador de carga do gateway.CERTIFICATE_FILE
: o ficheiro de certificado que gerou. Tem de guardar este ficheiro no computador que está a usar para se ligar ao gateway. O certificado é necessário para autenticar o gateway porque o gateway usa um certificado autoassinado.
O resultado é semelhante ao seguinte:
... * 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" }
Este resultado inclui um handshake TLS bem-sucedido e uma resposta da aplicação. O TLS é terminado corretamente no gateway e a aplicação responde ao cliente de forma segura.
Proteja o balanceador de carga para o tráfego de aplicações através do protocolo TLS
Pode encriptar o tráfego do equilibrador de carga para os pods de back-end através do campo ports[].appProtocol
. Os campos suportados para appProtocol
são: HTTP
,
HTTPS
, HTTP2
e kubernetes.io/h2c
.
O manifesto seguinte descreve um serviço que especifica que o balanceador de carga tem de usar tráfego HTTPS para 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 valida o certificado usado pelos pods de back-end. É da sua responsabilidade garantir que o certificado usado nos pods de back-end é válido.
Proteja o tráfego do cliente para o balanceador de carga através de políticas SSL
Quando as suas aplicações são expostas através de um gateway externo que usa HTTPS, é importante usar os protocolos mais recentes ou especificar a versão mínima do SSL ou TLS. Pode proteger o tráfego do cliente para o equilibrador de carga através de políticas SSL.
Para saber mais acerca das políticas SSL que podem ser anexadas ao seu gateway e como as criar, consulte o artigo Configure políticas SSL para proteger o tráfego do cliente para o equilibrador de carga.
Proteja os seus back-ends com o Google Cloud Armor
As políticas de segurança do Google Cloud Armor
ajudam a proteger as suas aplicações com balanceamento de carga contra ataques baseados na Web. Depois de configurar uma política de segurança do Google Cloud Armor, pode referenciá-la num GCPBackendPolicy
aplicado aos seus serviços Kubernetes.
Para configurar políticas do Google Cloud Armor com o Gateway, consulte o artigo Configure a política de segurança do Google Cloud Armor para proteger os seus serviços de back-end.
Autentique pedidos aos seus back-ends através do Identity-Aware Proxy
O Identity-Aware Proxy ajuda a proteger os seus back-ends contra tráfego indesejado autenticando clientes que enviam pedidos às suas aplicações e aplicando a autorização de tráfego baseada em funções. Depois de ativar o Identity-Aware Proxy para o GKE, pode fazer referência às suas credenciais OAuth num GCPBackendPolicy
aplicado aos seus serviços Kubernetes.
Para configurar o Identity-Aware Proxy com o gateway, consulte o artigo Configure o Identity-Aware Proxy.
O que se segue?
- Saiba mais sobre a segurança do gateway.
- Saiba como configurar recursos de gateway através de políticas.
- Saiba como implementar gateways.
- Saiba mais acerca da API Gateway