Quando suas aplicações enviam HTTP em texto simples para serviços externos, o tráfego de saída do mesh permanece sem criptografia. O egress gateway do Service Mesh (ASM) atua como ponto único de saída para todo o tráfego externo do mesh. Ele intercepta as requisições e estabelece conexões mTLS com os serviços externos em nome das cargas de trabalho, garantindo criptografia de ponta a ponta sem exigir alterações no código.
Este guia descreve como rotear o tráfego HTTP de saída por um egress gateway e atualizá-lo para mTLS.
Casos de uso
Roteie o tráfego por um egress gateway com origem mTLS quando:
A política de segurança exigir egress criptografado. As aplicações enviam HTTP em texto simples, mas todo o tráfego de saída do mesh requer criptografia. O egress gateway gerencia a origem TLS sem exigir alterações na aplicação.
For necessário controle centralizado de egress. Todo o tráfego de saída deve passar por nós de gateway dedicados para auditoria, monitoramento e aplicação de políticas.
O serviço externo exigir autenticação por certificado de cliente. O mesh precisa apresentar um certificado de cliente específico (TLS mútuo) em nome das cargas de trabalho.
Como funciona
O diagrama a seguir ilustra o caminho completo do tráfego após a conclusão de todas as etapas de configuração deste guia:
sleep pod ──mesh mTLS──> egress gateway ──external mTLS──> external ingress gateway ──mTLS──> httpbin
O pod
sleepenvia uma requisição HTTP em texto simples paratest.com.O proxy sidecar intercepta a requisição e a encaminha ao egress gateway via mTLS interno do mesh (certificados gerenciados pelo ASM).
O egress gateway inicia uma nova conexão mTLS com o serviço externo usando um certificado de cliente fornecido pelo usuário.
O ingress gateway externo termina o mTLS e roteia a requisição para o serviço upstream
httpbin.
Este guia constrói esse caminho de forma incremental. Após a Etapa 3, o segmento entre o egress e o serviço externo ainda utiliza texto simples. A Etapa 4 atualiza esse segmento para mTLS, eliminando a lacuna de segurança.
Pré-requisitos
Antes de começar, verifique se você:
Concluiu todas as etapas em Configurar serviço mTLS no ingress gateway do ASM e restringir acesso de clientes específicos. Esse tutorial implanta o servidor mTLS usado como serviço externo neste guia.
Dispõe de uma instância do ASM e um cluster do Container Service for Kubernetes (ACK) separados como ambiente principal para este guia.
Ativou a injeção automática de sidecar. Para mais informações, consulte Configurar políticas de injeção de proxy sidecar.
Nas etapas abaixo, $INGRESS_GATEWAY_IP refere-se ao IP do ingress gateway do tutorial de pré-requisito. "Cluster ACK" e "instância do ASM" referem-se aos recursos do ambiente principal.
Defina a variável de shell usada em todo este guia. Com o kubeconfig do cluster ACK, execute:
# Replace with the actual ingress gateway IP from the prerequisite tutorial
export INGRESS_GATEWAY_IP=<ingress-gateway-ip>
Etapa 1: Implantar a aplicação de teste sleep
Implante a aplicação sleep como cliente de teste. Para instruções de implantação, consulte Operações relacionadas.
Verificar a implantação
Com o kubeconfig do cluster ACK, verifique se o pod sleep alcança o serviço externo HTTPBin:
kubectl exec deploy/sleep -- curl --header "host:test.com" $INGRESS_GATEWAY_IP/status/418
Saída esperada:
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`
A resposta HTTP 418 (teapot) confirma a conectividade com o serviço externo HTTPBin.
Etapa 2: Ativar REGISTRY_ONLY e criar um ServiceEntry
Restringir o acesso de saída (opcional)
Defina a política de tráfego de saída como REGISTRY_ONLY para impedir que os pods alcancem qualquer serviço não registrado explicitamente por meio de um ServiceEntry. Para mais informações, consulte Etapa 2: Ativar REGISTRY_ONLY.
Após ativar REGISTRY_ONLY, as requisições para serviços não registrados retornam um erro 502 Bad Gateway.
Registrar o serviço externo
Crie um ServiceEntry para test.com de modo que os pods no mesh possam acessá-lo. Para mais informações, consulte Criar um serviço externo.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: test-com
namespace: default
spec:
endpoints:
- address: <ingress-gateway-ip> # IP address of the external ingress gateway
hosts:
- test.com
location: MESH_EXTERNAL
ports:
- name: http
number: 80
protocol: HTTP
- name: https
number: 443
protocol: HTTPS
resolution: STATIC
Substitua <ingress-gateway-ip> pelo endereço IP do ingress gateway obtido no tutorial de pré-requisito.
Verificar
Após aplicar o ServiceEntry, execute o mesmo comando curl da Etapa 1 para confirmar que o pod sleep ainda acessa o serviço HTTPBin em test.com.
Etapa 3: Criar o egress gateway e rotear tráfego HTTP por ele
3a. Criar o egress gateway
Crie um egress gateway para tráfego HTTP na porta 80 com autenticação TLS mútua ativada. As cargas de trabalho no mesh criptografam automaticamente o tráfego destinado ao gateway usando certificados gerenciados pelo ASM. Para mais informações, consulte Criar um egress gateway.
3b. Criar regras de gateway
Crie um recurso Gateway que declare o listener do egress gateway. O gateway escuta na porta 80 com modo TLS ISTIO_MUTUAL (certificados gerenciados pelo ASM). Para mais informações, consulte Criar regras de gateway.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: egress-gateway
namespace: default
spec:
selector:
istio: egressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTPS
tls:
mode: ISTIO_MUTUAL
3c. Criar um VirtualService
Crie um VirtualService que roteie o tráfego de test.com em dois estágios:
Do mesh para o egress gateway: O sidecar encaminha o tráfego na porta 80 para o egress gateway.
Do egress gateway para o serviço externo: O egress gateway encaminha o tráfego para o ServiceEntry
test.comna porta 80.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: egressgateway-vs
spec:
hosts:
- test.com
gateways:
- egress-gateway # Gateway created in step 3b
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
weight: 100
- match:
- gateways:
- egress-gateway
port: 80
route:
- destination:
host: test.com
port:
number: 80
weight: 100
Verificar se o tráfego flui pelo egress gateway
-
Acesse
test.coma partir do podsleep. Saída esperada: a arte ASCII do bule de chá HTTP 418 (igual à Etapa 1).kubectl exec deploy/sleep -- curl --header "host:test.com" $INGRESS_GATEWAY_IP/status/418 -
Verifique o log de acesso do egress gateway. Com o kubeconfig da instância do ASM, execute o comando abaixo. A entrada de log deve exibir
"upstream_cluster":"outbound|80||test.com", confirmando que a requisição passou pelo egress gateway.export EGRESS_POD=$(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') kubectl -n istio-system logs $EGRESS_POD | tail -1
Fluxo de tráfego nesta etapa
sleep pod ──mTLS──> egress gateway ──plaintext──> external ingress gateway ──mTLS──> httpbin
O segmento entre o egress e o serviço externo ainda utiliza texto simples. A Etapa 4 atualiza esse segmento para mTLS.
Etapa 4: Atualizar o tráfego de egress para mTLS
4a. Atualizar o VirtualService
Atualize o VirtualService para rotear o tráfego do egress gateway para a porta 443 em vez da porta 80. A única alteração é a porta de destino na correspondência do egress-gateway:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: egressgateway-vs
spec:
hosts:
- test.com
gateways:
- egress-gateway
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
weight: 100
- match:
- gateways:
- egress-gateway
port: 80
route:
- destination:
host: test.com
port:
number: 443 # Changed from 80 to 443
weight: 100
4b. Importar o certificado de cliente mTLS
Importe o certificado mTLS de Configurar serviço mTLS no ingress gateway do ASM e restringir acesso de clientes específicos. Nomeie o certificado como test.client. Para mais informações, consulte Usar o recurso de gerenciamento de certificados do ASM.
Como alternativa, crie o secret diretamente com kubectl. Com o kubeconfig do cluster ACK, execute:
kubectl create -n istio-system secret generic test.client \
--from-file=tls.key=client.key.pem \
--from-file=tls.crt=clientcert.pem \
--from-file=ca.crt=cacert.pem
4c. Criar um DestinationRule para origem mTLS
Crie um DestinationRule que configure o egress gateway para iniciar mTLS ao se conectar a test.com na porta 443:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-mtls-for-test-com
spec:
host: test.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: MUTUAL
credentialName: test.client
sni: test.com
|
Campo |
Descrição |
|
|
Ativa o TLS mútuo. O egress gateway apresenta um certificado de cliente e valida o certificado do servidor. |
|
|
Referencia o secret |
|
|
Define a extensão Server Name Indication (SNI) como |
Verificar a origem mTLS
-
Teste um caminho permitido para o certificado de cliente. Saída esperada:
kubectl exec deploy/sleep -it -- curl --header "host:test.com" $INGRESS_GATEWAY_IP/status/200 -IHTTP/1.1 200 OK server: envoy date: Mon, 29 Jul 2024 03:33:50 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 5 -
Teste um caminho bloqueado para o certificado de cliente. Saída esperada: A requisição é negada porque o certificado
test.clientfoi configurado no tutorial de pré-requisito para bloquear o acesso ao caminho/status/418.kubectl exec deploy/sleep -it -- curl --header "host:test.com" $INGRESS_GATEWAY_IP/status/418RBAC: access denied% -
Confirme se o egress gateway se conecta pela porta 443. Com o kubeconfig da instância do ASM, execute o comando abaixo. A entrada de log deve exibir
"upstream_cluster":"outbound|443||test.com"e"upstream_host":"...:443", confirmando que o egress gateway se conecta ao serviço externo pela porta mTLS.kubectl -n istio-system logs $EGRESS_POD | tail -1
Fluxo de tráfego após a atualização para mTLS
sleep pod ──mTLS──> egress gateway ──mTLS──> external ingress gateway ──mTLS──> httpbin
Todos os segmentos agora estão criptografados com mTLS. A lacuna de texto simples da Etapa 3 foi eliminada.
Etapa 5: Configurar políticas de autorização
Com o mTLS de ponta a ponta implementado, o mesh autentica as identidades dos clientes em cada salto. As políticas de autorização aplicam controle de acesso granular em dois pontos.
Restringir acesso no egress gateway
Aplique uma AuthorizationPolicy no egress gateway para controlar quais serviços dentro do mesh podem acessar test.com. O exemplo a seguir nega à conta de serviço sleep o acesso ao caminho /headers:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
labels:
gateway: egressgateway
name: test
namespace: istio-system
spec:
action: DENY
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/sleep
to:
- operation:
hosts:
- test.com
paths:
- /headers
selector:
matchLabels:
istio: egressgateway
Após aplicar essa política, as requisições do pod sleep para test.com/headers através do egress gateway serão negadas.
Restringir acesso no ingress gateway externo
A AuthorizationPolicy no ingress gateway externo (de Configurar serviço mTLS no ingress gateway do ASM e restringir acesso de clientes específicos) restringe o acesso com base na identidade do certificado de cliente. A política do tutorial de pré-requisito impede que o certificado test.client acesse /status/418.
Juntos, esses dois pontos de autorização fornecem controle de acesso em camadas:
|
Ponto de autorização |
Escopo |
|
Políticas do egress gateway |
Controlam quais serviços do mesh podem acessar quais hosts e caminhos externos. |
|
Políticas do ingress gateway externo |
Controlam quais certificados de cliente podem acessar quais caminhos de backend. |