TLS/SSL and PyMongo

    For connections using TLS/SSL, PyMongo may require third party dependencies asdetermined by your version of Python. With PyMongo 3.3+, you can installPyMongo 3.3+ and any TLS/SSL-related dependencies using the following pipcommand:

    Earlier versions of PyMongo require you to manually install the dependencieslisted 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 forPyMongo to make use of the newest protocols, some operating systems orversions may not provide an OpenSSL version new enough to support them.

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

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

    1. $ openssl version

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

    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.

    You can read more about TLS versions and their security implications here:

    Basic configuration

    In many cases connecting to MongoDB over TLS/SSL requires nothing more thanpassing as a keyword argument to:

    1. >>> client = pymongo.MongoClient('example.com', ssl=True)

    Or passing in the URI:

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

      By default, PyMongo is configured to require a certificate from the server whenTLS is enabled. This is configurable using the ssl_cert_reqs option. Todisable this requirement pass as a keyword parameter:

      1. >>> import ssl
      2. >>> client = pymongo.MongoClient('example.com',
      3. ... ssl=True,
      4. ... ssl_cert_reqs=ssl.CERT_NONE)

      Or, in the URI:

      Specifying a CA file

      In some cases you may want to configure PyMongo to use a specific set of CAcertificates. This is most often the case when using “self-signed” servercertificates. The ssl_ca_certs option takes a path to a CA file. It can bepassed as a keyword argument:

      1. >>> client = pymongo.MongoClient('example.com',
      2. ... ssl=True,
      3. ... ssl_ca_certs='/path/to/ca.pem')
      1. >>> uri = 'mongodb://example.com/?ssl=true&ssl_ca_certs=/path/to/ca.pem'
      2. >>> client = pymongo.MongoClient(uri)

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

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

      Or, in the URI:

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

      Client certificates

      PyMongo can be configured to present a client certificate using thessl_certfile option:

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

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

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

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

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

      TLS errors often fall into two categories, certificate verification failure orprotocol version mismatch. An error message similar to the following means thatOpenSSL 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’sroot certificates or the certificates are out of date. Linux users shouldensure that they have the latest root certificate updates installed fromtheir Linux vendor. macOS users using Python 3.6.0 or newer downloadedfrom python.org to installroot certificates:

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

      Users of older PyPy portable versions may have to set an environmentvariable to tellOpenSSL 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())")
      1. [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version

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