Skip to content

Commit 701d776

Browse files
michaelweisersuyograo
authored andcommitted
Add SSL support to tcp output
Port the SSL bits from tcp input over to tcp output
1 parent 564c4eb commit 701d776

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

lib/logstash/outputs/tcp.rb

+61
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,33 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
3131
# `client` connects to a server.
3232
config :mode, :validate => ["server", "client"], :default => "client"
3333

34+
# Enable SSL (must be set for other `ssl_` options to take effect).
35+
config :ssl_enable, :validate => :boolean, :default => false
36+
37+
# Verify the identity of the other end of the SSL connection against the CA.
38+
# For input, sets the field `sslsubject` to that of the client certificate.
39+
config :ssl_verify, :validate => :boolean, :default => false
40+
41+
# The SSL CA certificate, chainfile or CA path. The system CA path is automatically included.
42+
config :ssl_cacert, :validate => :path
43+
44+
# SSL certificate path
45+
config :ssl_cert, :validate => :path
46+
47+
# SSL key path
48+
config :ssl_key, :validate => :path
49+
50+
# SSL key passphrase
51+
config :ssl_key_passphrase, :validate => :password, :default => nil
52+
53+
# The format to use when writing events to the file. This value
54+
# supports any string and can include `%{name}` and other dynamic
55+
# strings.
56+
#
57+
# If this setting is omitted, the full json representation of the
58+
# event will be written as a single line.
59+
config :message_format, :validate => :string, :deprecated => true
60+
3461
class Client
3562
public
3663
def initialize(socket, logger)
@@ -62,6 +89,25 @@ def write(msg)
6289
def register
6390
require "socket"
6491
require "stud/try"
92+
require "openssl"
93+
if @ssl_enable
94+
@ssl_context = OpenSSL::SSL::SSLContext.new
95+
@ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
96+
@ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@ssl_key),@ssl_key_passphrase)
97+
if @ssl_verify
98+
@cert_store = OpenSSL::X509::Store.new
99+
# Load the system default certificate path to the store
100+
@cert_store.set_default_paths
101+
if File.directory?(@ssl_cacert)
102+
@cert_store.add_path(@ssl_cacert)
103+
else
104+
@cert_store.add_file(@ssl_cacert)
105+
end
106+
@ssl_context.cert_store = @cert_store
107+
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
108+
end
109+
end # @ssl_enable
110+
65111
if server?
66112
workers_not_supported
67113

@@ -73,6 +119,9 @@ def register
73119
:host => @host, :port => @port)
74120
raise
75121
end
122+
if @ssl_enable
123+
@server_socket = OpenSSL::SSL::SSLServer.new(@server_socket, @ssl_context)
124+
end # @ssl_enable
76125
@client_threads = []
77126

78127
@accept_thread = Thread.new(@server_socket) do |server_socket|
@@ -125,6 +174,18 @@ def register
125174
def connect
126175
Stud::try do
127176
client_socket = TCPSocket.new(@host, @port)
177+
if @ssl_enable
178+
client_socket = OpenSSL::SSL::SSLSocket.new(client_socket, @ssl_context)
179+
begin
180+
client_socket.connect
181+
rescue OpenSSL::SSL::SSLError => ssle
182+
@logger.error("SSL Error", :exception => ssle,
183+
:backtrace => ssle.backtrace)
184+
# NOTE(mrichar1): Hack to prevent hammering peer
185+
sleep(5)
186+
raise
187+
end
188+
end
128189
client_socket.instance_eval { class << self; include ::LogStash::Util::SocketPeer end }
129190
@logger.debug("Opened connection", :client => "#{client_socket.peer}")
130191
return client_socket

0 commit comments

Comments
 (0)