Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions lib/logstash/outputs/opensearch/http_client_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,21 @@ def self.setup_ssl(logger, params)

return {:ssl => {:enabled => false}} if params["ssl"] == false

cacert, truststore, truststore_password, keystore, keystore_password =
params.values_at('cacert', 'truststore', 'truststore_password', 'keystore', 'keystore_password')
cacert, truststore, truststore_password, keystore, keystore_password, tls_client_cert, tls_client_key =
params.values_at('cacert', 'truststore', 'truststore_password', 'keystore', 'keystore_password', 'tls_certificate', 'tls_key')

if cacert && truststore
raise(LogStash::ConfigurationError, "Use either \"cacert\" or \"truststore\" when configuring the CA certificate") if truststore
end

if (tls_client_cert && !tls_client_key)
raise(LogStash::ConfigurationError, "\"tls_key\" is missing")
end

if (!tls_client_cert && tls_client_key)
raise(LogStash::ConfigurationError, "\"tls_certificate\" is missing")
end

ssl_options = {:enabled => true}

if cacert
Expand All @@ -139,6 +147,10 @@ def self.setup_ssl(logger, params)
ssl_options[:keystore] = keystore
ssl_options[:keystore_password] = keystore_password.value if keystore_password
end
if (tls_client_cert && tls_client_key)
ssl_options[:client_cert] = tls_client_cert
ssl_options[:client_key] = tls_client_key
end
if !params["ssl_certificate_verification"]
logger.warn [
"** WARNING ** Detected UNSAFE options in opensearch output configuration!",
Expand Down
6 changes: 6 additions & 0 deletions lib/logstash/plugin_mixins/opensearch/api_configs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ module APIConfigs
# Set the keystore password
:keystore_password => { :validate => :password },

# Set the TLS Client certificate file
:tls_certificate => { :validate => :path },

# Private key file name
:tls_key => { :validate => :path },

# This setting asks OpenSearch for the list of all cluster nodes and adds them to the hosts list.
# Note: This will return ALL nodes with HTTP enabled (including master nodes!). If you use
# this with master nodes, you probably want to disable HTTP on them by setting
Expand Down
89 changes: 89 additions & 0 deletions spec/unit/outputs/opensearch_ssl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,93 @@
end

end

context "when using ssl with client certificates and key" do
let(:tls_certificate) { Stud::Temporary.file.path }
let(:tls_key) { Stud::Temporary.file.path }
before do
`openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout #{tls_key} -out #{tls_certificate}`
end

after :each do
File.delete(tls_key)
File.delete(tls_certificate)
subject.close
end

subject do
require "logstash/outputs/opensearch"
settings = {
"hosts" => "node01",
"ssl" => true,
"tls_certificate" => tls_certificate,
"tls_key" => tls_key
}
next LogStash::Outputs::OpenSearch.new(settings)
end

it "should pass the tls certificate parameters to the OpenSearch client" do
expect(::Manticore::Client).to receive(:new) do |args|
expect(args[:ssl]).to include(:client_cert => tls_certificate, :client_key => tls_key)
end.and_call_original
subject.register
end

end

context "passing only tls certificate but missing the key" do
let(:tls_certificate) { Stud::Temporary.file.path }
let(:tls_key) { Stud::Temporary.file.path }
before do
`openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout #{tls_key} -out #{tls_certificate}`
end

after :each do
File.delete(tls_key)
File.delete(tls_certificate)
subject.close
end

subject do
settings = {
"hosts" => "node01",
"ssl" => true,
"tls_certificate" => tls_certificate,
}
next LogStash::Outputs::OpenSearch.new(settings)
end

it "should not load plugin" do
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
end
end

context "passing only tls key but missing the certificate" do
let(:tls_certificate) { Stud::Temporary.file.path }
let(:tls_key) { Stud::Temporary.file.path }
before do
`openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout #{tls_key} -out #{tls_certificate}`
end

after :each do
File.delete(tls_key)
File.delete(tls_certificate)
subject.close
end

subject do
settings = {
"hosts" => "node01",
"ssl" => true,
"tls_key" => tls_key,
}
next LogStash::Outputs::OpenSearch.new(settings)
end

it "should not load plugin" do
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
end
end


end