|
| 1 | +.. _scala-tls: |
| 2 | + |
| 3 | +======= |
| 4 | +TLS/SSL |
| 5 | +======= |
| 6 | + |
| 7 | +.. facet:: |
| 8 | + :name: genre |
| 9 | + :values: reference |
| 10 | + |
| 11 | +.. meta:: |
| 12 | + :keywords: code example, certificate, authenticate |
| 13 | + |
| 14 | +.. contents:: On this page |
| 15 | + :local: |
| 16 | + :backlinks: none |
| 17 | + :depth: 2 |
| 18 | + :class: singlecol |
| 19 | + |
| 20 | +By default, the driver supports TLS/SSL connections to MongoDB |
| 21 | +servers using the underlying support for TLS/SSL provided by the JDK. |
| 22 | +This can be changed by utilizing the extensibility of the `Java SE |
| 23 | +API <https://docs.oracle.com/javase/8/docs/api/>`__. |
| 24 | + |
| 25 | +MongoClient API |
| 26 | +--------------- |
| 27 | + |
| 28 | +You can configure the driver to use |
| 29 | +TLS/SSL by specifying options in a ``ConnectionString`` or in a |
| 30 | +``MongoClientSettings`` instance. |
| 31 | + |
| 32 | +Specify TLS/SSL in ConnectionString |
| 33 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 34 | + |
| 35 | +Include the following import statements: |
| 36 | + |
| 37 | +.. code-block:: scala |
| 38 | + |
| 39 | + import org.mongodb.scala._ |
| 40 | + |
| 41 | +To specify TLS/SSL in a ``ConnectionString``, specify ``ssl=true`` as |
| 42 | +part of the connection string: |
| 43 | + |
| 44 | +.. code-block:: scala |
| 45 | + |
| 46 | + val mongoClient: MongoClient = MongoClient("mongodb://localhost/?ssl=true") |
| 47 | + |
| 48 | +Specify TLS/SSL in MongoClientSettings |
| 49 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 50 | + |
| 51 | +Include the following import statements: |
| 52 | + |
| 53 | +.. code-block:: scala |
| 54 | + |
| 55 | + import org.mongodb.scala._ |
| 56 | + |
| 57 | +To specify TLS/SSL in a ``MongoClientSettings`` instance, set the |
| 58 | +``enabled`` property to ``true``: |
| 59 | + |
| 60 | +.. code-block:: scala |
| 61 | + |
| 62 | + val settings = MongoClientSettings.builder() |
| 63 | + .applyToSslSettings((builder: SslSettings.Builder) => builder.enabled(true)) |
| 64 | + .build() |
| 65 | + val client = MongoClient(settings) |
| 66 | + |
| 67 | +Specify Java SE SSLContext in MongoClientSettings |
| 68 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 69 | + |
| 70 | +Include the following import statements: |
| 71 | + |
| 72 | +.. code-block:: scala |
| 73 | + |
| 74 | + import javax.net.ssl.SSLContext |
| 75 | + |
| 76 | +To specify the ``javax.net.ssl.SSLContext`` with |
| 77 | +``MongoClientSettings``, set the ``sslContext`` property: |
| 78 | + |
| 79 | +.. code-block:: scala |
| 80 | + |
| 81 | + val sslContext: SSLContext = ... |
| 82 | + val settings = MongoClientSettings.builder() |
| 83 | + .applyToSslSettings((builder: SslSettings.Builder) => { |
| 84 | + builder.enabled(true) |
| 85 | + builder.context(sslContext) |
| 86 | + }) |
| 87 | + .build() |
| 88 | + val client = MongoClient(settings) |
| 89 | + |
| 90 | +Disable Hostname Verification |
| 91 | +----------------------------- |
| 92 | + |
| 93 | +By default, the driver ensures that the hostname included in the |
| 94 | +server's SSL certificate matches the hostname provided when |
| 95 | +constructing a ``MongoClient``. |
| 96 | + |
| 97 | +If your application needs to disable hostname verification, you must |
| 98 | +explicitly indicate this in ``MongoClientSettings``: |
| 99 | + |
| 100 | +.. code-block:: scala |
| 101 | + |
| 102 | + val settings = MongoClientSettings.builder() |
| 103 | + .applyToSslSettings((builder: SslSettings.Builder) => { |
| 104 | + builder.enabled(true) |
| 105 | + builder.invalidHostNameAllowed(true) |
| 106 | + }) |
| 107 | + .build() |
| 108 | + |
| 109 | +Common TLS/SSL Configuration Tasks |
| 110 | +---------------------------------- |
| 111 | + |
| 112 | +This section is based on the documentation for `Oracle JDK |
| 113 | +<https://www.oracle.com/java/technologies/downloads/#JDK8>`__, so some |
| 114 | +parts may be inapplicable to your JDK or the custom TLS/SSL |
| 115 | +implementation that you use. |
| 116 | + |
| 117 | +Configure Trust Store and Key Store |
| 118 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 119 | + |
| 120 | +You might configure trust stores and key stores specific to the |
| 121 | +client by using ``javax.net.ssl.SSLContext.init(KeyManager[] km, |
| 122 | +TrustManager[] tm, SecureRandom random)``, or you might set the JVM default |
| 123 | +ones. |
| 124 | + |
| 125 | +Set the Default Trust Store |
| 126 | +``````````````````````````` |
| 127 | + |
| 128 | +A typical application will need to set several JVM system properties |
| 129 | +to ensure that the client can *validate* the TLS/SSL |
| 130 | +certificate presented by the server: |
| 131 | + |
| 132 | +- ``javax.net.ssl.trustStore``: the path to a trust store containing the |
| 133 | + certificate of the signing authority |
| 134 | +- ``javax.net.ssl.trustStorePassword``: the password to access this |
| 135 | + trust store |
| 136 | + |
| 137 | +The trust store is typically created with the ``keytool`` command-line |
| 138 | +program provided as part of the JDK: |
| 139 | + |
| 140 | +.. code-block:: bash |
| 141 | + |
| 142 | + keytool -importcert -trustcacerts -file <path to certificate authority file> |
| 143 | + -keystore <path to trust store> -storepass <trust store password> |
| 144 | + |
| 145 | +Set the Default Key Store |
| 146 | +````````````````````````` |
| 147 | + |
| 148 | +A typical application will also need to set several JVM system |
| 149 | +properties to ensure that the client *presents* a TLS/SSL client |
| 150 | +certificate to the MongoDB server: |
| 151 | + |
| 152 | +- ``javax.net.ssl.keyStore``: the path to a key store containing the |
| 153 | + clients TLS/SSL certificates |
| 154 | +- ``javax.net.ssl.keyStorePassword``: the password to access this key |
| 155 | + store |
| 156 | + |
| 157 | +The key store is typically created with the ``keytool`` or the |
| 158 | +``openssl`` command-line program. For example, if you have a file with |
| 159 | +the client certificate and its private key, and you want to create a key |
| 160 | +store in the `PKCS #12 <https://www.rfc-editor.org/rfc/rfc7292>`__ |
| 161 | +format, you can run the following command: |
| 162 | + |
| 163 | +.. code-block:: bash |
| 164 | + |
| 165 | + openssl pkcs12 -export -in <path to client certificate & private key file> |
| 166 | + -out <path to key store> -passout pass:<trust store password> |
| 167 | + |
| 168 | +To learn more about configuring a Java application for TLS/SSL, |
| 169 | +refer to the `JSSE Reference Guide |
| 170 | +<https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html>`__. |
| 171 | + |
| 172 | +Forcing TLS v1.2 |
| 173 | +~~~~~~~~~~~~~~~~ |
| 174 | + |
| 175 | +Some applications might want to force only the TLS 1.2 protocol. To do |
| 176 | +this, set the ``jdk.tls.client.protocols`` system property to ``TLSv1.2``. |
| 177 | + |
| 178 | +Java runtime environments before Java 8 started to enable the TLS |
| 179 | +1.2 protocol only in later updates, as shown in the previous section. |
| 180 | +For the driver to force the use of the TLS 1.2 protocol with a Java |
| 181 | +runtime environment before Java 8, ensure that the update has TLS |
| 182 | +1.2 enabled. |
| 183 | + |
| 184 | +OCSP |
| 185 | +~~~~ |
| 186 | + |
| 187 | +.. note:: |
| 188 | + |
| 189 | + The driver cannot enable OCSP by default on an individual |
| 190 | + ``MongoClient`` basis. |
| 191 | + |
| 192 | +Client-Driven OCSP |
| 193 | +`````````````````` |
| 194 | + |
| 195 | +An application will need to set the following JVM system and security properties to |
| 196 | +ensure that client-driven OCSP is enabled: |
| 197 | + |
| 198 | +- ``com.sun.net.ssl.checkRevocation``: when set to ``true``, this system |
| 199 | + property enables revocation checking |
| 200 | +- ``ocsp.enable``: When set to ``true``, this security property enables |
| 201 | + client-driven OCSP |
| 202 | + |
| 203 | +To configure an application to use client-driven OCSP, the application |
| 204 | +must already be set up to connect to a server using TLS. Setting these |
| 205 | +system properties is required to enable client-driven OCSP. |
| 206 | + |
| 207 | +.. note:: |
| 208 | + |
| 209 | + The support for TLS provided by the JDK utilizes "hard fail" behavior |
| 210 | + in the case of an unavailable OCSP responder in contrast to |
| 211 | + ``mongosh`` and the drivers that utilize "soft fail" behavior. |
| 212 | + |
| 213 | +OCSP Stapling |
| 214 | +````````````` |
| 215 | + |
| 216 | +.. important:: |
| 217 | + |
| 218 | + The following exception may occur when using OCSP stapling with Java |
| 219 | + runtime environments that use the TLS 1.3 protocol (Java 11 and higher |
| 220 | + use TLS 1.3 by default): |
| 221 | + |
| 222 | + .. code-block:: none |
| 223 | + |
| 224 | + javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request |
| 225 | + |
| 226 | + The exception is due to a known issue with TLS 1.3 in Java 11 and |
| 227 | + higher. To avoid this exception when using Java runtime environments |
| 228 | + that operate on the TLS 1.3 protocol, you can force the application to use the |
| 229 | + TLS 1.2 protocol. To do this, set the ``jdk.tls.client.protocols`` |
| 230 | + system property to ``TLSv1.2``. |
| 231 | + |
| 232 | +An application will need to set several JVM system properties to set |
| 233 | +up OCSP stapling: |
| 234 | + |
| 235 | +- ``jdk.tls.client.enableStatusRequestExtension``: when set to ``true`` |
| 236 | + (its default value), this enables OCSP stapling. |
| 237 | +- ``com.sun.net.ssl.checkRevocation``: when set to ``true``, this enables |
| 238 | + revocation checking. If this property is not set to ``true``, then the |
| 239 | + connection will be allowed to proceed regardless of the presence or |
| 240 | + status of the revocation information. |
| 241 | + |
| 242 | +To configure an application to use OCSP stapling, the application must |
| 243 | +already be set up to connect to a server using TLS, and the server |
| 244 | +must be set up to staple an OCSP response to the certificate it |
| 245 | +returns as part of the TLS handshake. |
| 246 | + |
| 247 | +To learn more about configuring a Java application to use OCSP, |
| 248 | +refer to `Client-Driven OCSP and OCSP Stapling |
| 249 | +<https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/ocsp.html>`__ |
| 250 | +in the Java documentation. |
0 commit comments