Skip to content

Commit 9bb4110

Browse files
rustagirmongoKart
andauthored
DOCSP-37871: tls tutorial (#20)
Co-authored-by: Mike Woofter <[email protected]>
1 parent 014a396 commit 9bb4110

File tree

2 files changed

+292
-1
lines changed

2 files changed

+292
-1
lines changed

source/tutorials/connect.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
Connect to MongoDB
55
==================
66

7-
.. TODO .. toctree:: /tutorials/...
7+
.. toctree::
8+
9+
/tutorials/connect/tls/
810

911
.. contents:: On this page
1012
:local:

source/tutorials/connect/tls.txt

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
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

Comments
 (0)