トランスポート層セキュリティ (TLS) の構成
項目一覧
Overview
このガイドでは、 TLS の使用方法を説明します。 プロトコルを使用して、 MongoDBデプロイへの接続を保護します。
接続に TLS を有効にすると、PyMongo は次のアクションを実行します。
TLS を使用して MongoDB 配置に接続
配置の証明書を検証します
証明書が配置を認証することを確認する
MongoDBTLS 用の 配置の構成方法については、 マニュアルの「 TLS 構成ガイド MongoDB Server」を参照してください。
重要
TLS/SSL、PKI(公開鍵基盤)証明書、認証局(CA)の詳細な説明は、このドキュメントの範囲外です。 このページでは、TLS/SSL に関する事前の知識と、有効な証明書にアクセスすることを前提としています。
TLS の有効化
MongoDB インスタンスへの接続で TLS を有効にするには、 tls
接続オプションをTrue
に設定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname:<port>", tls=True)
client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>?tls=true")
Specify a CA File
TLS ハンドシェイク中に、MongoDB 配置は ID を確立するために、アプリケーションに証明書鍵ファイルを提示します。 通常、配置の証明書は既知の CA によって署名されており、アプリケーションはこの CA に依存して証明書を検証します。
ただし、テスト中は、独自の CA として動作する必要がある場合があります。 この場合、別の CA によって署名された証明書の代わりに CA 証明書を使用するように PyMongo に指示する必要があります。
そのためには、 tlsCAFile
接続オプションを使用して、ルート証明書チェーンを含む.pem
ファイルへのパスを指定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
証明書の失効を確認する
X. 509証明書が信頼できなくなった場合、たとえば、秘密キーが侵害された場合、CA は証明書を取り消します。 PyMongo には、サーバーの証明書が失効しているかどうかを確認する 2 つの方法が含まれています。
OCSP
OCSP(Online Certificate Status Protocol、オンライン証明書ステータス プロトコル)を使用してサーバー証明書を検証するには、次の例に示すように、 ocsp
オプションを指定して PyMongo をインストールする必要があります。
python -m pip install pymongo[ocsp]
証明書検証プロセスは、接続する MongoDB Server のバージョンによって異なります。
MongoDB v 4.4以降:サーバーはタイムスタンプ付きの OCSP 応答を証明書にステープリングします。 PyMongo は OCSP 応答に対して証明書を検証します。 CA によって証明書が取り消されている場合、または OCSP 応答がその他の方法で無効な場合、TLS ハンドシェイクは失敗します。
MongoDB v 4.3またはそれ以前:サーバーは PyMongo が直接接続する OCSP エンドポイントを提供します。 次に、PyMongo は OCSP 応答に対して証明書を検証します。 CA が証明書を取り消していない場合、OCSP 応答が無効または不正であっても、TLS ハンドシェイクは続行されます。
PyMongo が OCSP エンドポイントへの接続を停止するには、 tlsDisableOCSPEndpointCheck
接続オプションをTrue
に設定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
注意
tlsDisableOCSPEndpointCheck
オプションがTrue
に設定されている場合でも、PyMongo はサーバーの証明書にステープリングされた OCSP 応答を検証します。
証明書失効リスト
OCSP を使用する代わりに、CA によって公開された証明書失効リスト(CRL)でサーバーの証明書を確認するように PyMongo に指示できます。 そのためには、 tlsCRLFile
接続オプションを使用して、CA からの.pem
または.der
ファイルへのパスを指定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
注意
同じ TLS ハンドシェイクで、CRL とOCSPの両方を使用することはできません。
クライアント証明書の提示
一部の MongoDB 配置では、接続するすべてのアプリケーションが ID を証明するクライアント証明書を提示する必要があります。 PyMongo が提示するクライアント証明書を指定するには、証明書と秘密キーを含む.pem
ファイルのファイル パスにtlsCertificateKeyFile
オプションを設定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
重要
クライアント証明書と秘密キーは同じ.pem
ファイル内になければなりません。 異なるファイルに保存されている場合は、それらを連結する必要があります。 次の例は、キー ファイルと証明書ファイルを Unix システム上のcombined.pem
という 3 つ目のファイルに連結する方法を示しています。
cat key.pem cert.pem > combined.pem
キー パスワードの入力
証明書ファイル内の秘密キーが暗号化されている場合は、パスワードを入力する必要があります。 そのためには、 tlsCertificateKeyFilePassword
接続オプションを使用して、暗号化された秘密キーのパスワードまたはパスフレーズを指定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
AllowInsecureTls
TLS が有効になっている場合、PyMongo はサーバーが提示した証明書を自動的に検証します。 コードをテストするときは、この検証を無効にできます。 これは安全でない TLS と呼ばれます。
安全でない TLS が有効になっている場合、PyMongo では X. 509証明書の提示のみが必要になります。 次のいずれかに当てはまる場合でも、ドライバーは証明書を受け入れます。
サーバーのホスト名と証明書のサブジェクト名(またはサブジェクトの別名)が一致しません。
証明書の有効期限が切れているか、まだ有効ではありません。
証明書のチェーン内に信頼できるルート証明書がありません。
証明書の目的がサーバー識別には無効です。
注意
安全でない TLS が有効になっている場合でも、クライアントとサーバー間の通信は TLS で暗号化されます。
安全でない TLS を有効にするには、 tlsInsecure
接続オプションをTrue
に設定します。 これは、MongoClient
コンストラクターに引数を渡す方法と、 接続stringのパラメーターを使用する方法の 2 つがあります。
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)
証明書の検証のみを無効にするには、 tlsAllowInvalidCertificates
オプションをTrue
に設定し、 tlsInsecure
オプションをFalse
に設定するか、省略します。
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)
ホスト名検証のみを無効にするには、 tlsAllowInvalidHostnames
オプションをTrue
に設定し、 tlsInsecure
オプションをFalse
に設定するか、省略します。
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)
警告
本番環境では を使用しないでください
本番環境では、 tlsInsecure
、 tlsAllowInvalidCertificates
、 tlsAllowInvalidHostnames
オプションは常にFalse
に設定します。
本番環境でこれらのオプションのいずれかをTrue
に設定すると、アプリケーションは安全でなくなり、期限切れの証明書や有効なクライアント インスタンスとみなされる外部プロセスに対して脆弱になる可能性があります。
TLS のトラブルシューティング
CERTTICATE_VERIFY_FAILED
次のようなエラー メッセージは、OpenSSL がサーバーの証明書を検証できなかったことを意味します。
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
これは、OpenSSL がシステムのルート証明書にアクセスできないか、証明書が古くなっているために多く発生します。
Linux を使用する場合は、Linux ベンダーから最新のルート証明書の更新がインストールされていることを確認してください。
macOS を使用しており、python.org からダウンロードした Python v 3.7以降を実行している場合は、 ルート証明書をインストールするには、次のコマンドを実行します。
open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"
Tip
この問題の詳細については、 Python の問題29065 を参照してください。
port-pypy を使用する場合は、OpenSSL にルート証明書を見つける場所を指示するために環境変数を設定する必要がある場合があります。 次のコード例は、 認証モジュール をインストールする方法を示しています から Pypi に接続し、SSL_CERT_FILE
環境変数をエクスポートします。
$ pypy -m pip install certifi $ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")
Tip
この問題の詳細については、 port-pypy の問題15 を参照してください。
TLSV 1 _ALERT_PROTOCOL_VERSION
次のようなエラーメッセージが表示された場合、Python で使用される OpenSSL バージョンでは、サーバーに接続するのに十分な新しい TLS プロトコルがサポートされていないことを意味します。
[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version
業界のベストプラクティスでは、一部の MongoDB の配置で古い TLS プロトコルを無効にすることが推奨されています。また、一部の規則では、古い TLS プロトコルを無効にすることが推奨されています。 一部の配置では TLS 1.0が無効になり、他の配置では TLS 1.0および TLS 1.1が無効になる場合があります。
PyMongo が最新の TLS バージョンを使用するためにアプリケーションを変更する必要はありませんが、一部のオペレーティング システムのバージョンでは、それらをサポートするのに十分な新しい OpenSSL バージョンが提供されていない場合があります。
macOS v 10.12を使用している場合 (High Sierra)またはそれ以前の場合は、 python.org から Python をインストールします。 Homebrew、macports、または同様のソース。
Linux またはその他の macOS Unix を使用している場合は、次のコマンドを使用して OpenSSL バージョンを確認します。
openssl version
上記のコマンドで1.0.1未満のバージョン番号が表示されている場合、 TLS 1.1以降のサポートは利用できません。 新しいバージョンにアップグレードするか、OS ベンダーに解決策について問い合わせてください。
Python インタープリタの TLS バージョンを確認するには、 requests
モジュールをインストールして次のコードを実行します。
python -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"
TLS 1.1以降が表示されます。
無効なステータス応答
次のようなエラー メッセージが表示された場合、証明書失効チェックに失敗したことを意味します。
[('SSL routines', 'tls_process_initial_server_flight', 'invalid status response')]
詳細については、このガイドの「 OCSP 」セクションを参照してください。
SSLV 3 _ALERT_HANDSHAKE_FAILURE
Python v 3.10以降を v 4.0より前のバージョンの MongoDB で使用する場合、 次のメッセージのようなエラーが表示される場合があります。
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)
MongoDB Server ログには、次のエラーも表示される場合があります。
2021-06-30T21:22:44.917+0100 E NETWORK [conn16] SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
Python v で ssl モジュールに加えられた変更3.10は v 4より前のバージョンの MongoDB と互換性がない可能性があります。 0 。 この問題を解決するには、次の手順の 1 つ以上を試してください。
Python を v 3.9またはそれ以前のバージョンにダウングレード
MongoDB Server を v 4.2以降にアップグレードする
OCSPオプションを使用して PyMongo をインストールする(PyOpenSSL に依存する)
レガシー再ネゴシエートが無効
OpenSSL v 3 以降を使用している場合、次のメッセージのようなエラーが表示される場合があります。
[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled
このようなエラーは、レガシーTLS 再ネゴシエートを誤って強制する、古くなった、またはバグのある SSL プロキシが原因で発生します。
この問題を解決するには、次の手順を実行します。
重要
UnsafeLegacyServerConnect
オプションを設定すると セキュリティ上の影響 があるため、 エラーに対処するための最後の手段としてこの回避策を使用してください。unsafe legacy renegotiation disabled
API ドキュメント
PyMongo の TLS 構成の詳細については、次の API ドキュメントを参照してください。