Quando suas aplicações enviam HTTP em texto simples para serviços externos, o tráfego de saída da malha não é criptografado. O egress gateway do Service Mesh (ASM) atua como ponto de saída único para todo o tráfego de saída da malha. Ele intercepta as requisições de saída e inicia conexões mTLS com os serviços externos em nome das suas cargas de trabalho, o que garante criptografia de ponta a ponta sem alterações no código.
Este guia orienta você a 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:
Sua política de segurança exige egress criptografado. As aplicações enviam HTTP em texto simples, mas todo o tráfego de saída da malha deve ser criptografado. O egress gateway gerencia a origem TLS sem exigir alterações na aplicação.
Você precisa de controle de egress centralizado. Todo o tráfego de saída deve fluir por nós de gateway dedicados para auditoria, monitoramento e aplicação de políticas.
O serviço externo exige autenticação por certificado de cliente. A malha deve apresentar um certificado de cliente específico (TLS mútuo) em nome das suas cargas de trabalho.
Como funciona
O diagrama a seguir mostra 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 para o egress gateway por meio do mTLS interno da malha (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 encerra o mTLS e roteia a requisição para o serviço
httpbinupstream.
Este guia constrói esse caminho de forma incremental. Após a Etapa 3, o segmento do egress para o serviço externo ainda está em texto simples. A Etapa 4 atualiza esse segmento para mTLS e elimina a lacuna de segurança.
Pré-requisitos
Antes de começar, certifique-se de ter:
Concluído todas as etapas em Configure mTLS service on ASM ingress gateway and restrict specific client access. Esse tutorial implanta o servidor mTLS usado como serviço externo neste guia.
Uma instância do ASM e um cluster do Container Service for Kubernetes (ACK) separados como ambiente principal para este guia.
A injeção automática de sidecar ativada. Para mais informações, consulte Configure sidecar proxy injection policies.
Nas etapas a seguir, $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.
Agora, defina a variável de shell usada neste 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: Implante a aplicação de teste sleep
Implante a aplicação sleep como cliente de teste. Para instruções de implantação, consulte Related operations.
Verifique a implantação
Com o kubeconfig do cluster ACK, verifique se o pod sleep consegue acessar o serviço HTTPBin externo:
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 HTTPBin externo.
Etapa 2: Ative o REGISTRY_ONLY e crie um ServiceEntry
Restrinja o acesso de saída (opcional)
Para restringir o acesso, defina a política de tráfego de saída como REGISTRY_ONLY para impedir que os pods acessem qualquer serviço não registrado explicitamente por meio de um ServiceEntry. Para mais informações, consulte Step 2: Enable REGISTRY_ONLY.
Depois de ativar o REGISTRY_ONLY, as requisições para serviços não registrados retornam um erro 502 Bad Gateway.
Registre o serviço externo
Crie um ServiceEntry para test.com para que os pods na malha possam acessá-lo. Para mais informações, consulte Create an external service.
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 do tutorial de pré-requisito.
Verifique
Depois de aplicar o ServiceEntry, execute o mesmo comando curl da Etapa 1 para confirmar que o pod sleep ainda consegue acessar o serviço HTTPBin em test.com.
Etapa 3: Crie o egress gateway e roteie o tráfego HTTP por ele
3a. Crie o egress gateway
Para começar, crie um egress gateway para tráfego HTTP na porta 80 com autenticação TLS mútua ativada. As cargas de trabalho na malha criptografam automaticamente o tráfego para o gateway usando certificados gerenciados pelo ASM. Para mais informações, consulte Create an egress gateway.
3b. Crie regras do gateway
Crie um recurso Gateway que declare o listener do egress gateway. O gateway escuta na porta 80 com o modo TLS ISTIO_MUTUAL (certificados gerenciados pelo ASM). Para mais informações, consulte Create gateway rules.
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. Crie um VirtualService
Crie um VirtualService que roteie o tráfego de test.com em duas etapas:
Malha para o egress gateway: O sidecar encaminha o tráfego na porta 80 para o egress gateway.
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
Verifique se o tráfego flui pelo egress gateway
-
Acesse
test.coma partir do podsleep. Saída esperada: a arte ASCII do teapot 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 mostrar
"upstream_cluster":"outbound|80||test.com", o que confirma 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 do egress para o serviço externo ainda está em texto simples. A Etapa 4 atualiza esse segmento para mTLS.
Etapa 4: Atualize o tráfego de egress para mTLS
4a. Atualize o VirtualService
Atualize o VirtualService para rotear o tráfego do egress gateway para a porta 443 em vez da porta 80. A única mudança é a porta de destino para a 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. Importe o certificado de cliente mTLS
Importe o certificado mTLS de Configure mTLS service on ASM ingress gateway and restrict specific client access. Nomeie o certificado como test.client. Para mais informações, consulte Use the certificate management feature of ASM.
Como alternativa, crie o secret diretamente com o 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. Crie um DestinationRule para origem mTLS
Crie um DestinationRule que configure o egress gateway para iniciar o 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 |
|
|
Habilita o TLS mútuo. O egress gateway fornece um certificado de cliente e valida o certificado do servidor. |
|
|
Referencia o secret |
|
|
Define a extensão Server Name Indication (SNI) como |
Verifique a origem mTLS
-
Teste um caminho que o certificado de cliente tem permissão para acessar. 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 cujo acesso é negado ao certificado de cliente. Saída esperada: A requisição é negada porque o certificado
test.clienté 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% -
Por fim, confirme que 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 mostrar
"upstream_cluster":"outbound|443||test.com"e"upstream_host":"...:443", o que confirma 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: Configure políticas de autorização
Com o mTLS de ponta a ponta implementado, a malha autentica as identidades dos clientes em cada salto. As políticas de autorização aplicam controle de acesso refinado em dois pontos.
Restrinja o acesso no egress gateway
Aplique um AuthorizationPolicy no egress gateway para controlar quais serviços na malha podem acessar test.com. O exemplo a seguir nega o acesso da conta de serviço sleep 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
Depois de aplicar essa política, as requisições do pod sleep para test.com/headers através do egress gateway são negadas.
Restrinja o acesso no ingress gateway externo
O AuthorizationPolicy no ingress gateway externo (de Configure mTLS service on ASM ingress gateway and restrict specific client access) 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 na malha podem acessar quais hosts e caminhos externos. |
|
Políticas do ingress gateway externo |
Controlam quais certificados de cliente podem acessar quais caminhos de backend. |