O Mutual TLS (mTLS) no gateway de entrada do ASM exige que os clientes apresentem um certificado durante o handshake TLS para comprovar sua identidade. Após a autenticação, as políticas de autorização controlam o que cada identidade de cliente pode acessar. Essa abordagem em duas camadas separa a autenticação (o mTLS verifica quem é o cliente) da autorização (as políticas controlam o que o cliente pode fazer).
Este guia aborda três tarefas:
Gerar os certificados para mTLS (CA, servidor e cliente).
Configure o gateway de entrada do ASM para exigir certificados de cliente na porta 443.
Crie uma política de autorização que negue a uma identidade de cliente específica o acesso a um caminho específico.
Como a identidade do cliente se mapeia para as regras de autorização
O certificado do cliente inclui uma URI SPIFFE em seu Subject Alternative Name (SAN), como spiffe://test.client. As políticas de autorização do ASM usam o campo principals para corresponder a essa identidade. A política faz a correspondência com o valor após o prefixo spiffe://. Por exemplo, um valor principals definido como test.client corresponde a um certificado com URI.1 = spiffe://test.client.
Esse mapeamento é o mecanismo central que conecta a autenticação mTLS ao controle de acesso baseado em caminho.
Pré-requisitos
Antes de começar, verifique se você tem:
A injeção automática de sidecar ativada. Para mais informações, consulte Configurar políticas de injeção de proxy sidecar
O gateway de entrada e a aplicação httpbin implantados, com a porta 443 habilitada no gateway de entrada. Para mais informações, consulte Implantar a aplicação httpbin
OpenSSL instalado na sua máquina local
Etapa 1: Gerar certificados mTLS
O mTLS requer três conjuntos de certificados: uma CA raiz, um certificado de servidor e um certificado de cliente. A CA raiz assina tanto o certificado do servidor quanto o do cliente. O gateway apresenta o certificado do servidor para se identificar, e os clientes apresentam o certificado de cliente para provar sua identidade.
Ao ser solicitado a preencher campos de certificado durante a geração, aceite os valores padrão. Os arquivos de configuração abaixo já definem todos os campos obrigatórios.
-
Crie um arquivo chamado
ca.cnfcom o seguinte conteúdo. -
Gere o certificado da CA raiz e a chave privada.
openssl req -x509 -config ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEMEsse comando gera dois arquivos:
cacert.pem(o certificado da CA) ecakey.pem(a chave privada da CA). -
Crie um arquivo chamado
server.cnfcom o seguinte conteúdo.HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = serverkey.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = bj localityName = Locality Name (eg, city) localityName_default = bj organizationName = Organization Name (eg, company) organizationName_default = test commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = test.com emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] DNS.1 = test.com -
Gere o certificado do servidor, inicialize o banco de dados de assinatura da CA e assine o certificado.
# Generate the CSR and private key openssl req -config server.cnf -newkey rsa:2048 -sha256 -nodes -out server.csr -outform PEM # Initialize the CA signing database touch index.txt echo '01' > serial.txt # Sign the server certificate with the root CA openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles server.csrEsse processo gera dois arquivos:
servercert.pem(o certificado do servidor) eserverkey.pem(a chave privada do servidor). -
Crie um arquivo chamado
client.cnfcom o seguinte conteúdo.HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = client.key.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = bj localityName = Locality Name (eg, city) localityName_default = bj organizationName = Organization Name (eg, company) organizationName_default = test.client commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = test.client emailAddress = Email Address emailAddress_default = test.client@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] URI.1 = spiffe://test.clientDois campos nesta configuração determinam a identidade do cliente para autorização:
Campo
Valor
Função
commonName_defaulttest.clientIdentifica o cliente
URI.1(SAN)spiffe://test.clientCorrespondido pelo campo
principalsnas políticas de autorização (após o prefixospiffe://) -
Gere o certificado do cliente e assine-o com a CA raiz.
# Generate the CSR and private key openssl req -config client.cnf -newkey rsa:2048 -sha256 -nodes -out clientcert.csr -outform PEM # Sign the client certificate with the root CA openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out clientcert.pem -infiles clientcert.csrComo resultado, são gerados dois arquivos:
clientcert.pem(o certificado do cliente) eclient.key.pem(a chave privada do cliente). -
Importe o certificado mTLS usando o recurso de gerenciamento de certificados do ASM. Defina o nome do certificado como
test.com. Para mais informações, consulte Usar o recurso de gerenciamento de certificados do ASM.Como alternativa, crie um Secret do Kubernetes diretamente. Execute o comando a seguir usando o kubeconfig do seu cluster de plano de dados:
kubectl create -n istio-system secret generic test.com \ --from-file=tls.key=serverkey.pem \ --from-file=tls.crt=servercert.pem \ --from-file=ca.crt=cacert.pemEste Secret agrupa três arquivos:
Chave
Arquivo
Finalidade
tls.keyserverkey.pemChave privada do servidor para terminação TLS
tls.crtservercert.pemCertificado do servidor apresentado aos clientes
ca.crtcacert.pemCertificado da CA raiz usado para verificar certificados de cliente
Etapa 2: Configure o listener mTLS no gateway
Adicione um listener mTLS na porta 443 do gateway de entrada do ASM. Após essa configuração, os clientes externos devem apresentar um certificado de cliente válido para acessar o serviço httpbin.
-
Atualize o resource Gateway com o seguinte conteúdo.
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: httpbin namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: test number: 80 protocol: HTTP - hosts: - test.com port: number: 443 name: https protocol: HTTPS tls: mode: MUTUAL credentialName: test.comA configuração
tls.mode: MUTUALexige que os clientes apresentem um certificado assinado pela CA no Secrettest.com. Sem um certificado de cliente válido, o handshake TLS falha e o gateway rejeita a conexão.NotaOutros modos TLS incluem
SIMPLE(apenas TLS no lado do servidor, sem necessidade de certificado de cliente) ePASSTHROUGH(o TLS não é terminado no gateway). UseMUTUALquando precisar autenticar a identidade do cliente no nível do gateway. -
Verifique se o mTLS rejeita requisições sem um certificado de cliente.
curl -v --resolve "test.com:443:<ASM-gateway-IP>" \ --cacert cacert.pem \ https://test.com/status/200Substitua
<ASM-gateway-IP>pelo endereço IP do seu gateway de entrada do ASM.A requisição falha com um erro de handshake TLS porque nenhum certificado de cliente foi fornecido. Isso confirma que o gateway impõe o mTLS.
-
Verifique se o mTLS aceita requisições com um certificado de cliente válido.
curl --header "host:test.com" \ --resolve "test.com:443:<ASM-gateway-IP>" \ --cacert cacert.pem \ --cert clientcert.pem \ --key client.key.pem \ https://test.com/status/200 -ISaída esperada:
HTTP/2 200 server: istio-envoy date: Sun, 28 Jul 2024 7:30:30 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: 6Uma resposta
HTTP/2 200confirma que o gateway aceitou o certificado do cliente e encaminhou a requisição para o httpbin.
Etapa 3: Restringir o acesso do cliente com uma política de autorização
Depois que o mTLS autentica cada cliente, as políticas de autorização controlam o que cada cliente pode acessar. Nesta etapa, crie uma política DENY que bloqueie a identidade test.client de acessar um caminho específico. Outros clientes permanecem inalterados.
Quando existem várias políticas de autorização na mesma carga de trabalho, as políticas DENY são avaliadas antes das políticas ALLOW. Uma requisição que corresponda a qualquer regra DENY será rejeitada, independentemente das regras ALLOW.
-
Implante o seguinte AuthorizationPolicy para negar ao
test.cliento acesso ao caminho/status/418na aplicação httpbin. Para mais informações, consulte Configurar políticas de autorização para requisições HTTP.apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: test namespace: istio-system spec: action: DENY rules: - from: - source: principals: - test.client to: - operation: paths: - /status/418 selector: matchLabels: istio: ingressgatewayEsta política tem como alvo o gateway de entrada (
istio: ingressgateway) e nega qualquer requisição do principaltest.clientpara o caminho/status/418. O valorprincipalsdefinido comotest.clientcorresponde à URI SPIFFEspiffe://test.clientno SAN do certificado do cliente.
Verifique a política de autorização
-
Confirme se o
test.clientainda consegue acessar outros caminhos. Envie uma requisição para/status/200:curl --header "host:test.com" \ --resolve "test.com:443:<ASM-gateway-IP>" \ --cacert cacert.pem \ --cert clientcert.pem \ --key client.key.pem \ https://test.com/status/200 -ISaída esperada:
HTTP/2 200 server: istio-envoy date: Sun, 28 Jul 2024 7:33:30 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: 6Uma resposta
200significa que a política DENY se aplica apenas a/status/418, e não a outros caminhos. -
Confirme se o acesso do
test.clienta/status/418foi negado:curl --header "host:test.com" \ --resolve "test.com:443:<ASM-gateway-IP>" \ --cacert cacert.pem \ --cert clientcert.pem \ --key client.key.pem \ https://test.com/status/418Saída esperada:
RBAC: access deniedA mensagem
RBAC: access deniedconfirma que a política de autorização bloqueou otest.clientneste caminho. -
Confirme se uma identidade de cliente diferente ainda consegue acessar
/status/418. Envie uma requisição usando o certificado do servidor:curl --header "host:test.com" \ --resolve "test.com:443:<ASM-gateway-IP>" \ --cacert cacert.pem \ --cert servercert.pem \ --key serverkey.pem \ https://test.com/status/418Saída esperada:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`A resposta "teapot" confirma que a regra DENY tem como alvo apenas a identidade
test.client. Outras identidades com certificados válidos ainda podem acessar/status/418.