logstash-output-tcp 6.0.2 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/docs/index.asciidoc +15 -0
- data/lib/logstash/outputs/tcp.rb +89 -32
- data/logstash-output-tcp.gemspec +5 -2
- data/spec/outputs/tcp_spec.rb +160 -5
- metadata +44 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d30cf25cfbc7e1cc2e72d5e1eb8ab8179d42b31413a549801a012d5e1be7e640
|
4
|
+
data.tar.gz: 53632382865d4bade1e6d56e9872b1b5db690fd9b866cb4d0952dfa8d1156cee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e48f3511c25df04edb79dfd0425c6a84d18808bce5f8d4910cabe024955e6c16f8b856a8ac7fac01cb7721e7628934101e14e7180497a7c6cc1096169290963e
|
7
|
+
data.tar.gz: 94758e5adb6be529f4c70715aa0796d1a15bd8d17e91d35c63fdc1b29eccea58c0f36e4c29b0cf911a3691fade34c895922ca9b0384cd3df405f723a97ff642f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 6.1.0
|
2
|
+
- Feat: ssl_supported_protocols (TLSv1.3) [#47](https://github.com/logstash-plugins/logstash-output-tcp/pull/47)
|
3
|
+
- Fix: close server and client sockets on plugin close
|
4
|
+
|
1
5
|
## 6.0.2
|
2
6
|
- Fix: unable to start with password protected key [#45](https://github.com/logstash-plugins/logstash-output-tcp/pull/45)
|
3
7
|
|
data/docs/index.asciidoc
CHANGED
@@ -45,6 +45,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
45
45
|
| <<plugins-{type}s-{plugin}-ssl_enable>> |<<boolean,boolean>>|No
|
46
46
|
| <<plugins-{type}s-{plugin}-ssl_key>> |a valid filesystem path|No
|
47
47
|
| <<plugins-{type}s-{plugin}-ssl_key_passphrase>> |<<password,password>>|No
|
48
|
+
| <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<string,string>>|No
|
48
49
|
| <<plugins-{type}s-{plugin}-ssl_verify>> |<<boolean,boolean>>|No
|
49
50
|
|=======================================================================
|
50
51
|
|
@@ -130,6 +131,20 @@ SSL key path
|
|
130
131
|
|
131
132
|
SSL key passphrase
|
132
133
|
|
134
|
+
[id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
|
135
|
+
===== `ssl_supported_protocols`
|
136
|
+
|
137
|
+
* Value type is <<string,string>>
|
138
|
+
* Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
|
139
|
+
* Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
|
140
|
+
`'TLSv1.1'` is not considered secure and is only provided for legacy applications.
|
141
|
+
|
142
|
+
List of allowed SSL/TLS versions to use when establishing a secure connection.
|
143
|
+
|
144
|
+
NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
|
145
|
+
the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
|
146
|
+
the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.
|
147
|
+
|
133
148
|
[id="plugins-{type}s-{plugin}-ssl_verify"]
|
134
149
|
===== `ssl_verify`
|
135
150
|
|
data/lib/logstash/outputs/tcp.rb
CHANGED
@@ -51,38 +51,43 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
|
|
51
51
|
# SSL key passphrase
|
52
52
|
config :ssl_key_passphrase, :validate => :password, :default => nil
|
53
53
|
|
54
|
+
# NOTE: the default setting [] uses SSL engine defaults
|
55
|
+
config :ssl_supported_protocols, :validate => ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], :default => [], :list => true
|
56
|
+
|
54
57
|
class Client
|
55
|
-
|
58
|
+
|
56
59
|
def initialize(socket, logger)
|
57
60
|
@socket = socket
|
58
61
|
@logger = logger
|
59
62
|
@queue = Queue.new
|
60
63
|
end
|
61
64
|
|
62
|
-
public
|
63
65
|
def run
|
64
66
|
loop do
|
65
67
|
begin
|
66
68
|
@socket.write(@queue.pop)
|
67
69
|
rescue => e
|
68
|
-
|
69
|
-
:exception => e)
|
70
|
+
log_warn 'socket write failed:', e, socket: (@socket ? @socket.to_s : nil)
|
70
71
|
break
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end # def run
|
74
75
|
|
75
|
-
public
|
76
76
|
def write(msg)
|
77
77
|
@queue.push(msg)
|
78
78
|
end # def write
|
79
|
+
|
80
|
+
def close
|
81
|
+
@socket.close
|
82
|
+
rescue => e
|
83
|
+
log_warn 'socket close failed:', e, socket: (@socket ? @socket.to_s : nil)
|
84
|
+
end
|
79
85
|
end # class Client
|
80
86
|
|
81
|
-
private
|
82
87
|
def setup_ssl
|
83
88
|
require "openssl"
|
84
89
|
|
85
|
-
@ssl_context =
|
90
|
+
@ssl_context = new_ssl_context
|
86
91
|
if @ssl_cert
|
87
92
|
@ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
|
88
93
|
if @ssl_key
|
@@ -104,50 +109,74 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
|
|
104
109
|
@ssl_context.cert_store = @cert_store
|
105
110
|
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
106
111
|
end
|
107
|
-
end # def setup_ssl
|
108
112
|
|
109
|
-
|
113
|
+
@ssl_context.min_version = :TLS1_1 # not strictly required - JVM should have disabled TLSv1
|
114
|
+
if ssl_supported_protocols.any?
|
115
|
+
disabled_protocols = ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'] - ssl_supported_protocols
|
116
|
+
unless OpenSSL::SSL.const_defined? :OP_NO_TLSv1_3 # work-around JRuby-OpenSSL bug - missing constant
|
117
|
+
@ssl_context.max_version = :TLS1_2 if disabled_protocols.delete('TLSv1.3')
|
118
|
+
end
|
119
|
+
# mapping 'TLSv1.2' -> OpenSSL::SSL::OP_NO_TLSv1_2
|
120
|
+
disabled_protocols.map! { |v| OpenSSL::SSL.const_get "OP_NO_#{v.sub('.', '_')}" }
|
121
|
+
@ssl_context.options = disabled_protocols.reduce(@ssl_context.options, :|)
|
122
|
+
end
|
123
|
+
@ssl_context
|
124
|
+
end
|
125
|
+
private :setup_ssl
|
126
|
+
|
127
|
+
# @note to be able to hook up into #ssl_context from tests
|
128
|
+
def new_ssl_context
|
129
|
+
OpenSSL::SSL::SSLContext.new
|
130
|
+
end
|
131
|
+
private :new_ssl_context
|
132
|
+
|
133
|
+
# @overload Base#register
|
110
134
|
def register
|
111
135
|
require "socket"
|
112
136
|
require "stud/try"
|
113
|
-
|
114
|
-
|
115
|
-
end # @ssl_enable
|
137
|
+
@closed = Concurrent::AtomicBoolean.new(false)
|
138
|
+
setup_ssl if @ssl_enable
|
116
139
|
|
117
140
|
if server?
|
118
141
|
@logger.info("Starting tcp output listener", :address => "#{@host}:#{@port}")
|
119
142
|
begin
|
120
143
|
@server_socket = TCPServer.new(@host, @port)
|
121
144
|
rescue Errno::EADDRINUSE
|
122
|
-
@logger.error("Could not start
|
123
|
-
:host => @host, :port => @port)
|
145
|
+
@logger.error("Could not start tcp server: Address in use", host: @host, port: @port)
|
124
146
|
raise
|
125
147
|
end
|
126
148
|
if @ssl_enable
|
127
149
|
@server_socket = OpenSSL::SSL::SSLServer.new(@server_socket, @ssl_context)
|
128
150
|
end # @ssl_enable
|
129
|
-
@client_threads =
|
151
|
+
@client_threads = Concurrent::Array.new
|
130
152
|
|
131
153
|
@accept_thread = Thread.new(@server_socket) do |server_socket|
|
154
|
+
LogStash::Util.set_thread_name("[#{pipeline_id}]|output|tcp|server_accept")
|
132
155
|
loop do
|
133
|
-
|
156
|
+
break if @closed.value
|
157
|
+
client_socket = server_socket.accept_nonblock exception: false
|
158
|
+
if client_socket == :wait_readable
|
159
|
+
IO.select [ server_socket ]
|
160
|
+
next
|
161
|
+
end
|
162
|
+
Thread.start(client_socket) do |client_socket|
|
134
163
|
# monkeypatch a 'peer' method onto the socket.
|
135
164
|
client_socket.instance_eval { class << self; include ::LogStash::Util::SocketPeer end }
|
136
|
-
@logger.debug("
|
137
|
-
:server => "#{@host}:#{@port}")
|
165
|
+
@logger.debug("accepted connection", client: client_socket.peer, server: "#{@host}:#{@port}")
|
138
166
|
client = Client.new(client_socket, @logger)
|
139
167
|
Thread.current[:client] = client
|
168
|
+
LogStash::Util.set_thread_name("[#{pipeline_id}]|output|tcp|client_socket-#{@client_threads.size}")
|
140
169
|
@client_threads << Thread.current
|
141
|
-
client.run
|
170
|
+
client.run unless @closed.value
|
142
171
|
end
|
143
172
|
end
|
144
173
|
end
|
145
174
|
|
146
175
|
@codec.on_event do |event, payload|
|
176
|
+
@client_threads.select!(&:alive?)
|
147
177
|
@client_threads.each do |client_thread|
|
148
178
|
client_thread[:client].write(payload)
|
149
179
|
end
|
150
|
-
@client_threads.reject! {|t| !t.alive? }
|
151
180
|
end
|
152
181
|
else
|
153
182
|
client_socket = nil
|
@@ -163,8 +192,7 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
|
|
163
192
|
# Now send the payload
|
164
193
|
client_socket.syswrite(payload) if w.any?
|
165
194
|
rescue => e
|
166
|
-
|
167
|
-
:exception => e, :backtrace => e.backtrace)
|
195
|
+
log_warn "client socket failed:", e, host: @host, port: @port, socket: (client_socket ? client_socket.to_s : nil)
|
168
196
|
client_socket.close rescue nil
|
169
197
|
client_socket = nil
|
170
198
|
sleep @reconnect_interval
|
@@ -172,9 +200,27 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
|
|
172
200
|
end
|
173
201
|
end
|
174
202
|
end
|
175
|
-
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# @overload Base#receive
|
206
|
+
def receive(event)
|
207
|
+
@codec.encode(event)
|
208
|
+
end
|
209
|
+
|
210
|
+
# @overload Base#close
|
211
|
+
def close
|
212
|
+
@closed.make_true
|
213
|
+
@server_socket.close rescue nil if @server_socket
|
214
|
+
|
215
|
+
return unless @client_threads
|
216
|
+
@client_threads.each do |thread|
|
217
|
+
client = thread[:client]
|
218
|
+
client.close rescue nil if client
|
219
|
+
end
|
220
|
+
end
|
176
221
|
|
177
222
|
private
|
223
|
+
|
178
224
|
def connect
|
179
225
|
begin
|
180
226
|
client_socket = TCPSocket.new(@host, @port)
|
@@ -183,29 +229,40 @@ class LogStash::Outputs::Tcp < LogStash::Outputs::Base
|
|
183
229
|
begin
|
184
230
|
client_socket.connect
|
185
231
|
rescue OpenSSL::SSL::SSLError => ssle
|
186
|
-
|
232
|
+
log_error 'connect ssl failure:', ssle, backtrace: false
|
187
233
|
# NOTE(mrichar1): Hack to prevent hammering peer
|
188
234
|
sleep(5)
|
189
235
|
raise
|
190
236
|
end
|
191
237
|
end
|
192
238
|
client_socket.instance_eval { class << self; include ::LogStash::Util::SocketPeer end }
|
193
|
-
@logger.debug("
|
239
|
+
@logger.debug("opened connection", :client => client_socket.peer)
|
194
240
|
return client_socket
|
195
|
-
rescue
|
196
|
-
|
241
|
+
rescue => e
|
242
|
+
log_error 'failed to connect:', e
|
197
243
|
sleep @reconnect_interval
|
198
244
|
retry
|
199
245
|
end
|
200
246
|
end # def connect
|
201
247
|
|
202
|
-
private
|
203
248
|
def server?
|
204
249
|
@mode == "server"
|
205
250
|
end # def server?
|
206
251
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
252
|
+
def pipeline_id
|
253
|
+
execution_context.pipeline_id || 'main'
|
254
|
+
end
|
255
|
+
|
256
|
+
def log_warn(msg, e, backtrace: @logger.debug?, **details)
|
257
|
+
details = details.merge message: e.message, exception: e.class
|
258
|
+
details[:backtrace] = e.backtrace if backtrace
|
259
|
+
@logger.warn(msg, details)
|
260
|
+
end
|
261
|
+
|
262
|
+
def log_error(msg, e, backtrace: @logger.info?, **details)
|
263
|
+
details = details.merge message: e.message, exception: e.class
|
264
|
+
details[:backtrace] = e.backtrace if backtrace
|
265
|
+
@logger.error(msg, details)
|
266
|
+
end
|
267
|
+
|
211
268
|
end # class LogStash::Outputs::Tcp
|
data/logstash-output-tcp.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-output-tcp'
|
4
|
-
s.version = '6.0
|
4
|
+
s.version = '6.1.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Writes events over a TCP socket"
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
@@ -21,11 +21,14 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
23
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
|
-
|
24
|
+
s.add_runtime_dependency 'logstash-core', '>= 8.1.0'
|
25
25
|
s.add_runtime_dependency 'logstash-codec-json'
|
26
26
|
s.add_runtime_dependency 'stud'
|
27
27
|
|
28
|
+
s.add_runtime_dependency 'jruby-openssl', '>= 0.12.2' # 0.12 supports TLSv1.3
|
29
|
+
|
28
30
|
s.add_development_dependency 'logstash-devutils'
|
31
|
+
s.add_development_dependency 'logstash-codec-plain'
|
29
32
|
s.add_development_dependency 'flores'
|
30
33
|
end
|
31
34
|
|
data/spec/outputs/tcp_spec.rb
CHANGED
@@ -4,13 +4,112 @@ require "flores/pki"
|
|
4
4
|
|
5
5
|
describe LogStash::Outputs::Tcp do
|
6
6
|
subject { described_class.new(config) }
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
|
8
|
+
let(:port) do
|
9
|
+
begin
|
10
|
+
# Start high to better avoid common services
|
11
|
+
port = rand(10000..65535)
|
12
|
+
s = TCPServer.new("127.0.0.1", port)
|
13
|
+
s.close
|
14
|
+
|
15
|
+
port
|
16
|
+
rescue Errno::EADDRINUSE
|
17
|
+
retry
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:server) { TCPServer.new("127.0.0.1", port) }
|
22
|
+
|
23
|
+
let(:config) { { "host" => "localhost", "port" => port } }
|
24
|
+
|
25
|
+
let(:event) { LogStash::Event.new('message' => 'foo bar') }
|
26
|
+
|
27
|
+
context 'failing to connect' do
|
28
|
+
|
29
|
+
before { subject.register }
|
30
|
+
|
31
|
+
let(:config) { super().merge 'port' => 1000 }
|
32
|
+
|
33
|
+
it 'fails to connect' do
|
34
|
+
expect( subject ).to receive(:log_error).and_call_original
|
35
|
+
Thread.start { subject.receive(event) }
|
36
|
+
sleep 1.0
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'server mode' do
|
42
|
+
|
43
|
+
before { subject.register }
|
44
|
+
|
45
|
+
let(:config) { super().merge 'mode' => 'server' }
|
46
|
+
|
47
|
+
let(:client) do
|
48
|
+
Stud::try(3.times) { TCPSocket.new("127.0.0.1", port) }
|
49
|
+
end
|
50
|
+
|
51
|
+
after { subject.close }
|
52
|
+
|
53
|
+
it 'receives serialized data' do; require 'json'
|
54
|
+
client # connect
|
55
|
+
Thread.start { sleep 0.5; subject.receive event }
|
56
|
+
|
57
|
+
read = client.recv(1000)
|
58
|
+
expect( read.size ).to be > 0
|
59
|
+
expect( JSON.parse(read)['message'] ).to eql 'foo bar'
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with forced protocol" do
|
65
|
+
let(:config) do
|
66
|
+
super().merge 'ssl_supported_protocols' => [ 'TLSv1.1' ]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "limits protocol selection" do
|
70
|
+
if OpenSSL::SSL.const_defined? :OP_NO_TLSv1_3
|
71
|
+
ssl_context = subject.send :setup_ssl
|
72
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_3).to_not eql 0
|
73
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_2).to_not eql 0
|
74
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_1).to eql 0
|
75
|
+
else
|
76
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
77
|
+
allow(subject).to receive(:new_ssl_context).and_return(ssl_context)
|
78
|
+
expect(ssl_context).to receive(:max_version=).with(:'TLS1_2').and_call_original
|
79
|
+
ssl_context = subject.send :setup_ssl
|
80
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_2).to_not eql 0
|
81
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_1).to eql 0
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "with protocol range" do
|
87
|
+
let(:config) do
|
88
|
+
super().merge 'ssl_supported_protocols' => [ 'TLSv1.3', 'TLSv1.1', 'TLSv1.2' ]
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does not limit protocol selection (except min_version)" do
|
92
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
93
|
+
allow(subject).to receive(:new_ssl_context).and_return(ssl_context)
|
94
|
+
expect(ssl_context).to receive(:min_version=).with(:'TLS1_1').at_least(1).and_call_original
|
95
|
+
|
96
|
+
if OpenSSL::SSL.const_defined? :OP_NO_TLSv1_3
|
97
|
+
subject.send :setup_ssl
|
98
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_3).to eql 0
|
99
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_2).to eql 0
|
100
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_1).to eql 0
|
101
|
+
else
|
102
|
+
subject.send :setup_ssl
|
103
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_2).to eql 0
|
104
|
+
expect(ssl_context.options & OpenSSL::SSL::OP_NO_TLSv1_1).to eql 0
|
105
|
+
end
|
106
|
+
|
107
|
+
subject.send :setup_ssl
|
108
|
+
end
|
109
|
+
end
|
11
110
|
|
12
111
|
context "when enabling SSL" do
|
13
|
-
let(:config) { super().merge("ssl_enable" => true) }
|
112
|
+
let(:config) { super().merge("ssl_enable" => true, 'codec' => 'plain') }
|
14
113
|
context "and not providing a certificate/key pair" do
|
15
114
|
it "registers without error" do
|
16
115
|
expect { subject.register }.to_not raise_error
|
@@ -51,6 +150,62 @@ describe LogStash::Outputs::Tcp do
|
|
51
150
|
end
|
52
151
|
|
53
152
|
end
|
153
|
+
|
154
|
+
let(:secure_server) do
|
155
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
156
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
157
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(crt_file))
|
158
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(key_file), nil)
|
159
|
+
ssl_context.ssl_version = server_ssl_version if server_ssl_version
|
160
|
+
ssl_context.min_version = server_min_version if server_min_version
|
161
|
+
ssl_context.max_version = server_max_version if server_max_version
|
162
|
+
OpenSSL::SSL::SSLServer.new(server, ssl_context)
|
163
|
+
end
|
164
|
+
|
165
|
+
let(:server_min_version) { nil }
|
166
|
+
let(:server_max_version) { nil }
|
167
|
+
let(:server_ssl_version) { nil }
|
168
|
+
|
169
|
+
context 'with supported protocol' do
|
170
|
+
|
171
|
+
let(:config) { super().merge("ssl_supported_protocols" => ['TLSv1.2']) }
|
172
|
+
|
173
|
+
let(:server_min_version) { 'TLS1_2' }
|
174
|
+
|
175
|
+
before { subject.register }
|
176
|
+
after { secure_server.close }
|
177
|
+
|
178
|
+
it 'reads plain data' do
|
179
|
+
Thread.start { sleep 0.25; subject.receive event }
|
180
|
+
socket = secure_server.accept
|
181
|
+
read = socket.sysread(100)
|
182
|
+
expect( read.size ).to be > 0
|
183
|
+
expect( read ).to end_with 'foo bar'
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'with unsupported protocol (on server)' do
|
189
|
+
|
190
|
+
let(:config) { super().merge("ssl_supported_protocols" => ['TLSv1.1']) }
|
191
|
+
|
192
|
+
let(:server_min_version) { 'TLS1_2' }
|
193
|
+
|
194
|
+
before { subject.register }
|
195
|
+
after { secure_server.close }
|
196
|
+
|
197
|
+
it 'fails (and loops retrying)' do
|
198
|
+
expect(subject.logger).to receive(:error).with(/connect ssl failure/i, hash_including(message: /No appropriate protocol/i)).and_call_original
|
199
|
+
expect(subject.logger).to receive(:error).with(/failed to connect/i, hash_including(exception: OpenSSL::SSL::SSLError)).and_call_original
|
200
|
+
expect(subject).to receive(:sleep).once.and_call_original
|
201
|
+
expect(subject).to receive(:sleep).once.and_throw :TEST_DONE # to be able to abort the retry loop
|
202
|
+
|
203
|
+
Thread.start { secure_server.accept rescue nil }
|
204
|
+
expect { subject.receive event }.to throw_symbol(:TEST_DONE)
|
205
|
+
end
|
206
|
+
|
207
|
+
end if LOGSTASH_VERSION > '7.0'
|
208
|
+
|
54
209
|
end
|
55
210
|
|
56
211
|
context "encrypted key using PKCS#1" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-tcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.99'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 8.1.0
|
39
|
+
name: logstash-core
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 8.1.0
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
requirement: !ruby/object:Gem::Requirement
|
35
49
|
requirements:
|
@@ -58,6 +72,20 @@ dependencies:
|
|
58
72
|
- - ">="
|
59
73
|
- !ruby/object:Gem::Version
|
60
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 0.12.2
|
81
|
+
name: jruby-openssl
|
82
|
+
prerelease: false
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.12.2
|
61
89
|
- !ruby/object:Gem::Dependency
|
62
90
|
requirement: !ruby/object:Gem::Requirement
|
63
91
|
requirements:
|
@@ -72,6 +100,20 @@ dependencies:
|
|
72
100
|
- - ">="
|
73
101
|
- !ruby/object:Gem::Version
|
74
102
|
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
name: logstash-codec-plain
|
110
|
+
prerelease: false
|
111
|
+
type: :development
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
75
117
|
- !ruby/object:Gem::Dependency
|
76
118
|
requirement: !ruby/object:Gem::Requirement
|
77
119
|
requirements:
|