Boas práticas de autenticação service-to-service com mTLS
1. Fundamentos do mTLS para comunicação entre serviços
O Mutual Transport Layer Security (mTLS) é uma extensão do protocolo TLS que estabelece autenticação bidirecional entre serviços. Diferentemente do TLS tradicional, onde apenas o servidor apresenta um certificado para validação pelo cliente, no mTLS ambos os lados da conexão devem apresentar e validar certificados mutuamente.
A cadeia de confiança no mTLS é composta por três elementos principais: uma Autoridade Certificadora (CA) raiz que emite certificados intermediários, certificados de servidor que identificam o serviço receptor, e certificados de cliente que autenticam o serviço originador. Durante o handshake mTLS, ocorre a seguinte sequência:
Cliente Servidor
| |
|--- ClientHello --------------->|
|<--- ServerHello + Cert -------|
|<--- CertificateRequest -------|
|--- ClientCertificate -------->|
|--- ClientVerify -------------->|
|--- ChangeCipherSpec --------->|
|--- Finished ----------------->|
|<--- ChangeCipherSpec ---------|
|<--- Finished -----------------|
| |
|<====== Canal Criptografado ===>|
Cada serviço verifica se o certificado recebido foi assinado por uma CA confiável, se não está expirado e se o CN (Common Name) ou SAN (Subject Alternative Name) corresponde à identidade esperada.
2. Planejamento da infraestrutura de PKI
Para ambientes de produção, a escolha entre CA interna e CA pública depende do contexto. CAs internas como HashiCorp Vault ou cert-manager no Kubernetes oferecem controle total sobre o ciclo de vida dos certificados, enquanto CAs públicas (Let's Encrypt, DigiCert) são mais adequadas para serviços expostos externamente.
O ciclo de vida do certificado deve ser gerenciado com automação:
# Exemplo de política de ciclo de vida
- Emissão: Automática via cert-manager ou Vault PKI
- Renovação: 30 dias antes da expiração (para certificados de 90 dias)
- Revogação: Imediata em caso de comprometimento
- Rotação: Chaves regeneradas a cada renovação
Para identificação de serviços, adote uma estrutura de nomes padronizada:
CN: service-name.namespace.svc.cluster.local
SANs:
- DNS: service-name.namespace.svc.cluster.local
- DNS: service-name.namespace.svc
- DNS: service-name
3. Distribuição segura e armazenamento de certificados
A distribuição de certificados deve seguir o princípio do menor privilégio. No Kubernetes, utilize Secrets montados como volumes ou injetados via CSI drivers:
apiVersion: v1
kind: Secret
metadata:
name: mTLS-certificates
namespace: production
type: kubernetes.io/tls
data:
tls.crt: <certificado-base64>
tls.key: <chave-privada-base64>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-service
spec:
template:
spec:
containers:
- name: app
volumeMounts:
- name: mTLS-certs
mountPath: /etc/mTLS/certs
readOnly: true
volumes:
- name: mTLS-certs
secret:
secretName: mTLS-certificates
defaultMode: 0400
Para proteção de chaves privadas, implemente:
- Permissões de arquivo 0400 (apenas leitura para o proprietário)
- Criptografia em repouso usando KMS ou Vault Transit
- Rotação automática a cada 30-90 dias
- Armazenamento em HSM (Hardware Security Module) para ambientes críticos
4. Validação e controle de acesso no mTLS
A validação estrita de identidade deve verificar se o CN/SAN corresponde exatamente ao serviço esperado:
# Exemplo de validação em Go
func validatePeerCertificate(conn *tls.Conn, expectedService string) error {
certs := conn.ConnectionState().PeerCertificates
if len(certs) == 0 {
return fmt.Errorf("nenhum certificado apresentado")
}
// Verificar CN
if certs[0].Subject.CommonName != expectedService {
return fmt.Errorf("CN inválido: esperado %s, recebido %s",
expectedService, certs[0].Subject.CommonName)
}
// Verificar SANs
for _, san := range certs[0].DNSNames {
if san == expectedService {
return nil
}
}
return fmt.Errorf("SAN não encontrada para %s", expectedService)
}
Para revogação, prefira OCSP (Online Certificate Status Protocol) sobre CRLs (Certificate Revocation Lists), pois oferece verificação em tempo real:
# Configuração de OCSP stapling no NGINX
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/mTLS/ca-chain.crt;
resolver 8.8.8.8 valid=300s;
Combine mTLS com RBAC baseado em claims do certificado:
# Mapeamento de certificado para permissões
{
"service-a.production.svc": ["read:payments", "write:logs"],
"service-b.production.svc": ["read:payments"],
"monitoring.production.svc": ["read:*"]
}
5. Performance e resiliência da autenticação mTLS
O handshake mTLS adiciona latência devido à troca de certificados e verificação criptográfica. Para mitigar esse impacto:
# Configuração de keep-alive e reutilização de sessão
TLSConfig:
MinVersion: TLSv1.3
SessionTicketsDisabled: false
SessionCache:
Capacity: 10000
Expiration: 3600 # 1 hora
HandshakeTimeout: 5s
KeepAlive:
Enabled: true
Interval: 30s
Timeout: 10s
MaxIdleConnections: 100
Implemente renovação proativa para evitar falhas de expiração:
# Algoritmo de renovação antecipada
if daysUntilExpiration <= 30:
iniciarRenovacao()
if renovacaoFalhou:
manterCertificadoAtual
agendarRetry(5 minutos)
elif diasRestantes == 0:
emitirAlertaCritico()
usarFallbackSeguro()
6. Monitoramento e operação contínua
Adote métricas RED (Rate, Errors, Duration) específicas para mTLS:
# Métricas essenciais
mtls_handshake_total{status="success"} # Taxa de handshakes bem-sucedidos
mtls_handshake_errors_total{reason="expired"} # Erros por certificado expirado
mtls_handshake_duration_seconds # Latência do handshake
mtls_certificate_expiry_days # Dias até expiração
mtls_revocation_checks_total # Verificações de revogação
Configure alertas para:
- Certificados com menos de 14 dias para expiração (warning)
- Certificados com menos de 7 dias para expiração (critical)
- Taxa de erros de handshake > 1% em 5 minutos
- Falhas de verificação OCSP/CRL
Logs de auditoria devem registrar:
2025-01-15T10:30:00Z [AUDIT] mTLS connection established
Source: payment-service.production.svc
Target: database-service.production.svc
Certificate Serial: 0xABCD1234
Expiry: 2025-04-15T10:30:00Z
CA: vault-ca.production.internal
2025-01-15T10:30:01Z [AUDIT] mTLS connection rejected
Source: unknown-service.staging.svc
Reason: Certificate not trusted by CA
Certificate Serial: 0xDEADBEEF
7. Integração com malhas de serviço e gateways
Malhas de serviço como Istio e Linkerd simplificam a implementação de mTLS:
# Istio PeerAuthentication para mTLS estrito
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT # STRICT, PERMISSIVE, DISABLE
portLevelMtls:
8080:
mode: STRICT
Para gateways de API, configure mTLS no Envoy:
# Configuração Envoy para mTLS
static_resources:
listeners:
- name: external_api
address:
socket_address:
address: 0.0.0.0
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
config:
stat_prefix: ingress_http
route_config:
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: backend_service
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
filename: /etc/mTLS/server.crt
private_key:
filename: /etc/mTLS/server.key
validation_context:
trusted_ca:
filename: /etc/mTLS/ca.crt
match_subject_alt_names:
- exact: "allowed-client.service.consul"
Para adoção gradual, utilize o modo permissivo:
# Transição gradual para mTLS
Fase 1: PERMISSIVE (aceita conexões com e sem TLS)
- Monitorar tráfego não criptografado
- Identificar serviços que precisam de atualização
Fase 2: PERMISSIVE com alertas
- Rejeitar conexões não TLS em ambiente de staging
- Gerar alertas para tráfego inseguro
Fase 3: STRICT
- Exigir mTLS para todas as conexões
- Validar identidades de todos os serviços
O mTLS bem implementado oferece autenticação forte, confidencialidade e integridade para comunicação entre serviços, sendo um pilar fundamental para arquiteturas de microsserviços seguras e resilientes.
Referências
- Mutual TLS (mTLS) - Cloudflare Learning Center — Explicação detalhada do funcionamento do mTLS e casos de uso em ambientes corporativos
- Istio Security: Mutual TLS Authentication — Documentação oficial do Istio sobre configuração e operação de mTLS em malhas de serviço
- HashiCorp Vault PKI Secrets Engine — Guia completo para gerenciamento de PKI interna com Vault, incluindo emissão e renovação automática
- cert-manager Documentation: ACME Certificates — Documentação oficial do cert-manager para automação de certificados TLS/mTLS no Kubernetes
- Envoy Proxy: TLS Configuration — Referência técnica para configuração de mTLS em gateways e sidecars Envoy
- Linkerd: Automatic mTLS — Como o Linkerd implementa mTLS transparente para todos os serviços na malha
- NIST SP 800-52: Guidelines for TLS Implementations — Diretrizes do NIST para implementação segura de TLS, incluindo recomendações para mTLS