Skip to content

Commit c898a2c

Browse files
committed
Add a TLS option to use TLS in args for mongo command and mongod config file
Starting in version 4.2, MongoDB provides net.tls settings. See https://www.mongodb.com/docs/v5.0/tutorial/configure-ssl/#procedures--using-net.tls-settings And tls args for the client : https://www.mongodb.com/docs/v5.0/tutorial/configure-ssl-clients/ SSL options are deprecated : https://www.mongodb.com/docs/v5.0/reference/configuration-options/#net.ssl-options weak_cert option is now conn_without_cert See : https://www.mongodb.com/docs/v3.0/release-notes/3.0-compatibility/#tls-ssl-configuration-option-changes
1 parent 61c6690 commit c898a2c

File tree

7 files changed

+289
-1
lines changed

7 files changed

+289
-1
lines changed

README.md

+24
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,30 @@ Default: False
538538
Ssl authorization mode. Valid options are: requireSSL, preferSSL, allowSSL.
539539
Default: requireSSL
540540

541+
##### `tls`
542+
Set to true to enable tls. Default: <>
543+
*Important*: You need to have tls_key set as well, and the file needs to
544+
pre-exist on node. If you wish to use certificate validation, tls_ca must also
545+
be set.
546+
547+
##### `tls_key`
548+
Default: <>
549+
550+
##### `tls_ca`
551+
Default: <>
552+
553+
##### `tls_conn_without_cert`
554+
Set to true to disable mandatory TLS client authentication
555+
Default: False
556+
557+
##### `tls_invalid_hostnames`
558+
Set to true to disable fqdn TLS cert check
559+
Default: False
560+
561+
##### `tls_mode`
562+
Tls authorization mode. Valid options are: requireTLS, preferTLS, allowTLS.
563+
Default: requireTLS
564+
541565
##### `service_manage`
542566
Whether or not the MongoDB service resource should be part of the catalog.
543567
Default: true

lib/facter/is_master.rb

+16
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ def get_options_from_hash_config(config)
1717
result << "--ssl --host #{Facter.value(:fqdn)}" if config['net.ssl.mode'] == 'requireSSL' || !config['net.ssl.PEMKeyFile'].nil? || !config['net.ssl.CAFile'].nil?
1818
result << "--sslPEMKeyFile #{config['net.ssl.PEMKeyFile']}" unless config['net.ssl.PEMKeyFile'].nil?
1919
result << "--sslCAFile #{config['net.ssl.CAFile']}" unless config['net.ssl.CAFile'].nil?
20+
# use --tls and --host if:
21+
# - tlsMode is "requireTLS"
22+
# - Parameter --tlsCertificateKeyFile is set
23+
# - Parameter --tlsCAFile is set
24+
result << "--tls --host #{Facter.value(:fqdn)}" if config['net.tls.mode'] == 'requireTLS' || !config['net.tls.certificateKeyFile'].nil? || !config['net.tls.CAFile'].nil?
25+
result << "--tlsCertificateKeyFile #{config['net.tls.certificateKeyFile']}" unless config['net.tls.certificateKeyFile'].nil?
26+
result << "--tlsCAFile #{config['net.tls.CAFile']}" unless config['net.tls.CAFile'].nil?
27+
2028
result << '--ipv6' unless config['net.ipv6'].nil?
2129

2230
result.join(' ')
@@ -39,6 +47,14 @@ def get_options_from_keyvalue_config(file)
3947
result << "--ssl --host #{Facter.value(:fqdn)}" if config['ssl'] == 'requireSSL' || !config['sslcert'].nil? || !config['sslca'].nil?
4048
result << "--sslPEMKeyFile #{config['sslcert']}" unless config['sslcert'].nil?
4149
result << "--sslCAFile #{config['sslca']}" unless config['sslca'].nil?
50+
# use --tls and --host if:
51+
# - tlsMode is "requireTLS"
52+
# - Parameter --tlsCertificateKeyFile is set
53+
# - Parameter --tlsCAFile is set
54+
result << "--tls --host #{Facter.value(:fqdn)}" if config['tls'] == 'requireTLS' || !config['tlscert'].nil? || !config['tlsca'].nil?
55+
result << "--tlsCertificateKeyFile #{config['tlscert']}" unless config['tlscert'].nil?
56+
result << "--tlsCAFile #{config['tlsca']}" unless config['tlsca'].nil?
57+
4258
result << '--ipv6' unless config['ipv6'].nil?
4359

4460
result.join(' ')

lib/puppet/provider/mongodb.rb

+25
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def self.mongo_conf
3535
'ssl' => config['net.ssl.mode'],
3636
'sslcert' => config['net.ssl.PEMKeyFile'],
3737
'sslca' => config['net.ssl.CAFile'],
38+
'tlsallowInvalidHostnames' => config['net.tls.allowInvalidHostnames'],
39+
'tls' => config['net.tls.mode'],
40+
'tlscert' => config['net.tls.certificateKeyFile'],
41+
'tlsca' => config['net.tls.CAFile'],
3842
'auth' => config['security.authorization'],
3943
'shardsvr' => config['sharding.clusterRole'],
4044
'confsvr' => config['sharding.clusterRole']
@@ -52,11 +56,22 @@ def self.ssl_is_enabled(config = nil)
5256
!ssl_mode.nil? && ssl_mode != 'disabled'
5357
end
5458

59+
def self.tls_is_enabled(config = nil)
60+
config ||= mongo_conf
61+
tls_mode = config.fetch('tls')
62+
!tls_mode.nil? && tls_mode != 'disabled'
63+
end
64+
5565
def self.ssl_invalid_hostnames(config = nil)
5666
config ||= mongo_conf
5767
config['allowInvalidHostnames']
5868
end
5969

70+
def self.tls_invalid_hostnames(config = nil)
71+
config ||= mongo_conf
72+
config['tlsallowInvalidHostnames']
73+
end
74+
6075
def self.mongo_cmd(db, host, cmd)
6176
config = mongo_conf
6277

@@ -72,6 +87,16 @@ def self.mongo_cmd(db, host, cmd)
7287
args += ['--sslCAFile', ssl_ca] unless ssl_ca.nil?
7388
end
7489

90+
if tls_is_enabled(config)
91+
args.push('--tls')
92+
args += ['--tlsCertificateKeyFile', config['tlscert']]
93+
94+
tls_ca = config['tlsca']
95+
args += ['--tlsCAFile', tls_ca] unless tls_ca.nil?
96+
97+
args.push('--tlsAllowInvalidHostnames') if tls_invalid_hostnames(config)
98+
end
99+
75100
args += ['--eval', cmd]
76101
mongo(args)
77102
end

manifests/server.pp

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1-
# This installs a MongoDB server. See README.md for more details.
1+
# @summary This installs a MongoDB server. See README.md for more details.
2+
#
3+
# @param tls
4+
# Ensure tls is enabled.
5+
# @param tls_key
6+
# Defines the path of the file that contains the TLS/SSL certificate and key.
7+
# @param tls_ca
8+
# Defines the path of the file that contains the certificate chain for verifying client certificates.
9+
# @param tls_conn_without_cert
10+
# Set to true to bypass client certificate validation for clients that do not present a certificate.
11+
# @param tls_invalid_hostnames
12+
# Set to true to disable the validation of the hostnames in TLS certificates.
13+
# @param tls_mode
14+
# Defines if TLS is used for all network connections. Allowed values are 'requireTLS', 'preferTLS' or 'allowTLS'.
15+
#
216
class mongodb::server (
317
Variant[Boolean, String] $ensure = $mongodb::params::ensure,
418
String $user = $mongodb::params::user,
@@ -71,6 +85,12 @@
7185
Boolean $ssl_weak_cert = false,
7286
Boolean $ssl_invalid_hostnames = false,
7387
Enum['requireSSL', 'preferSSL', 'allowSSL'] $ssl_mode = 'requireSSL',
88+
Optional[Boolean] $tls = undef,
89+
Optional[Stdlib::Absolutepath] $tls_key = undef,
90+
Optional[Stdlib::Absolutepath] $tls_ca = undef,
91+
Boolean $tls_conn_without_cert = false,
92+
Boolean $tls_invalid_hostnames = false,
93+
Enum['requireTLS', 'preferTLS', 'allowTLS'] $tls_mode = 'requireTLS',
7494
Boolean $restart = $mongodb::params::restart,
7595
Optional[String] $storage_engine = undef,
7696
Boolean $create_admin = $mongodb::params::create_admin,

manifests/server/config.pp

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@
6666
$ssl_weak_cert = $mongodb::server::ssl_weak_cert
6767
$ssl_invalid_hostnames = $mongodb::server::ssl_invalid_hostnames
6868
$ssl_mode = $mongodb::server::ssl_mode
69+
$tls = $mongodb::server::tls
70+
$tls_key = $mongodb::server::tls_key
71+
$tls_ca = $mongodb::server::tls_ca
72+
$tls_conn_without_cert = $mongodb::server::tls_conn_without_cert
73+
$tls_invalid_hostnames = $mongodb::server::tls_invalid_hostnames
74+
$tls_mode = $mongodb::server::tls_mode
6975
$storage_engine = $mongodb::server::storage_engine
7076

7177
File {
@@ -75,6 +81,8 @@
7581

7682
if ($logpath and $syslog) { fail('You cannot use syslog with logpath') }
7783

84+
if ($ssl and $tls) { fail('You cannot use ssl and tls options together') }
85+
7886
if ($ensure == 'present' or $ensure == true) {
7987
# Exists for future compatibility and clarity.
8088
if $auth {

spec/classes/server_spec.rb

+182
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,188 @@
328328
end
329329
end
330330

331+
describe 'with tls' do
332+
context 'enabled' do
333+
let :params do
334+
{
335+
tls: true,
336+
tls_mode: 'requireTLS',
337+
tls_key: '/etc/ssl/mongodb.pem'
338+
}
339+
end
340+
341+
it {
342+
is_expected.to contain_file(config_file).
343+
with_content(%r{^net\.tls\.mode: requireTLS$}).
344+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$})
345+
}
346+
end
347+
348+
context 'disabled' do
349+
let :params do
350+
{
351+
tls: false
352+
}
353+
end
354+
355+
it {
356+
is_expected.not_to contain_file(config_file).
357+
with_content(%r{net\.tls\.mode}).
358+
with_content(%r{net\.tls\.certificateKeyFile})
359+
}
360+
end
361+
end
362+
363+
describe 'with tls and client certificate validation' do
364+
context 'enabled' do
365+
let :params do
366+
{
367+
tls: true,
368+
tls_mode: 'requireTLS',
369+
tls_key: '/etc/ssl/mongodb.pem',
370+
tls_ca: '/etc/ssl/caToValidateClientCertificates.pem'
371+
}
372+
end
373+
374+
it {
375+
is_expected.to contain_file(config_file).
376+
with_content(%r{^net\.tls\.mode: requireTLS$}).
377+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$}).
378+
with_content(%r{^net\.tls\.CAFile: /etc/ssl/caToValidateClientCertificates.pem$})
379+
}
380+
end
381+
382+
context 'client certificate validation disabled but tls enabled' do
383+
let :params do
384+
{
385+
tls: true,
386+
tls_mode: 'requireTLS',
387+
tls_key: '/etc/ssl/mongodb.pem'
388+
}
389+
end
390+
391+
it {
392+
is_expected.to contain_file(config_file).
393+
with_content(%r{^net\.tls\.mode: requireTLS$}).
394+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$})
395+
is_expected.not_to contain_file(config_file).
396+
with_content(%r{net\.tls\.CAFile})
397+
}
398+
end
399+
400+
context 'disabled' do
401+
let :params do
402+
{
403+
tls: false
404+
}
405+
end
406+
407+
it { is_expected.not_to contain_file(config_file).with_content(%r{net\.tls\.CAFile}) }
408+
end
409+
end
410+
411+
describe 'with tls, client certificate validation and allow connection without certificates' do
412+
context 'enabled' do
413+
let :params do
414+
{
415+
tls: true,
416+
tls_mode: 'requireTLS',
417+
tls_key: '/etc/ssl/mongodb.pem',
418+
tls_ca: '/etc/ssl/caToValidateClientCertificates.pem',
419+
tls_conn_without_cert: true
420+
}
421+
end
422+
423+
it {
424+
is_expected.to contain_file(config_file).
425+
with_content(%r{^net\.tls\.mode: requireTLS$}).
426+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$}).
427+
with_content(%r{^net\.tls\.CAFile: /etc/ssl/caToValidateClientCertificates.pem$}).
428+
with_content(%r{^net\.tls\.allowConnectionsWithoutCertificates: true$})
429+
}
430+
end
431+
432+
context 'connection without certificates disabled but tls and client certificate validation enabled' do
433+
let :params do
434+
{
435+
tls: true,
436+
tls_mode: 'requireTLS',
437+
tls_key: '/etc/ssl/mongodb.pem',
438+
tls_ca: '/etc/ssl/caToValidateClientCertificates.pem',
439+
tls_conn_without_cert: false
440+
}
441+
end
442+
443+
it {
444+
is_expected.to contain_file(config_file).
445+
with_content(%r{^net\.tls\.mode: requireTLS$}).
446+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$}).
447+
with_content(%r{net\.tls\.CAFile})
448+
is_expected.not_to contain_file(config_file).
449+
with_content(%r{net\.tls\.allowConnectionsWithoutCertificates:\s*true})
450+
}
451+
end
452+
453+
context 'disabled' do
454+
let :params do
455+
{
456+
tls: false
457+
}
458+
end
459+
460+
it { is_expected.not_to contain_file(config_file).with_content(%r{net\.tls\.allowConnectionsWithoutCertificates:\s*true}) }
461+
end
462+
end
463+
464+
describe 'with tls and allow invalid hostnames' do
465+
context 'enabled' do
466+
let :params do
467+
{
468+
tls: true,
469+
tls_mode: 'requireTLS',
470+
tls_key: '/etc/ssl/mongodb.pem',
471+
tls_invalid_hostnames: true
472+
}
473+
end
474+
475+
it {
476+
is_expected.to contain_file(config_file).
477+
with_content(%r{^net\.tls\.mode: requireTLS$}).
478+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$}).
479+
with_content(%r{^net\.tls\.allowInvalidHostnames: true$})
480+
}
481+
end
482+
483+
context 'disallow invalid hostnames but tls enabled' do
484+
let :params do
485+
{
486+
tls: true,
487+
tls_mode: 'requireTLS',
488+
tls_key: '/etc/ssl/mongodb.pem',
489+
tls_invalid_hostnames: false
490+
}
491+
end
492+
493+
it {
494+
is_expected.to contain_file(config_file).
495+
with_content(%r{^net\.tls\.mode: requireTLS$}).
496+
with_content(%r{^net\.tls\.certificateKeyFile: /etc/ssl/mongodb.pem$})
497+
is_expected.not_to contain_file(config_file).
498+
with_content(%r{net\.tls\.allowInvalidHostnames:\s*true})
499+
}
500+
end
501+
502+
context 'disabled' do
503+
let :params do
504+
{
505+
tls: false
506+
}
507+
end
508+
509+
it { is_expected.not_to contain_file(config_file).with_content(%r{net\.tls\.allowInvalidHostnames:\s*true}) }
510+
end
511+
end
512+
331513
context 'setting nohttpinterface' do
332514
it "isn't set when undef" do
333515
is_expected.not_to contain_file(config_file).with_content(%r{net\.http\.enabled})

templates/mongodb.conf.2.6.erb

+13
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,19 @@ net.ssl.weakCertificateValidation: <%= @ssl_weak_cert %>
121121
net.ssl.allowInvalidHostnames: <%= @ssl_invalid_hostnames %>
122122
<% end -%>
123123
<% end -%>
124+
<% if @tls -%>
125+
net.tls.mode: <%= @tls_mode %>
126+
net.tls.certificateKeyFile: <%= @tls_key %>
127+
<% if @tls_ca -%>
128+
net.tls.CAFile: <%= @tls_ca %>
129+
<% end -%>
130+
<% if @tls_conn_without_cert -%>
131+
net.tls.allowConnectionsWithoutCertificates: <%= @tls_conn_without_cert %>
132+
<% end -%>
133+
<% if @tls_invalid_hostnames -%>
134+
net.tls.allowInvalidHostnames: <%= @tls_invalid_hostnames %>
135+
<% end -%>
136+
<% end -%>
124137

125138
#Replication
126139
<% if @replset -%>

0 commit comments

Comments
 (0)