O Mutual TLS (mTLS) no ingress gateway 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:
Gere os certificados para o mTLS (CA, servidor e cliente).
Configure o ingress gateway do ASM para exigir certificados de cliente na porta 443.
Crie uma política de autorização que negue o acesso de uma identidade de cliente específica a um caminho específico.
Como a identidade do cliente se mapeia para as regras de autorização
O certificado do cliente inclui um 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 corresponde ao valor após o prefixo spiffe://. Por exemplo, o valor test.client no campo principals corresponde a um certificado com URI.1 = spiffe://test.client.
Esse mapeamento é o mecanismo principal que conecta a autenticação mTLS ao controle de acesso baseado em caminho.
Pré-requisitos
Antes de começar, certifique-se de ter:
Injeção automática de sidecar ativada. Para mais informações, consulte Configure sidecar proxy injection policies
Ingress gateway e aplicativo httpbin implantados, com a porta 443 habilitada no ingress gateway. Para mais informações, consulte Deploy the httpbin application
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 os certificados do servidor e do cliente. O gateway apresenta o certificado do servidor para se identificar, e os clientes apresentam o certificado de cliente para comprovar sua identidade.
Ao preencher os campos do certificado durante a geração, aceite os valores padrão. Os arquivos de configuração abaixo já definem todos os campos necessá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 comando 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.clientUsado 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.csrEsse comando gera 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 Use the certificate management feature of ASM.Como alternativa, crie um Secret do Kubernetes diretamente. Execute o seguinte comando usando o kubeconfig do seu cluster do 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 contém 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 os certificados dos clientes
Etapa 2: Configurar o listener mTLS no gateway
Adicione um listener mTLS na porta 443 do ingress gateway 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 recurso 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 gateway não termina o TLS). 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 ingress gateway do ASM.A requisição falha com um erro de handshake TLS porque não há certificado de cliente. Isso confirma que o gateway exige 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 de clientes 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 o acesso da identidade test.client a um caminho específico. Isso não afeta os demais clientes.
Quando existem várias políticas de autorização na mesma carga de trabalho, o sistema avalia as políticas DENY antes das políticas ALLOW. O sistema rejeita qualquer requisição que corresponda a uma regra DENY, independentemente das regras ALLOW.
-
Implante o seguinte AuthorizationPolicy para negar o acesso de
test.clientao caminho/status/418no aplicativo httpbin. Para mais informações, consulte Configure authorization policies for HTTP requests.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 aplica-se ao ingress gateway (
istio: ingressgateway) e nega qualquer requisição do principaltest.clientpara o caminho/status/418. O valortest.clientno campoprincipalscorresponde ao URI SPIFFEspiffe://test.clientno SAN do certificado do cliente.
Verifique a política de autorização
-
Confirme se
test.clientainda pode 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 sistema nega o acesso de
test.clienta/status/418: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 o acesso detest.clienta este caminho. -
Confirme se uma identidade de cliente diferente ainda pode acessar
/status/418. Para isso, 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 bloqueia apenas a identidade
test.client. Outras identidades com certificados válidos ainda podem acessar/status/418.