A partir da versão 1.23, o Kubernetes não é mais compatível com a validação de identidade do servidor usando o campo X.509 Common Name (CN) nos certificados. Em vez disso, o Kubernetes confiará apenas nas informações dos campos X.509 Subject Alternative Name (SAN).
Para evitar impacto nos clusters, substitua certificados incompatíveis sem SANs para back-ends de webhooks e servidores de API agregados antes de fazer upgrade dos clusters para a versão 1.23 do Kubernetes.
Por que o Kubernetes não é mais compatível com certificados de back-end sem SANs
O GKE opera o Kubernetes de código aberto, que usa o componente kube-apiserver para entrar em contato com o webhook e os back-ends de servidores de API agregados usando o Transport Layer Security (TLS). O componente kube-apiserver é escrito na linguagem de programação Go.
Antes do Go 1.15, os clientes TLS validavam a identidade dos servidores aos quais se conectaram usando um processo de duas etapas:
- Verifique se o nome DNS (ou endereço IP) do servidor está presente como um dos SANs no certificado do servidor.
- Como substituto, verifique se o nome DNS (ou endereço IP) do servidor é igual ao CN do certificado do servidor.
A validação de identidade do servidor RFC 6125 baseada no campo CN foi totalmente suspensa em 2011. Navegadores e outros aplicativos essenciais para a segurança não usam mais o campo.
Para se alinhar ao ecossistema TLS mais amplo, o
Go 1.15 removeu a Etapa 2
do processo de validação, mas deixou uma chave de depuração (x509ignoreCN=0
) para permitir
que o comportamento antigo facilite o processo de migração. A versão 1.19 do Kubernetes foi
a primeira versão criada com o Go 1.15. Por padrão, os clusters do
GKE nas versões 1.19 a 1.22 ativaram a chave de depuração para oferecer aos clientes
mais tempo para substituir os certificados do webhook e dos back-ends de servidor de
APIs agregados afetados.
O Kubernetes versão 1.23 foi criado com o Go 1.17, que remove a chave de depuração. Depois que o GKE fizer upgrade dos clusters para a versão 1.23, as chamadas não serão conectadas do plano de controle do cluster para webhooks ou serviços de API agregados que não forneçam um certificado X.509 válido com SAN apropriado.
Como identificar clusters afetados
Para clusters que executam versões de patch pelo menos 1.21.9 ou 1.22.3
Para clusters nas versões de patch 1.21.9 e 1.22.3 ou mais recentes com o Cloud Logging ativado, o GKE fornece um registro dos Registros de auditoria do Cloud para identificar chamadas para back-ends afetados de seu cluster. Use o filtro a seguir para pesquisar os registros:
logName =~ "projects/.*/logs/cloudaudit.googleapis.com%2Factivity"
resource.type = "k8s_cluster"
operation.producer = "k8s.io"
"invalid-cert.webhook.gke.io"
Se os clusters não tiverem chamado back-ends com certificados afetados, você não verá nenhum registro. Se você vir um registro de auditoria desse tipo, ele incluirá o nome do host do back-end afetado.
Veja a seguir um exemplo da entrada de registro de um back-end de webhook hospedado por um serviço chamado example-webhook no namespace example-webhook:
{
...
resource {
type: "k8s_cluster",
"labels": {
"location": "us-central1-c",
"cluster_name": "example-cluster",
"project_id": "example-project"
}
},
labels: {
invalid-cert.webhook.gke.io/example-webhook.default.svc: "No subjectAltNames returned from example-webhook.default.svc:8443",
...
},
logName: "projects/example-project/logs/cloudaudit.googleapis.com%2Factivity",
operation: {
...
producer: "k8s.io",
...
},
...
}
Os nomes do host dos serviços afetados (por exemplo, example-webhook.default.svc
) são
incluídos como sufixos nos nomes dos rótulos que começam com invalid-cert.webhook.gke.io/
. Também é possível receber o nome do cluster que fez a chamada do
rótulo resource.labels.cluster_name
, que tem o valor example-cluster
neste exemplo.
Insights de descontinuação
Saiba quais clusters usam certificados incompatíveis em insights de descontinuação. Os insights estão disponíveis para clusters que executam a versão 1.22.6-gke.1000 ou mais recente.
Outras versões do cluster
Se você tiver um cluster em uma versão de patch anterior à 1.22 na versão secundária de 1.22 ou qualquer versão de patch anterior à 1.21.9, terá duas opções para determinar se o cluster foi afetado por essa suspensão de uso:
Opção 1 (recomendado): faça upgrade do cluster para uma versão de patch compatível com a identificação de certificados afetados com registros. Verifique se o Cloud Logging está ativado no cluster. Depois que o cluster for atualizado, os registros de auditoria do Cloud identificados serão produzidos sempre que o cluster tentar chamar um serviço que não forneça um certificado com um SAN adequado. Como os registros só serão produzidos em uma tentativa de chamada, recomendamos aguardar 30 dias após um upgrade para ter tempo suficiente para que todos os caminhos de chamada sejam invocados.
O uso de registros para identificar serviços afetados é recomendado porque essa abordagem minimiza o esforço manual, gerando registros automaticamente para mostrar os serviços afetados.
Opção 2: inspecione todos os certificados usados por webhooks ou serviços de API agregados nos clusters para determinar se eles foram afetados por não usar SANs:
- Veja a lista de webhooks e servidores de API agregados no cluster e identifique os back-ends deles (serviços ou URLs).
- Inspecione os certificados usados pelos serviços de back-end.
Considerando o esforço manual necessário para inspecionar todos os certificados dessa maneira, esse método só será seguido se você precisar avaliar o impacto das descontinuações no Kubernetes versão 1.23 antes de fazer upgrade do cluster para a versão 1.21. Se você puder fazer upgrade do cluster para a versão 1.21, faça primeiro o upgrade e, em seguida, siga as instruções da Opção 1 para evitar o esforço manual.
Como identificar serviços de back-end a serem inspecionados
Para identificar os back-ends que podem ser afetados pela suspensão de uso, receba a lista de webhooks e serviços de API agregados e os back-ends associados no cluster.
Para listar todos os webhooks relevantes no cluster, use os seguintes comandos
kubectl
:
kubectl get mutatingwebhookconfigurations -A # mutating admission webhooks
kubectl get validatingwebhookconfigurations -A # validating admission webhooks
Para receber um URL ou serviço de back-end associado a um determinado webhook,
examine o campo
clientConfig.service
ou
o campo
webhooks.clientConfig.url
na configuração
do webhook:
kubectl get mutatingwebhookconfigurations example-webhook -o yaml
A saída deste comando é semelhante a:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
webhooks:
- admissionReviewVersions:
clientConfig:
service:
name: example-service
namespace: default
port: 443
O clientConfig pode especificar o back-end como um Serviço do Kubernetes
(clientConfig.service
) ou um URL (clientConfig.url
).
Para listar todos os serviços de API agregados relevantes no cluster, use o seguinte
comando kubectl
:
kubectl get apiservices -A |grep -v Local # aggregated API services
A saída deste comando é semelhante a:
NAME SERVICE AVAILABLE AGE
v1beta1.metrics.k8s.io kube-system/metrics-server True 237d
Este exemplo retorna o serviço metric-server
a partir do namespace kube-system
.
É possível receber um serviço associado para determinada API agregada examinando
o campo spec.service
:
kubectl get apiservices v1beta1.metrics.k8s.io -o yaml
A saída deste comando é semelhante a:
...
apiVersion: apiregistration.k8s.io/v1
kind: APIService
spec:
service:
name: metrics-server
namespace: kube-system
port: 443
Como inspecionar o certificado de um serviço
Depois de identificar os serviços de back-end
relevantes para inspeção, é possível inspecionar o certificado de cada serviço específico,
como example-service
:
Encontre o seletor e a porta de destino do serviço:
kubectl describe service example-service
A saída deste comando é semelhante a:
Name: example-service Namespace: default Labels: run=nginx Selector: run=nginx Type: ClusterIP IP: 172.21.xxx.xxx Port: 443 TargetPort: 444
Neste exemplo,
example-service
tem o seletorrun=nginx
e a porta de destino444
.Encontre um pod que corresponda ao seletor:
kubectl get pods --selector=run=nginx
A saída deste comando é semelhante a:
NAME READY STATUS RESTARTS AGE example-pod 1/1 Running 0 21m
Configure um encaminhamento de portas
do seu localhost
kubectl
para o pod.kubectl port-forward pods/example-pod LOCALHOST_PORT:TARGET_PORT # port forwarding in background
Substitua o seguinte no comando:
LOCALHOST_PORT
: o endereço a ser detectado.TARGET_PORT
doTargetPort
da etapa 1.
Use
openssl
para imprimir o certificado usado pelo serviço:openssl s_client -connect localhost:LOCALHOST_PORT </dev/null | openssl x509 -noout -text
Este exemplo de saída mostra um certificado válido (com entradas SAN):
Subject: CN = example-service.default.svc X509v3 extensions: X509v3 Subject Alternative Name: DNS:example-service.default.svc
Este exemplo de saída mostra um certificado com uma SAN ausente:
Subject: CN = example-service.default.svc X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Authority Key Identifier: keyid:1A:5F:29:D8:E9:3C:54:3C:35:CC:D8:AB:D1:21:FD:C3:56:25:C0:74
Remova o encaminhamento de portas em execução em segundo plano com os seguintes comandos:
$ jobs [1]+ Running kubectl port-forward pods/example-pod 8888:444 & $ kill %1 [1]+ Terminated kubectl port-forward pods/example 8888:444
Como inspecionar o certificado de um back-end de URL
Se o webhook usar um back-end url
, conecte-se diretamente ao
nome do host especificado no URL. Por exemplo, se o URL for https://example.com:123/foo/bar
,
use o seguinte comando openssl
para imprimir o certificado usado pelo
back-end:
openssl s_client -connect example.com:123 </dev/null | openssl x509 -noout -text
Como minimizar o risco de upgrade 1,23
Depois de identificar os clusters afetados e os serviços de back-end usando certificados sem SANs, você precisa atualizar os webhooks e os back-ends de servidores de API agregados para usar certificados com SANs apropriados antes de fazer upgrade dos clusters para a versão 1.23.
O GKE não fará upgrade automático dos clusters nas versões 1.22.6-gke.1000 ou posterior com back-ends que usam certificados incompatíveis até que você substitua os certificados ou até que a versão 1.22 alcance o fim do suporte padrão.
Se o cluster estiver em uma versão do GKE anterior a 1.22.6-gke.1000, é possível impedir temporariamente os upgrades automáticos configurando uma exclusão de manutenção para evitar upgrades secundários.
Recursos
Consulte os seguintes recursos para mais informações sobre essa alteração:
- Notas de lançamento do Kubernetes 1.23
- O Kubernetes foi criado usando o Go 1.17. Essa versão do Go remove a
capacidade de usar uma configuração de ambiente
GODEBUG=x509ignoreCN=0
para reativar o comportamento legado descontinuado de tratar o CN dos certificados de exibição de X.509 como um nome de host.
- O Kubernetes foi criado usando o Go 1.17. Essa versão do Go remove a
capacidade de usar uma configuração de ambiente
- Notas de lançamento
do Kubernetes 1.19
e do Kubernetes 1.20
- O comportamento descontinuado do legado de tratar o campo CN nos certificados de exibição de X.509 como um nome de host quando não houver SANs está desativado por padrão.
- Notas de lançamento do Go 1.17
- A sinalização
GODEBUG=x509ignoreCN=0
temporária foi removida.
- A sinalização
- Notas de lançamento do Go 1.15
- O comportamento legado descontinuado de tratar o campo CN nos certificados X.509 como um host quando não há SANs está desativado por padrão.
- RFC 6125
(página 46)
- Embora o uso do valor de CN seja uma prática existente, ele está descontinuado.
As autoridades de certificação são incentivadas a fornecer valores
subjectAltName
.
- Embora o uso do valor de CN seja uma prática existente, ele está descontinuado.
As autoridades de certificação são incentivadas a fornecer valores
- Webhooks de admissão