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