Skip to content

Commit 60b3fb6

Browse files
authored
Merge pull request #8507 from joshcooper/tls_ciphers
(PUP-10889) Explicitly set ciphersuite and allow it to be configurable
2 parents 77ad68d + bdd30a7 commit 60b3fb6

File tree

6 files changed

+51
-1
lines changed

6 files changed

+51
-1
lines changed

lib/puppet/defaults.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,14 @@ def self.initialize_default_settings!(settings)
10851085
certificate revocation checking and does not attempt to download the CRL.
10861086
EOT
10871087
},
1088+
:ciphers => {
1089+
:default => 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256',
1090+
:type => :string,
1091+
:desc => "The list of ciphersuites for TLS connections initiated by puppet. The
1092+
default value is chosen to support TLS 1.0 and up, but can be made
1093+
more restrictive if needed. The ciphersuites must be specified in OpenSSL
1094+
format, not IANA."
1095+
},
10881096
:key_type => {
10891097
:default => 'rsa',
10901098
:type => :enum,

lib/puppet/network/http/factory.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ def create_connection(site)
2727

2828
http = Puppet::Util::HttpProxy.proxy(URI(site.addr))
2929
http.use_ssl = site.use_ssl?
30+
if site.use_ssl?
31+
http.min_version = OpenSSL::SSL::TLS1_VERSION if http.respond_to?(:min_version)
32+
http.ciphers = Puppet[:ciphers]
33+
end
3034
http.read_timeout = Puppet[:http_read_timeout]
3135
http.open_timeout = Puppet[:http_connect_timeout]
3236
http.keep_alive_timeout = KEEP_ALIVE_TIMEOUT if http.respond_to?(:keep_alive_timeout=)

lib/puppet/util/monkey_patches.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ def daemonize
3232
# (#19151) Reject all SSLv2 ciphers and handshakes
3333
require 'puppet/ssl/openssl_loader'
3434
unless Puppet::Util::Platform.jruby_fips?
35+
unless defined?(OpenSSL::SSL::TLS1_VERSION)
36+
module OpenSSL::SSL
37+
# see https://github.com/ruby/ruby/commit/609103dbb5fb182eec12f052226c43e39b907682#diff-09f822c26289f5347111795ca22ed7ed1cfadd6ebd28f987991d1d414eef565aR2755-R2759
38+
OpenSSL::SSL::TLS1_VERSION = 0x301
39+
end
40+
end
41+
3542
class OpenSSL::SSL::SSLContext
3643
if DEFAULT_PARAMS[:options]
3744
DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3

spec/integration/application/plugin_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
require 'puppet/face'
33
require 'puppet_spec/puppetserver'
44

5-
describe "puppet plugin" do
5+
describe "puppet plugin", unless: Puppet::Util::Platform.jruby? do
66
include_context "https client"
77

88
let(:server) { PuppetSpec::Puppetserver.new }

spec/integration/http/client_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,16 @@
151151
end
152152
end
153153
end
154+
155+
context 'ciphersuites' do
156+
it "does not connect when using an SSLv3 ciphersuite" do
157+
Puppet[:ciphers] = "DES-CBC3-SHA"
158+
159+
https_server.start_server do |port|
160+
expect {
161+
client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
162+
}.to raise_error(Puppet::HTTP::ConnectionError, /no cipher match|sslv3 alert handshake failure/)
163+
end
164+
end
165+
end
154166
end

spec/unit/network/http/factory_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,23 @@ def create_connection(site)
144144
expect(conn.local_host).to eq('127.0.0.1')
145145
end
146146
end
147+
148+
context 'tls' do
149+
it "sets the minimum version to TLS 1.0", if: RUBY_VERSION.to_f >= 2.5 do
150+
conn = create_connection(site)
151+
expect(conn.min_version).to eq(OpenSSL::SSL::TLS1_VERSION)
152+
end
153+
154+
it "defaults to ciphersuites providing 128 bits of security or greater" do
155+
conn = create_connection(site)
156+
expect(conn.ciphers).to eq("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256")
157+
end
158+
159+
it "can be restricted to TLSv1.3 ciphers" do
160+
tls13_ciphers = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
161+
Puppet[:ciphers] = tls13_ciphers
162+
conn = create_connection(site)
163+
expect(conn.ciphers).to eq(tls13_ciphers)
164+
end
165+
end
147166
end

0 commit comments

Comments
 (0)