No dia 30 de maio de 2020, vivenciamos uma situação rara na infraestrutura pública-chave da Internet: dois dos certificados principais expiraram, sendo cada um deles emitido pela outra autoridade de verificação SSL.
Teóricamente, isso não é nada incomum. Os certificados expiram constantemente (normalmente em um ano ou até mesmo em 90 dias, se você usar o Let’s Encrypt), e os certificados das entidades de certificação expiram após alguns anos. Mas em 30 de maio, a entidade de certificação que estava prestes a expirar abordou um problema fundamental que fez com que nossa API não estivesse disponível para alguns de nossos clientes.
No dia 30 de maio, quando os certificados das autoridades de certificação expiraram, recebemos pedidos de suporte informando que havia um problema com o certificado do nosso serviço. Essa foi uma notícia inesperada, pois nós verificamos cuidadosamente se nossos certificados estavam válidos e não estavam prestes a expirar em um prazo razoável. Uma verificação rápida no navegador também confirmou que tudo parecia estar normal e que a API estava respondendo corretamente.
Ao analisar as estatísticas da nossa infraestrutura, percebemos que o número de chamadas à API diminuiu, mas isso estava longe de ser zero, como seria de esperar em caso de falha completa do SSL. Quando as coisas não funcionam completamente, é frequentemente mais fácil identificar o que não funciona do que em situações em que algumas coisas funcionam e outras não.
Uma análise abrangente revelou, finalmente, que também outros serviços na Internet apresentaram problemas. Rapidamente descobrimos as causas: https://support.sectigo.com/articles/Knowledge/Sectigo-AddTrust-External-CA-Root-Expiring-May-30-2020
- O certificado da nossa entidade de certificação intermediária, a Sectigo RSA Organization Validation Secure Server CA, era válido.
- No caminho 1, o certificado de raiz USERTrust RSA Certification Authority era válido e toda a cadeia era válida.
- No caminho 2, o certificado da nossa autoridade de certificação principal, a USERTrust RSA Certification Authority, expirou em 30 de maio às 10:48 UTC.
- O certificado da Autoridade de Certificação de Raiz AddTrust, que cruzou a assinatura do certificado do USERTrust RSA, expirou em 30 de maio às 10:48 UTC.
Esta foi uma situação interessante. Existia um caminho válido para a Autoridade de Certificação RSA do USERTrust, e também existia um caminho expirado. O navegador era capaz de encontrar a cadeia válida, mas a ferramenta não conseguiu encontrá-la. O teste da Quality SSL Labs mostrou que o sistema funcionava e que a configuração de certificado funcionava perfeitamente.
Nossa equipe iniciou a segunda alteração de nosso certificado público e tentou restaurar o serviço para os clientes remanescentes, e pouco depois do seu lançamento confirmou a eles que poderiam retomar o serviço. O incidente havia finalmente terminado, e o serviço foi restaurado para todos os clientes. Mas por que alguns de nossos clientes perderam o acesso em primeiro lugar, quando até mesmo o verificador de SSL afirma que o certificado é válido?
O certificado era, de fato, válido, e toda a cadeia de certificados foi gerada de forma razoavelmente correta pela certificadora Comodo/Sectigo (o armazenamento de certificados durante o fim de semana não é uma prática recomendável). O que não estava previsto era a forma como as bibliotecas de clientes lidarão com essa situação, principalmente o OpenSSL, que é utilizado pela grande maioria do HTTPS no mundo. Ao analisar o incidente, descobrimos um interessante erro do OpenSSL de 2014 que diz:
Não use certificados com data de validade vencida, se possível.
Fonte: https://github.com/openssl/openssl/commit/0930251df814f3993bf2c598761e0c7c6d0d62a2
Ao procurar o emitente de um certificado, se o candidato atual tiver expirado, continue a procurar. Retorne apenas um certificado expirado se não forem encontrados certificados válidos.
Isso significa que antes da implementação dessa alteração, o OpenSSL, sempre que detecta um certificado inválido na cadeia, declara o certificado inválido e rejeita a conexão. Depois que essa alteração foi implementada, o OpenSSL ignora o certificado vencido e continua procurando certificados adicionais que possam comprovar que o certificado é válido. Essa pequena alteração se adapta à forma da cadeia de certificados – uma única autoridade de certificação pode ser assinada por várias autoridades de certificação, algumas das quais ainda são válidas e outras não mais. Tudo parece ótimo, então por que as implicações?
Se você continuar a pesquisar, essa alteração no OpenSSL é apenas uma parte do OpenSSL 1.1.1 e não parte do OpenSSL 1.0.x. Isso significa, por exemplo, que todas as versões do Ubuntu 16.04 e posteriores, do Debian 9 e posteriores, do CentOS 7 e posteriores ou do RedHat 7 e posteriores estão afetadas, mas todas elas ainda são versões amplamente suportadas, pelo menos do ponto de vista da segurança.
Mas por que os navegadores verificaram corretamente os certificados? Os navegadores são fornecidos com suas próprias bibliotecas SSL/TLS e seus próprios métodos para verificar a PKI. O Chrome é fornecido com o BoringSSL e o Firefox com o NSS, independentemente das bibliotecas SSL/TLS do sistema operacional subjacente, não apresenta o mesmo problema e é atualizado com muito mais frequência.
E agora finalmente temos uma imagem completa do que aconteceu e por que apenas algumas implementações de back-end de alguns clientes foram afetadas e por que alguns sistemas apresentaram armazenamento de certificados desatualizado, necessitando de um certificado principal muito mais antigo.
Como proceder? Estamos contactando os clientes afetados e explicando o que aconteceu. Estamos a melhorar a nossa ferramenta de verificação de certificados para verificar o processo em toda a cadeia, e não apenas o nosso certificado.
FAQ
A indisponibilidade do serviço foi causada por um problema nos servidores do LOX24?
Não, o serviço continuou a funcionar e só estava disponível para sistemas antigos.
O que deveria eu fazer para evitar que uma situação semelhante ocorra no futuro com o LOX24 ou outros serviços?
Atualize seu OpenSSL para pelo menos a versão 1.1.1 e o LibreSSL para pelo menos a versão 3.2.0. Atualize também seus repositórios de certificados, no Linux muitas vezes chamado de pacote „ca-certificates“.
O certificado do LOX24 já expirou?
Não, o certificado da LOX24 não expirou e ainda está válido. O que expirou foi uma das 3 versões dos certificados de CA das entidades certificadoras que assinaram nosso certificado.
Algum outro fornecedor foi afetado ou o problema era específico do LOX24?
Infelizmente, também havia outros fornecedores afetados: Heroku, Stripe, kernel.org, Datadog, Gandi.net e muitos outros.
