lib/logstash/outputs/redis.rb in logstash-output-redis-5.0.0 vs lib/logstash/outputs/redis.rb in logstash-output-redis-5.2.0
- old
+ new
@@ -36,10 +36,38 @@
config :shuffle_hosts, :validate => :boolean, :default => true
# The default port to connect on. Can be overridden on any hostname.
config :port, :validate => :number, :default => 6379
+ # SSL
+ config :ssl_enabled, :validate => :boolean, :default => false
+
+ # Validate the certificate chain against these authorities. You can define multiple files.
+ # All the certificates will be read and added to the trust store.
+ config :ssl_certificate_authorities, :validate => :path, :list => true
+
+ # Options to verify the server's certificate.
+ # "full": validates that the provided certificate has an issue date that’s within the not_before and not_after dates;
+ # chains to a trusted Certificate Authority (CA); has a hostname or IP address that matches the names within the certificate.
+ # "none": performs no certificate validation. Disabling this severely compromises security (https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf)
+ config :ssl_verification_mode, :validate => %w[full none], :default => 'full'
+
+ # SSL certificate path
+ config :ssl_certificate, :validate => :path
+
+ # SSL key path
+ config :ssl_key, :validate => :path
+
+ # SSL key passphrase
+ config :ssl_key_passphrase, :validate => :password, :default => nil
+
+ # NOTE: the default setting [] uses SSL engine defaults
+ config :ssl_supported_protocols, :validate => %w[TLSv1.1 TLSv1.2 TLSv1.3], :default => [], :list => true
+
+ # The list of ciphers suite to use
+ config :ssl_cipher_suites, :validate => :string, :list => true
+
# The Redis database number.
config :db, :validate => :number, :default => 0
# Redis initial connection timeout in seconds.
config :timeout, :validate => :number, :default => 5
@@ -88,10 +116,12 @@
config :congestion_interval, :validate => :number, :default => 1
def register
require 'redis'
+ validate_ssl_config!
+
if @batch
if @data_type != "list"
raise RuntimeError.new(
"batch is not supported with data_type #{@data_type}"
)
@@ -182,19 +212,84 @@
params = {
:host => @current_host,
:port => @current_port,
:timeout => @timeout,
- :db => @db
+ :db => @db,
+ :ssl => @ssl_enabled,
}
+
+ params[:ssl_params] = setup_ssl_params if @ssl_enabled
+
@logger.debug("connection params", params)
if @password
params[:password] = @password.value
end
Redis.new(params)
end # def connect
+
+ def setup_ssl_params
+ require "openssl"
+
+ params = {}
+ params[:cert_store] = ssl_certificate_store
+
+ if @ssl_verification_mode == 'none'
+ params[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
+ else
+ params[:verify_mode] = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
+ end
+
+ if @ssl_certificate
+ params[:cert] = OpenSSL::X509::Certificate.new(File.read(@ssl_certificate))
+ if @ssl_key
+ # if we have an encrypted key and a password is not provided (nil) than OpenSSL::PKey::RSA
+ # prompts the user to enter a password interactively - we do not want to do that,
+ # for plain-text keys the default '' password argument gets simply ignored
+ params[:key] = OpenSSL::PKey::RSA.new(File.read(@ssl_key), @ssl_key_passphrase.value || '')
+ end
+ end
+
+ params[:min_version] = :TLS1_1
+ if @ssl_supported_protocols.any?
+ protocols = @ssl_supported_protocols.map { |v| v.delete('v').tr(".", "_").to_sym }.sort
+ params[:min_version] = protocols.first
+ params[:max_version] = protocols.last
+ end
+
+ params[:ciphers] = @ssl_cipher_suites if @ssl_cipher_suites&.any?
+ params
+ end
+
+ def ssl_certificate_store
+ cert_store = new_ssl_certificate_store
+ cert_store.set_default_paths
+ @ssl_certificate_authorities&.each do |cert|
+ cert_store.add_file(cert)
+ end
+
+ cert_store
+ end
+
+ def new_ssl_certificate_store
+ OpenSSL::X509::Store.new
+ end
+
+ def validate_ssl_config!
+ unless @ssl_enabled
+ ignored_ssl_settings = original_params.select { |k| k != 'ssl_enabled' && k.start_with?('ssl_') }
+ @logger.warn("Configured SSL settings are not used when `ssl_enabled` is set to `false`: #{ignored_ssl_settings.keys}") if ignored_ssl_settings.any?
+ return
+ end
+
+ if @ssl_certificate && !@ssl_key
+ raise LogStash::ConfigurationError, "Using an `ssl_certificate` requires an `ssl_key`"
+ elsif @ssl_key && !@ssl_certificate
+ raise LogStash::ConfigurationError, 'An `ssl_certificate` is required when using an `ssl_key`'
+ end
+ end
# A string used to identify a Redis instance in log messages
def identity
"redis://#{@password}@#{@current_host}:#{@current_port}/#{@db} #{@data_type}:#{@key}"
end