Menu Docs
Página inicial do Docs
/ / /
PyMongo
/

Configurar o TLS (Transport Layer Security)

Nesta página

  • Visão geral
  • Habilitar TLS
  • Especifique um arquivo CA
  • Verifique a revogação do certificado
  • OCSP
  • Lista de revogação de certificados
  • Apresentar um Certificado de Cliente
  • Forneça uma senha de chave
  • Permitir TLS Inseguro
  • Solucionar problemas de TLS
  • CERTIFICATE_VERIFY_FAILED
  • TLSV1_ALERT_PROTOCOL_VERSION
  • Resposta de status inválida
  • SSLV3_ALERT_HANDSHAKE_FAILURE
  • Renegociação legada insegura desativada
  • Documentação da API

Neste guia, você aprenderá a usar o TLS protocolo para proteger sua conexão com um sistema do MongoDB .

Quando você habilita o TLS para uma conexão, o PyMongo executa as seguintes ações:

  • Usa TLS para se conectar ao MongoDB deployment

  • Verifica o certificado do sistema

  • Garante que o certificado certifique o sistema

Para saber como configurar seu sistema MongoDB para TLS, consulte o guia de configuração TLS no manual do MongoDB Server .

Importante

Uma descrição completa de certificados TLS/SSL, PKI (Public Key Infrastructure) e Autoridades de Certificação (CAs) está além do escopo deste documento. Esta página pressupõe conhecimento prévio de TLS/SSL e acesso a certificados válidos.

Para habilitar o TLS para a conexão com sua instância do MongoDB, defina a opção de conexão tls como True. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname:<port>", tls=True)
client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>?tls=true")

Dica

Se a string de conexão incluir a modificação +srv , que especifica o formato de conexão SRV, o TLS será habilitado na sua conexão por padrão.

Para saber mais sobre o formato de conexão SRV, consulte Formato de conexão SRV na documentação do MongoDB Server .

Durante a negociação TLS, o sistema do MongoDB apresenta um arquivo de chave de certificado para seu aplicativo para estabelecer sua identidade. Normalmente, o certificado de um sistema é assinado por uma CA conhecida, e seu aplicativo depende dessa CA para validar o certificado.

No entanto, durante os testes, você pode querer agir como sua própria CA. Nesse caso, você deve instruir o PyMongo a usar seus certificados de CA em vez dos assinados por outra CA.

Para fazer isso, use a opção de conexão tlsCAFile para especificar o caminho para um arquivo .pem que contém a cadeia de certificados raiz. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsCAFile="/path/to/ca.pem")
uri = "mongodb://<db_username>:<db_password>@<hostname>:<port>/?tls=true&tlsCAFile=/path/to/ca.pem"
client = pymongo.MongoClient(uri)

Quando um certificado X.509 não é mais confiável - por exemplo, se sua chave privada foi comprometida - a CA revoga o certificado. O PyMongo inclui duas maneiras de verificar se o certificado de um servidor foi revogado.

Para usar o Protocolo de Status do Certificado On-line (OCSP) para validar um certificado de servidor, você deve instalar o PyMongo com a opção ocsp , conforme mostrado no exemplo a seguir:

python -m pip install pymongo[ocsp]

O processo de validação do certificado varia dependendo da versão do MongoDB Server à qual você está se conectando:

  • MongoDB v4.4 ou posterior: o servidor grampeia uma resposta OCSP com registro de data e hora em seu certificado. O PyMongo valida o certificado em relação à resposta do OCSP. Se a CA tiver revogado o certificado ou se a resposta OCSP for inválida, a negociação TLS falhará.

  • MongoDB v4.3 ou anterior: o servidor fornece um endpoint OCSP, com o qual o PyMongo entra em contato diretamente. O PyMongo então valida o certificado em relação à resposta do OCSP. Se a CA não tiver revogado o certificado, a negociação TLS continuará, mesmo que a resposta OCSP seja inválida ou malformada.

Para impedir que o PyMongo entre em contato com o endpoint OCSP, defina a opção de conexão tlsDisableOCSPEndpointCheck como True. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsDisableOCSPEndpointCheck=True)
uri = "mongodb://example.com/?tls=true&tlsDisableOCSPEndpointCheck=true"
client = pymongo.MongoClient(uri)

Observação

Mesmo que a opção tlsDisableOCSPEndpointCheck esteja definida como True, o PyMongo ainda verificará qualquer resposta OCSP grampeada no certificado de um servidor.

Em vez de usar o OCSP, você pode instruir o PyMongo a verificar o certificado do servidor em relação a uma Lista de revogação de certificados (CRL) publicada pela CA. Para fazer isso, use a opção de conexão tlsCRLFile para especificar o caminho para um arquivo .pem ou .der da CA. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsCRLFile="/path/to/crl.pem")
uri = "mongodb://example.com/?tls=true&tlsCRLFile=/path/to/crl.pem"
client = pymongo.MongoClient(uri)

Observação

Você não pode usar um CRL e um OCSP no mesmo handshake TLS.

Algumas implementações do MongoDB exigem que cada aplicativo de conexão apresente um certificado de cliente que comprove sua identidade. Para especificar o certificado do cliente para o PyMongo apresentar, defina a opção tlsCertificateKeyFile para o caminho do arquivo .pem que contém seu certificado e chave privada. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsCertificateKeyFile='/path/to/client.pem')
uri = ("mongodb://<db_username>:<db_password>@<hostname:<port>/?"
"tls=true"
"&tlsCertificateKeyFile=path/to/client.pem")
client = pymongo.MongoClient(uri)

Importante

Seu certificado de cliente e chave privada devem estar no mesmo arquivo .pem . Se estiverem armazenados em arquivos diferentes, você deverá concatená-los. O exemplo a seguir mostra como concatenar um arquivo de chave e um arquivo de certificado em um terceiro arquivo chamado combined.pem em um sistema Unix:

$ cat key.pem cert.pem > combined.pem

Se a chave privada em seu arquivo de certificado estiver criptografada, você deverá fornecer uma senha. Para fazer isso, use a opção de conexão tlsCertificateKeyFilePassword para especificar a senha ou frase secreta para a chave privada criptografada. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname:<port>",
tls=True,
tlsCertificateKeyFile='/path/to/client.pem',
tlsCertificateKeyFilePassword=<passphrase>)
uri = ("mongodb://<db_username>:<db_password>@<hostname:<port>/?"
"tls=true"
"&tlsCertificateKeyFile=path/to/client.pem"
"&tlsCertificateKeyFilePassword=<passphrase>")
client = pymongo.MongoClient(uri)

Quando o TLS está habilitado, o PyMongo verifica automaticamente o certificado apresentado pelo servidor. Ao testar seu código, você pode desativar essa verificação. Isso é conhecido como TLS inseguro.

Quando o TLS inseguro está habilitado, o PyMongo exige apenas que o servidor apresente um certificado X.509 . O driver aceita um certificado mesmo que alguma das seguintes afirmações seja verdadeira:

  • O nome do host do servidor e o nome do assunto (ou nome alternativo do assunto) no certificado não correspondem.

  • O certificado expirou ou ainda não é válido.

  • O certificado não tem um certificado raiz confiável na cadeia.

  • A finalidade do certificado não é válida para identificação do servidor.

Observação

Mesmo quando o TLS inseguro está habilitado, a comunicação entre o cliente e o servidor é criptografada com TLS.

Para habilitar o TLS inseguro, defina a opção de conexão tlsInsecure como True. Você pode fazer isso de duas maneiras: passando um argumento para o construtor MongoClient ou por meio de um parâmetro em sua connection string.

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname:<port>",
tls=True,
tlsInsecure=True)
uri = ("mongodb://<db_username>:<db_password>@<hostname>:<port>/?"
"tls=true"
"&tlsInsecure=true")
client = pymongo.MongoClient(uri)

Para desabilitar somente a validação do certificado, defina a opção tlsAllowInvalidCertificates como True e defina a opção tlsInsecure como False ou omita-a:

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsAllowInvalidCertificates=True)
uri = ("mongodb://<db_username>:<db_password>@<hostname>:<port>/?"
"tls=true"
"&tlsAllowInvalidCertificates=true")
client = pymongo.MongoClient(uri)

Para desabilitar somente a verificação do nome de host, configure a opção tlsAllowInvalidHostnames para True e configure a opção tlsInsecure para False ou omita:

client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
tls=True,
tlsAllowInvalidHostnames=True)
uri = ("mongodb://<db_username>:<db_password>@<hostname>:<port>/?"
"tls=true"
"&tlsAllowInvalidHostnames=true")
client = pymongo.MongoClient(uri)

Aviso

Não use em produção

Sempre defina as opções tlsInsecure, tlsAllowInvalidCertificates e tlsAllowInvalidHostnames como False em produção.

Definir qualquer uma dessas opções como True em um ambiente de produção torna seu aplicativo desprotegido e potencialmente vulnerável a certificados expirados e a processos externos que se apresentam como instâncias de cliente válidas.

Uma mensagem de erro semelhante à seguinte significa que o OpenSSL não conseguiu verificar o certificado do servidor:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

Isso geralmente acontece porque o OpenSSL não consegue acessar os certificados raiz do sistema ou porque os certificados estão desatualizados.

Se você usar Linux, certifique-se de ter as atualizações de certificado raiz mais recentes instaladas do seu fornecedor de Linux.

Se você usa macOS e se está executando o Python v3.7 ou posterior baixado de python.org, execute o seguinte comando para instalar certificados raiz:

open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"

Dica

Para obter mais informações sobre este problema, consulte Problema do Python 29065.

Se você usar o embedded-pypy, talvez seja necessário definir uma variável de ambiente para informar ao OpenSSL onde encontrar certificados raiz. O seguinte exemplo de código mostra como instalar o módulo de certificação do PyPi e exporte a SSL_CERT_FILE variável de ambiente :

$ pypy -m pip install certifi
$ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")

Dica

Para obter mais informações sobre esse problema, consulte problema portátil-pypy 15.

Uma mensagem de erro semelhante à seguinte significa que a versão OpenSSL usada pelo Python não suporta um protocolo TLS novo o suficiente para se conectar ao servidor:

[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version

As melhores práticas do setor recomendam, e algumas regulamentações exigem, que os protocolos TLS mais antigos sejam desabilitados em algumas implantações do MongoDB. Algumas implantações podem desativar o TLS 1.0, enquanto outras podem desativar o TLS 1.0 e o TLS 1.1.

Nenhuma alteração no aplicativo é necessária para que o PyMongo use as versões mais recentes do TLS, mas algumas versões do sistema operacional podem não fornecer uma versão do OpenSSL nova o suficiente para habilitá-las.

Se você usa macOS v10.12 (High Sierra) ou anterior, instale o Python a partir de python.org, homebrew, macports ou uma fonte semelhante.

Se você usa Linux ou outro Unix não macOS, use o seguinte comando para verificar sua versão do OpenSSL:

$ openssl version

Se o comando anterior mostrar um número de versão inferior a 1.0.1, suporte para TLS 1.1 ou mais recente não está disponível. Atualize para uma versão mais recente ou entre em contato com o fornecedor do sistema operacional para obter uma solução.

Para verificar a versão TLS do seu interpretador Python, instale o módulo requests e execute o seguinte código:

python -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

Você deve ver TLS 1.1 ou posterior.

Uma mensagem de erro semelhante à seguinte significa que a verificação de revogação do certificado falhou:

[('SSL routines', 'tls_process_initial_server_flight', 'invalid status response')]

Para obter mais detalhes, consulte a seção OCSP deste guia.

Ao usar o Python v3.10 ou posterior com versões do MongoDB anteriores à v4.0, você pode ver erros semelhantes às seguintes mensagens:

SSL handshake failed: localhost:27017: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)
SSL handshake failed: localhost:27017: EOF occurred in violation of protocol (_ssl.c:997)

Os registros do MongoDB Server também podem mostrar o seguinte erro:

2021-06-30T21:22:44.917+0100 E NETWORK [conn16] SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher

Alterações feitas no módulo ssl no Python v3.10 pode causar incompatibilidades com versões do MongoDB anteriores à v4.0. Para resolver esse problema, tente uma ou mais das seguintes etapas:

  • Faça downgrade do Python para a3.9 ou anterior

  • Atualize o MongoDB Server para v4.2 ou posterior

  • Instalar o PyMongo com a opção OCSP , que depende do PyOpenSSL

Ao usar o OpenSSL v3 ou posterior, você poderá ver um erro semelhante à seguinte mensagem:

[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled

Esses tipos de erros ocorrem devido a proxies SSL desatualizados ou com erros que impõem erroneamente a renegociação do TLS legado .

Para resolver esse problema, execute as seguintes etapas:

1

Execute o seguinte comando para garantir que você tenha o OpenSSL vv3.0.4 ou posterior instalado:

openssl version
2

Crie um arquivo de configuração que inclua a opção UnsafeLegacyServerConnect. O exemplo seguinte mostra como configurar a opção UnsafeLegacyServerConnect:

openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
Options = UnsafeLegacyServerConnect
3

Execute o Python enquanto configura a variável de ambiente do OPENSSL_CONF para utilizar o arquivo de configuração OpenSSL que você acabou de criar:

OPENSSL_CONF=/path/to/the/config/file/above.cnf python ...

Importante

Como a UnsafeLegacyServerConnect configuração da opção tem implicações de segurança, use esta solução alternativa como último recurso para solucionar unsafe legacy renegotiation disabled erros.

Para saber mais sobre como configurar o TLS para o PyMongo, consulte a seguinte documentação da API:

Voltar

Especificar opções de conexão