class GELF::Transport::TCPTLS

Provides encryption capabilities for TCP connections

Attributes

rescue_ssl_errors[RW]

Supported tls_options:

'no_default_ca' [Boolean] prevents OpenSSL from using the systems CA store.
'version' [Symbol] any of :TLSv1, :TLSv1_1, :TLSv1_2 (default)
'ca' [String] the path to a custom CA store
'cert' [String, IO] the client certificate file
'key' [String, IO] the key for the client certificate
'all_ciphers' [Boolean] allows any ciphers to be used, may be insecure
'rescue_ssl_errors' [Boolean] similar to rescue_network_errors in notifier.rb, allows SSL exceptions to be raised
'no_verify' [Boolean] disable peer verification

Public Class Methods

new(addresses, tls_options={}) click to toggle source
Calls superclass method GELF::Transport::TCP::new
# File lib/gelf/transport/tcp_tls.rb, line 19
def initialize(addresses, tls_options={})
  @tls_options = tls_options
  @rescue_ssl_errors = @tls_options['rescue_ssl_errors']
  @rescue_ssl_errors if @rescue_ssl_errors.nil?
  super(addresses)
end

Protected Instance Methods

connect(host, port) click to toggle source
Calls superclass method GELF::Transport::TCP#connect
# File lib/gelf/transport/tcp_tls.rb, line 36
def connect(host, port)
  plain_socket = super(host, port)
  start_tls(plain_socket)
rescue OpenSSL::SSL::SSLError
  plain_socket.close unless plain_socket.closed?
  raise unless rescue_ssl_errors
  nil
end
resource(data) click to toggle source

checks whether {resource} is a filename and tries to read it otherwise treats it as if it already contains certificate/key data

# File lib/gelf/transport/tcp_tls.rb, line 79
def resource(data)
  if data.is_a?(String) && File.exist?(data)
    File.read(data)
  else
    data
  end
end
restrict_ciphers(ctx) click to toggle source

Ciphers have to come from the CipherString class, specifically the TXT constants here - github.com/jruby/jruby-openssl/blob/master/src/main/java/org/jruby/ext/openssl/CipherStrings.java#L47-L178

# File lib/gelf/transport/tcp_tls.rb, line 88
def restrict_ciphers(ctx)
  # This CipherString is will allow a variety of 'currently' cryptographically secure ciphers,
  # while also retaining a broad level of compatibility
  ctx.ciphers = "TLSv1_2:TLSv1_1:TLSv1:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:!ADH:!IDEA:!3DES"
end
set_certificate_and_key(context) click to toggle source
# File lib/gelf/transport/tcp_tls.rb, line 71
def set_certificate_and_key(context)
  return unless @tls_options['cert'] && @tls_options['key']
  context.cert = OpenSSL::X509::Certificate.new(resource(@tls_options['cert']))
  context.key = OpenSSL::PKey::RSA.new(resource(@tls_options['key']))
end
ssl_cert_store() click to toggle source
# File lib/gelf/transport/tcp_tls.rb, line 109
def ssl_cert_store
  OpenSSL::X509::Store.new.tap do |store|
    unless @tls_options['no_default_ca']
      store.set_default_paths
    end

    if @tls_options.key?('ca')
      ca = @tls_options['ca']
      if File.directory?(ca)
        store.add_path(@tls_options['ca'])
      elsif File.file?(ca)
        store.add_file(ca)
      else
        $stderr.puts "No directory or file: #{ca}"
      end
    end
  end
end
ssl_context() click to toggle source
# File lib/gelf/transport/tcp_tls.rb, line 61
def ssl_context
  @ssl_context ||= OpenSSL::SSL::SSLContext.new.tap do |ctx|
    ctx.cert_store = ssl_cert_store
    ctx.ssl_version = tls_version
    ctx.verify_mode = verify_mode
    set_certificate_and_key(ctx)
    restrict_ciphers(ctx) unless @tls_options['all_ciphers']
  end
end
ssl_socket_class() click to toggle source
# File lib/gelf/transport/tcp_tls.rb, line 53
def ssl_socket_class
  if defined?(Celluloid::IO::SSLSocket)
    Celluloid::IO::SSLSocket
  else
    OpenSSL::SSL::SSLSocket
  end
end
start_tls(plain_socket) click to toggle source

Initiates TLS communication on the socket

# File lib/gelf/transport/tcp_tls.rb, line 46
def start_tls(plain_socket)
  ssl_socket_class.new(plain_socket, ssl_context).tap do |ssl_socket|
    ssl_socket.sync_close = true
    ssl_socket.connect
  end
end
tls_version() click to toggle source

SSL v2&3 are insecure, forces at least TLS v1.0 and defaults to v1.2

# File lib/gelf/transport/tcp_tls.rb, line 99
def tls_version
  if @tls_options.key?('version') &&
      OpenSSL::SSL::SSLContext::METHODS.include?(@tls_options['version']) &&
      @tls_options['version'] =~ /\ATLSv/
    @tls_options['version']
  else
    :TLSv1_2
  end
end
verify_mode() click to toggle source
# File lib/gelf/transport/tcp_tls.rb, line 94
def verify_mode
  @tls_options['no_verify'] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
end
write_socket(socket, message) click to toggle source
Calls superclass method GELF::Transport::TCP#write_socket
# File lib/gelf/transport/tcp_tls.rb, line 28
def write_socket(socket, message)
  super(socket, message)
rescue OpenSSL::SSL::SSLError
  socket.close unless socket.closed?
  raise unless rescue_ssl_errors
  false
end