TLS/SSL and PyMongo

    For connections using TLS/SSL, PyMongo may require third party dependencies as determined by your version of Python. With PyMongo 3.3+, you can install PyMongo 3.3+ and any TLS/SSL-related dependencies using the following pip command:

    Starting with PyMongo 3.11 this installs PyOpenSSL, and service_identity for users of Python versions older than 2.7.9. PyOpenSSL supports SNI for these old Python versions allowing applictions to connect to Altas free and shared tier instances.

    Earlier versions of PyMongo require you to manually install the dependencies listed below.

    The module is required on all platforms.

    When using CPython < 2.7.9 or PyPy < 2.5.1:

    • On Windows, the wincertstore module is required.
    • On all other platforms, the module is required.

    Warning

    Industry best practices recommend, and some regulations require, the use of TLS 1.1 or newer. Though no application changes are required for PyMongo to make use of the newest protocols, some operating systems or versions may not provide an OpenSSL version new enough to support them.

    Users of macOS older than 10.13 (High Sierra) will need to install Python from python.org, , macports, or another similar source.

    Users of Linux or other non-macOS Unix can check their OpenSSL version like this:

    If the version number is less than 1.0.1 support for TLS 1.1 or newer is not available. Contact your operating system vendor for a solution or upgrade to a newer distribution.

    You can check your Python interpreter by installing the module and executing the following command:

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

    You should see “TLS 1.X” where X is >= 1.

    https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols

    Basic configuration

    In many cases connecting to MongoDB over TLS/SSL requires nothing more than passing tls=True as a keyword argument to MongoClient:

      Or passing tls=true in the URI:

      1. >>> client = pymongo.MongoClient('mongodb://example.com/?tls=true')

      This configures PyMongo to connect to the server using TLS, verify the server’s certificate and verify that the host you are attempting to connect to is listed by that certificate.

      By default, PyMongo is configured to require a certificate from the server when TLS is enabled. This is configurable using the tlsAllowInvalidCertificates option. To disable this requirement pass tlsAllowInvalidCertificates=True as a keyword parameter:

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... tls=True,
      3. ... tlsAllowInvalidCertificates=True)

      Or, in the URI:

      Specifying a CA file

      In some cases you may want to configure PyMongo to use a specific set of CA certificates. This is most often the case when you are acting as your own certificate authority rather than using server certificates signed by a well known authority. The tlsCAFile option takes a path to a CA file. It can be passed as a keyword argument:

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... tlsCAFile='/path/to/ca.pem')

      Or, in the URI:

      1. >>> uri = 'mongodb://example.com/?tls=true&tlsCAFile=/path/to/ca.pem'
      2. >>> client = pymongo.MongoClient(uri)

      Python 2.7.9+ (pypy 2.5.1+) and 3.4+ provide support for certificate revocation lists. The tlsCRLFile option takes a path to a CRL file. It can be passed as a keyword argument:

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... tls=True,
      3. ... tlsCRLFile='/path/to/crl.pem')

      Or, in the URI:

      1. >>> uri = 'mongodb://example.com/?tls=true&tlsCRLFile=/path/to/crl.pem'

      Note

      Certificate revocation lists and OCSP cannot be used together.

      Client certificates

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... tls=True,

      If the private key for the client certificate is stored in a separate file use the ssl_keyfile option:

      Python 2.7.9+ (pypy 2.5.1+) and 3.3+ support providing a password or passphrase to decrypt encrypted private keys. Use the tlsCertificateKeyFilePassword option:

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... tls=True,
      3. ... tlsCertificateKeyFile='/path/to/client.pem',
      4. ... ssl_keyfile='/path/to/key.pem',
      5. ... tlsCertificateKeyFilePassword=<passphrase>)

      These options can also be passed as part of the MongoDB URI.

      Starting with PyMongo 3.11, if PyMongo was installed with the “ocsp” extra:

      1. python -m pip install pymongo[ocsp]

      certificate revocation checking is enabled by way of OCSP (Online Certification Status Protocol). MongoDB 4.4+ to the TLS handshake which PyMongo will verify, failing the TLS handshake if the stapled OCSP response is invalid or indicates that the peer certificate is revoked.

      When connecting to a server version older than 4.4, or when a 4.4+ version of MongoDB does not staple an OCSP response, PyMongo will attempt to connect directly to an OCSP endpoint if the peer certificate specified one. The TLS handshake will only fail in this case if the response indicates that the certificate is revoked. Invalid or malformed responses will be ignored, favoring availability over maximum security.

      Troubleshooting TLS Errors

      TLS errors often fall into three categories - certificate verification failure, protocol version mismatch or certificate revocation checking failure. An error message similar to the following means that OpenSSL was not able to verify the server’s certificate:

      1. [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

      This often occurs because OpenSSL does not have access to the system’s root certificates or the certificates are out of date. Linux users should ensure that they have the latest root certificate updates installed from their Linux vendor. macOS users using Python 3.6.0 or newer downloaded from python.org to install root certificates:

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

      Users of older PyPy portable versions may have to set an environment variable to tell OpenSSL where to find root certificates. This is easily done using the from pypi:

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

      An error message similar to the following message means that the OpenSSL version used by Python does not support a new enough TLS protocol to connect to the server:

      Industry best practices recommend, and some regulations require, that older TLS protocols be disabled in some MongoDB deployments. Some deployments may disable TLS 1.0, others may disable TLS 1.0 and TLS 1.1. See the warning earlier in this document for troubleshooting steps and solutions.

      An error message similar to the following message means that certificate revocation checking failed: