Aprimorando a segurança dos microsserviços com o Istio

Olá! Meu nome é Ilya, trabalho como engenheiro de DevOps na equipe de desenvolvimento. Utilizamos ativamente uma abordagem de microsserviço e, devido às especificidades de nosso trabalho, a segurança da comunicação entre serviços é importante para nós. Neste artigo, quero descrever como o Istio funciona e mostrar como usar alguns de seus recursos de segurança usando um exemplo. Espero que isso seja útil para resolver seus problemas. Gostar de ler!







Para que serve uma rede de serviços?



A malha de serviço, neste caso, Istio, é uma ligação para tudo o que é necessário para gerenciar e configurar a comunicação entre serviços: roteamento, autenticação, autorização, rastreamento, controle de acesso e muito mais. E embora existam inúmeras bibliotecas abertas para implementar essas funções diretamente no código de serviço, com o Istio você pode obter a mesma coisa sem adicionar nada ao serviço em si.



Componentes 



Artigo escrito para istio 1.6


Sobre mudanças
Istio , . , , - , , . , , Istio 1.4   v1beta1 , Istio RBAC. 1.5 , Pilot, Galley Citadel istiod. - . .



O Istio é logicamente dividido em um plano de dados e um plano de controle.

O plano de dados é uma coleção de servidores proxy (Envoy) adicionados ao pod como sidecars. Esses proxies fornecem e controlam toda a comunicação de rede entre microsserviços e são configurados no plano de controle.



O plano de gerenciamento (istiod) fornece descoberta de serviços, configuração e gerenciamento de certificados. Ele converte objetos Istio em configurações que o Envoy entende e os distribui no plano de dados.







Componentes de malha de serviço Istio



Você pode adicionar o enviado ao pod do aplicativo manualmente ou configurando a adição automática usando o webhook Mutating Admission, que o Istio adiciona durante sua instalação. Para fazer isso, coloque a tag istio-injection = enabled no espaço para nome necessário.



Além do side-car proxy com enviado, o Istio adicionará um contêiner init especial ao pod que redirecionará o tráfego de combate para o contêiner com enviado. Mas como isso é alcançado? Nesse caso, não há mágica, e isso é implementado através da definição de regras adicionais de iptables no namespace de rede do pod.



Sobre o consumo de recursos
, 100 Istio ~2-3 , envoy 40 , CPU 5%-7% pod.



Vamos ver na prática como um carro lateral captura o tráfego de entrada e saída de um contêiner. Para fazer isso, dê uma olhada no espaço de rede de um pod com o sidio Istio adicionado em mais detalhes. 



Suporte de demonstração
Kubernetes Istio. 

Kubernetes minikube:



Linux:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

minikube start --driver=<driver_name> // --driver=none        .




MacOS:
brew install minikube
minikube start --driver=<driver_name>






Istio demo :



curl -L https://istio.io/downloadIstio | sh -
cd istio-1.6.3
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo


: productpage details. Istio .



kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml








Vamos ver uma lista de contêineres para o aplicativo da página do produto:



kubectl -n default get pods productpage-v1-7df7cb7f86-ntwzz -o jsonpath="{.spec['containers','initContainers'][*].name}"
productpage 
istio-proxy 
istio-init


Além da própria página do produto, o sidecar istio-proxy (o mesmo enviado) e o init init istio-init funcionam no pod.



Você pode ver os nomes dos pods das regras do iptables configuradas no espaço usando o utilitário nsenter. Para fazer isso, precisamos descobrir o detalhe do processo do contêiner:



docker inspect k8s_productpage --format '{{ .State.Pid }}'
16286


Agora podemos ver as regras do iptables instaladas neste contêiner.







Você pode ver que quase todo o tráfego de entrada e saída agora é interceptado e redirecionado para portas nas quais o enviado já o espera. 



Ativar criptografia de tráfego mútuo



Os objetos Policy e MeshPolicy foram removidos da versão 1.6. Em vez disso, é sugerido o uso do objeto PeerAuthentication


O Istio permite criptografar todo o tráfego entre contêineres, e os próprios aplicativos nem saberão que estão se comunicando via tls. Isso é feito pelo próprio Istio, pronto para uso, com literalmente um manifesto, pois os certificados do cliente já estão montados no side-car proxy. 



O algoritmo é o seguinte: 



  1. Os proxies enviados, no lado do cliente e no servidor, se autenticam antes de enviar solicitações;

  2. Se a verificação for bem-sucedida, o proxy do cliente criptografa o tráfego e o envia ao proxy do servidor;

  3. O lado do servidor proxy descriptografa o tráfego e o redireciona localmente para o serviço de destino real.



Você pode ativar o mTLS em diferentes níveis:



  • No nível de toda a rede;

  • No nível do espaço para nome;

  • No nível de um pod específico. 



Modos de operação:



  • PERMISSIVO: o tráfego de texto criptografado e de texto sem formatação é permitido;

  • STRICT: somente TLS permitido;

  • DESATIVAR: somente texto sem formatação é permitido.



Vamos acessar o serviço de detalhes no pod da página do produto usando curl sem TLS ativado e ver o que vem com o tcpdump para obter detalhes:



Solicitação:







Despejo de tráfego:







todo o corpo e cabeçalhos são perfeitamente legíveis em texto sem formatação.



Vamos ativar tls. Para fazer isso, crie um objeto do tipo PeerAuthentication no espaço para nome com nossos pods.



apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: STRICT


Vamos executar a solicitação na página do produto para obter detalhes novamente e ver o que obtemos: O







tráfego é criptografado



Conecte-se



Os objetos ClusterRbacConfig, ServiceRole e ServiceRoleBinding foram removidos junto com a implementação da nova política de autorização. Em vez disso, propõe-se usar o objeto AuthorizationPolicy.


Usando políticas de autorização, o Istio pode configurar um aplicativo para acessar outro. Além disso, diferentemente das políticas de rede Kubernetes, isso funciona no nível L7. Por exemplo, para o tráfego http, você pode controlar com precisão os métodos e caminhos da solicitação.



Como vimos no exemplo anterior, por padrão, o acesso é aberto a todos os pods em todo o cluster.



Agora vamos desativar todas as atividades no espaço para nome padrão usando o seguinte arquivo yaml:



apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  {}


E vamos tentar alcançar o serviço de detalhes:



curl details:9080
RBAC: access denied


Ótimo, agora nosso pedido falha.



E agora vamos configurar o acesso para que apenas uma solicitação GET passe e somente ao longo do caminho / detalhes, e todas as outras solicitações sejam rejeitadas. Existem várias opções para isso:



  • Pode ser configurado para passar solicitações com cabeçalhos específicos;

  • Por conta de serviço do aplicativo;

  • Pelo endereço IP de saída;

  • Por namespace de saída;

  • Por reivindicações no token JWT.



A coisa mais fácil de manter é configurar o acesso à conta de serviço do aplicativo, pois não é necessária nenhuma configuração preliminar, pois o aplicativo de demonstração bookinfo já vem com uma conta de serviço criada e monitorada.



Para usar políticas de autorização com base em contas de serviço, você deve habilitar a autenticação mútua TLS.


Configurando uma nova política de acesso:



apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
        paths: ["/details/*"]


E tentamos entrar em contato novamente:



root@productpage-v1-6b64c44d7c-2fpkc:/# curl details:9080/details/0
{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}


Tudo está funcionando. Vamos tentar outros métodos e maneiras:



root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XPOST details:9080/details/0
RBAC: access denied
root@productpage-v1-6b64c44d7c-2fpkc:/# 
root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XGET details:9080/ping
RBAC: access denied


Conclusão



Concluindo, observo que as oportunidades consideradas são apenas uma fração do que o Istio pode fazer. Pronto para uso, recebemos e configuramos a criptografia e a autorização de tráfego entre serviços, embora com o custo de adicionar componentes adicionais e, portanto, consumo adicional de recursos. 



Obrigado a todos!



All Articles