Skip to content

Commit bcbb8b8

Browse files
authored
SWIFT-434 Document how to use the driver with TLS/SSL (#438)
1 parent b6ae06d commit bcbb8b8

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

Guides/TLS.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Swift Driver TLS/SSL Guide
2+
3+
This guide covers the installation requirements and configuration options for connecting to MongoDB over TLS/SSL in the driver. See the [server documentation](https://docs.mongodb.com/manual/tutorial/configure-ssl/) to configure MongoDB to use TLS/SSL.
4+
5+
## Dependencies
6+
7+
The driver relies on the the TLS/SSL library installed on your system for making secure connections to the database.
8+
- On macOS, the driver depends on SecureTransport, the native TLS library for macOS, so no additional installation is required.
9+
- On Linux, the driver depends on OpenSSL, which is usually bundled with your OS but may require specific installation. The driver also supports LibreSSL through the use of OpenSSL compatibility checks.
10+
11+
### Ensuring TLS 1.1+
12+
13+
Industry best practices recommend, and some regulations require, the use of TLS 1.1 or newer. Though no application changes are required for the driver to make use of the newest protocols, some operating systems or versions may not provide a TLS library version new enough to support them.
14+
15+
#### ...on Linux
16+
17+
Users of Linux or other non-macOS Unix can check their OpenSSL version like this:
18+
```
19+
$ openssl version
20+
```
21+
If the version number is less than 1.0.1, support for TLS 1.1 or newer is not available. Contact your operating system vendor for a solution, upgrade to a newer distribution, or manually upgrade your installation of OpenSSL.
22+
23+
#### ...on macOS
24+
25+
macOS 10.13 (High Sierra) and newer support TLS 1.1+.
26+
27+
28+
## Basic Configuration
29+
30+
To require that connections to MongoDB made by the driver use TLS/SSL, simply specify `tls: true` in the `ClientOptions` passed to a `MongoClient`'s initializer:
31+
```swift
32+
let client = try MongoClient("mongodb://example.com", using: elg, options: ClientOptions(tls: true))
33+
```
34+
35+
Alternatively, `tls=true` can be specified in the [MongoDB Connection String](https://docs.mongodb.com/manual/reference/connection-string/) passed to the initializer:
36+
```swift
37+
let client = try MongoClient("mongodb://example.com/?tls=true", using: elg)
38+
```
39+
**Note:** Specifying any `tls`-prefixed option in the connection string or `ClientOptions` will require all connections made by the driver to use TLS/SSL.
40+
41+
## Specifying a CA File
42+
43+
The driver can be configured to use a specific set of CA certificates. This is most often used with "self-signed" server certificates.
44+
45+
A path to a file with either a single or bundle of certificate authorities to be considered trusted when making a TLS connection can be specified via the `tlsCAFile` option on `ClientOptions`:
46+
```swift
47+
let client = try MongoClient("mongodb://example.com", using: elg, options: ClientOptions(tlsCAFile: URL(string: "/path/to/ca.pem")))
48+
```
49+
50+
Alternatively, the path can be specified via the `tlsCAFile` option in the [MongoDB Connection String](https://docs.mongodb.com/manual/reference/connection-string/) passed to the client's initializer:
51+
```swift
52+
let caFile = "/path/to/ca.pem".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
53+
let client = try MongoClient("mongodb://example.com/?tlsCAFile=\(caFile)", using: elg)
54+
```
55+
56+
## Specifying a Client Certificate or Private Key File
57+
58+
The driver can be configured to present the client certificate file or the client private key file via the `tlsCertificateKeyFile` option on `ClientOptions`:
59+
```swift
60+
let client = try MongoClient("mongodb://example.com", using: elg, options: ClientOptions(tlsCertificateKeyFile: URL(string: "/path/to/cert.pem")))
61+
```
62+
If the private key is password protected, a password can be supplied via `tlsCertificateKeyFilePassword` on `ClientOptions`:
63+
```swift
64+
let client = try MongoClient(
65+
"mongodb://example.com",
66+
using: elg,
67+
options: ClientOptions(tlsCertificateKeyFile: URL(string: "/path/to/cert.pem"), tlsCertificateKeyFilePassword: <password>)
68+
)
69+
```
70+
71+
Alternatively, these options can be set via the `tlsCertificateKeyFile` and `tlsCertificateKeyFilePassword` options in the [MongoDB Connection String](https://docs.mongodb.com/manual/reference/connection-string/) passed into the initializer:
72+
```swift
73+
let certificatePath = "/path/to/cert.pem".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
74+
let password = "not a secure password".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
75+
let client = try MongoClient(
76+
"mongodb://example.com/?tlsCertificateKeyFile=\(certificatePath)&tlsCertificateKeyFilePassword=\(password)"
77+
using: elg
78+
)
79+
```
80+
**Note**: In both cases, if both a client certificate and a client private key are needed, the files should be concatenated into a single file which is specified by `tlsCertificateKeyFile`.
81+

Sources/MongoSwift/ConnectionPool.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ internal class ConnectionPool {
114114
private func setTLSOptions(_ options: ClientOptions) throws {
115115
// return early so we don't set an empty options struct on the libmongoc pool. doing so will make libmongoc
116116
// attempt to use TLS for connections.
117-
guard options.tlsAllowInvalidCertificates != nil || options.tlsAllowInvalidHostnames != nil ||
117+
guard options.tls == true ||
118+
options.tlsAllowInvalidCertificates != nil ||
119+
options.tlsAllowInvalidHostnames != nil ||
118120
options.tlsCAFile != nil || options.tlsCertificateKeyFile != nil ||
119121
options.tlsCertificateKeyFilePassword != nil else {
120122
return

Sources/MongoSwift/MongoClient.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public struct ClientOptions: CodingStrategyProvider, Decodable {
3939
*/
4040
public var threadPoolSize: Int?
4141

42+
/// Whether or not to require TLS for connections to the server. By default this is set to false.
43+
///
44+
/// - Note: Specifying any other "tls"-prefixed option will require TLS for connections to the server.
45+
public var tls: Bool?
46+
4247
/// Indicates whether to bypass validation of the certificate presented by the mongod/mongos instance. By default
4348
/// this is set to false.
4449
public var tlsAllowInvalidCertificates: Bool?
@@ -81,6 +86,7 @@ public struct ClientOptions: CodingStrategyProvider, Decodable {
8186
retryReads: Bool? = nil,
8287
retryWrites: Bool? = nil,
8388
threadPoolSize: Int? = nil,
89+
tls: Bool? = nil,
8490
tlsAllowInvalidCertificates: Bool? = nil,
8591
tlsAllowInvalidHostnames: Bool? = nil,
8692
tlsCAFile: URL? = nil,
@@ -97,6 +103,7 @@ public struct ClientOptions: CodingStrategyProvider, Decodable {
97103
self.retryWrites = retryWrites
98104
self.retryReads = retryReads
99105
self.threadPoolSize = threadPoolSize
106+
self.tls = tls
100107
self.tlsAllowInvalidCertificates = tlsAllowInvalidCertificates
101108
self.tlsAllowInvalidHostnames = tlsAllowInvalidHostnames
102109
self.tlsCAFile = tlsCAFile

0 commit comments

Comments
 (0)