fluent-plugin-secure-forward 0.0.2 → 0.0.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 616e3ee6ce26495d3cae028b95f875452e65b281
4
+ data.tar.gz: c2c1e3423af3a2659389b3ed3a534876b56ad9d3
5
+ SHA512:
6
+ metadata.gz: d33ca023780967c1d5e543dd30da3beea56c9cddc53ad43b346f19513fa72a00fb35c48797336910b6455de39b14e3e32212f4250073c28ede2d1fddbbfcc077
7
+ data.tar.gz: 0353931f0f0308dc51719e24628cf96c9c01f53baba40ee087b5dd0f09f42c5bc7492475fe1434e15cc4706fbc0335f3728ca6f614b5a100fe98536bc332fb71
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Fluentd input/output plugin to forward fluentd messages over SSL with authentication.
4
4
 
5
- **THIS PLUGIN IS PoC, and now version is HIGHLY EXPERIMENTAL.**
5
+ **CURRENT STATUS: HIGHLY EXPERIMENTAL**
6
6
 
7
7
  This plugin makes you to be able to:
8
8
 
@@ -12,10 +12,6 @@ This plugin makes you to be able to:
12
12
  * authenticate by shared\_key check from both of client(out\_secure\_forward) and server(in\_secure\_forward)
13
13
  * authenticate with username / password pairs
14
14
 
15
- **DON'T USE THIS PLUGIN OF THIS VERSION (v0.0.x) IN PRODUCTION ENVIRONMENT.**
16
-
17
- We need new developer/maintainer of this plugin, who wants to use this plugin in their systems.
18
-
19
15
  ## Configuration
20
16
 
21
17
  ### SecureForwardInput
@@ -123,6 +119,7 @@ Minimal configurations like this:
123
119
  <match secret.data.**>
124
120
  type secure_forward
125
121
  shared_key secret_string
122
+ self_hostname client.fqdn.local
126
123
  <server>
127
124
  host server.fqdn.local # or IP
128
125
  # port 24284
@@ -136,6 +133,7 @@ If server requires username/password, set `username` and `password` in `<server>
136
133
  <match secret.data.**>
137
134
  type secure_forward
138
135
  shared_key secret_string
136
+ self_hostname client.fqdn.local
139
137
  <server>
140
138
  host server.fqdn.local
141
139
  username repeatedly
@@ -1,11 +1,11 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = "fluent-plugin-secure-forward"
4
- gem.version = "0.0.2"
4
+ gem.version = "0.0.3"
5
5
  gem.authors = ["TAGOMORI Satoshi"]
6
6
  gem.email = ["tagomoris@gmail.com"]
7
7
  gem.summary = %q{Fluentd input/output plugin to forward over SSL with authentications}
8
- gem.description = %q{This version is HIGHLY EXPERIMENTAL. DON'T USE IN PRODUCTION}
8
+ gem.description = %q{This version is HIGHLY EXPERIMENTAL.}
9
9
  gem.homepage = "https://github.com/tagomoris/fluent-plugin-secure-forward"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
@@ -15,4 +15,5 @@ Gem::Specification.new do |gem|
15
15
 
16
16
  gem.add_runtime_dependency "fluentd"
17
17
  gem.add_runtime_dependency "fluent-mixin-config-placeholders"
18
+ gem.add_runtime_dependency "resolve-hostname"
18
19
  end
@@ -65,7 +65,7 @@ module Fluent
65
65
 
66
66
  def configure(conf)
67
67
  super
68
-
68
+
69
69
  unless @cert_auto_generate || @cert_file_path
70
70
  raise Fluent::ConfigError, "One of 'cert_auto_generate' or 'cert_file_path' must be specified"
71
71
  end
@@ -106,7 +106,7 @@ module Fluent
106
106
 
107
107
  def start
108
108
  super
109
- OpenSSL::Random.seed(File.read("/dev/random", 16))
109
+ OpenSSL::Random.seed(File.read("/dev/urandom", 16))
110
110
  @sessions = []
111
111
  @sock = nil
112
112
  @listener = Thread.new(&method(:run))
@@ -118,7 +118,7 @@ module Fluent
118
118
  @sessions.each{ |s| s.shutdown }
119
119
  @sock.close
120
120
  end
121
-
121
+
122
122
  def select_authenticate_users(node, username)
123
123
  if node.nil? || node[:users].nil?
124
124
  @users.select{|u| u[:username] == username}
@@ -159,17 +159,27 @@ module Fluent
159
159
  end
160
160
 
161
161
  def run # sslsocket server thread
162
+ $log.trace "setup for ssl sessions"
162
163
  cert, key = self.certificate
163
164
  ctx = OpenSSL::SSL::SSLContext.new
164
165
  ctx.cert = cert
165
166
  ctx.key = key
166
167
 
168
+ $log.trace "start to listen", :bind => @bind, :port => @port
167
169
  server = TCPServer.new(@bind, @port)
170
+ $log.trace "starting SSL server", :bind => @bind, :port => @port
168
171
  @sock = OpenSSL::SSL::SSLServer.new(server, ctx)
169
- loop do
170
- while socket = @sock.accept
171
- @sessions.push Session.new(self, socket)
172
+ @sock.start_immediately = false
173
+ begin
174
+ $log.trace "accepting sessions"
175
+ loop do
176
+ while socket = @sock.accept
177
+ $log.trace "accept tcp connection (ssl session not established yet)"
178
+ @sessions.push Session.new(self, socket)
179
+ end
172
180
  end
181
+ rescue OpenSSL::SSL::SSLError => e
182
+ raise unless e.message.start_with?('SSL_accept SYSCALL') # signal trap on accept
173
183
  end
174
184
  end
175
185
 
@@ -179,12 +189,12 @@ module Fluent
179
189
  # TODO: format error
180
190
  tag = msg[0].to_s
181
191
  entries = msg[1]
182
-
192
+
183
193
  if entries.class == String
184
194
  # PackedForward
185
195
  es = MessagePackEventStream.new(entries, @cached_unpacker)
186
196
  Fluent::Engine.emit_stream(tag, es)
187
-
197
+
188
198
  elsif entries.class == Array
189
199
  # Forward
190
200
  es = Fluent::MultiEventStream.new
@@ -195,7 +205,7 @@ module Fluent
195
205
  es.add(time, record)
196
206
  }
197
207
  Fluent::Engine.emit_stream(tag, es)
198
-
208
+
199
209
  else
200
210
  # Message
201
211
  time = msg[1]
@@ -328,7 +338,7 @@ module Fluent
328
338
  return
329
339
  end
330
340
  send_data generate_pong(true, reason_or_salt)
331
-
341
+
332
342
  $log.debug "connection established"
333
343
  @state = :established
334
344
  end
@@ -342,11 +352,21 @@ module Fluent
342
352
  def start
343
353
  $log.debug "starting server"
344
354
 
355
+ $log.trace "accepting ssl session"
356
+ begin
357
+ @socket.accept
358
+ rescue OpenSSL::SSL::SSLError => e
359
+ $log.debug "failed to establish ssl session"
360
+ self.shutdown
361
+ return
362
+ end
363
+
345
364
  proto, port, host, ipaddr = @socket.io.addr
346
365
  @node = check_node(host, ipaddr, port, proto)
347
366
  if @node.nil? && (! @receiver.allow_anonymous_source)
348
367
  $log.warn "Connection required from unknown host '#{host}' (#{ipaddr}), disconnecting..."
349
368
  self.shutdown
369
+ return
350
370
  end
351
371
 
352
372
  @auth_key_salt = generate_salt
@@ -355,11 +375,11 @@ module Fluent
355
375
  read_length = @receiver.read_length
356
376
  read_interval = @receiver.read_interval
357
377
  socket_interval = @receiver.socket_interval
358
-
378
+
359
379
  send_data generate_helo()
360
380
  @state = :pingpong
361
381
 
362
- loop do
382
+ loop do
363
383
  begin
364
384
  while @socket.read_nonblock(read_length, buf)
365
385
  if buf == ''
@@ -377,9 +397,10 @@ module Fluent
377
397
  break
378
398
  end
379
399
  end
380
- self.shutdown
381
400
  rescue => e
382
401
  $log.warn e
402
+ ensure
403
+ self.shutdown
383
404
  end
384
405
 
385
406
  def shutdown
@@ -40,11 +40,14 @@ module Fluent
40
40
  # password pass # if required
41
41
  # </server>
42
42
 
43
+ attr_reader :hostname_resolver
44
+
43
45
  def initialize
44
46
  super
45
47
  require 'socket'
46
48
  require 'openssl'
47
49
  require 'digest'
50
+ require 'resolve/hostname'
48
51
  end
49
52
 
50
53
  def configure(conf)
@@ -75,6 +78,8 @@ module Fluent
75
78
  raise Fluent::ConfigError, "Two or more servers are not supported yet."
76
79
  end
77
80
 
81
+ @hostname_resolver = Resolve::Hostname.new(:system_resolver => true)
82
+
78
83
  true
79
84
  end
80
85
 
@@ -86,8 +91,11 @@ module Fluent
86
91
  def start
87
92
  super
88
93
 
89
- OpenSSL::Random.seed(File.read("/dev/random", 16))
94
+ $log.debug "starting secure-forward"
95
+ OpenSSL::Random.seed(File.read("/dev/urandom", 16))
96
+ $log.debug "start to connect target nodes"
90
97
  @nodes.each do |node|
98
+ $log.debug "connecting node", :host => node.host, :port => node.port
91
99
  node.start
92
100
  end
93
101
  @nodewatcher = Thread.new(&method(:node_watcher))
@@ -217,7 +225,7 @@ module Fluent
217
225
  @socket.close if @socket
218
226
  end
219
227
  rescue => e
220
- $log.debug "#{e.class}:#{e.message}"
228
+ $log.debug "error on node shutdown #{e.class}:#{e.message}"
221
229
  end
222
230
 
223
231
  def verify_result_name(code)
@@ -349,8 +357,12 @@ module Fluent
349
357
 
350
358
  def connect
351
359
  $log.debug "starting client"
352
- sock = TCPSocket.new(@host, @port)
353
360
 
361
+ addr = @sender.hostname_resolver.getaddress(@host)
362
+ $log.debug "create tcp socket to node", :host => @host, :address => addr, :port => @port
363
+ sock = TCPSocket.new(addr, @port)
364
+
365
+ $log.trace "changing socket options"
354
366
  opt = [1, @sender.send_timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
355
367
  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
356
368
 
@@ -358,16 +370,20 @@ module Fluent
358
370
  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, opt)
359
371
 
360
372
  # TODO: SSLContext constructer parameter (SSL/TLS protocol version)
373
+ $log.trace "initializing SSL contexts"
361
374
  context = OpenSSL::SSL::SSLContext.new
362
- context.ca_file = @cert_file_path
363
- # TODO: context.ciphers= (SSL Shared key chiper protocols)
375
+ # TODO: context.ca_file = (ca_file_path)
376
+ # TODO: context.ciphers = (SSL Shared key chiper protocols)
364
377
 
378
+ $log.debug "trying to connect ssl session", :host => @host, :ipaddr => addr, :port => @port
365
379
  sslsession = OpenSSL::SSL::SSLSocket.new(sock, context)
380
+ # TODO: check connection failure
366
381
  sslsession.connect
367
-
382
+ $log.debug "ssl session connected", :host => @host, :port => @port
383
+
368
384
  begin
369
385
  unless @sender.allow_self_signed_certificate
370
- $log.debug sslsession.peer_cert.subject.to_s
386
+ $log.debug "checking peer's certificate", :subject => sslsession.peer_cert.subject
371
387
  sslsession.post_connection_check(@hostlabel)
372
388
  verify = sslsession.verify_result
373
389
  if verify != OpenSSL::X509::V_OK
@@ -378,12 +394,12 @@ module Fluent
378
394
  end
379
395
  end
380
396
  rescue OpenSSL::SSL::SSLError => e
381
- $log.warn "failed to verify certification while connecting host #{@host} as #{@hostlabel}"
397
+ $log.warn "failed to verify certification while connecting ssl session", :host => @host, :hostlabel => @hostlabel
382
398
  self.shutdown
383
399
  raise
384
400
  end
385
401
 
386
- $log.debug "ssl sessison connected"
402
+ $log.debug "ssl sessison connected", :host => @host, :port => @port
387
403
  @socket = sock
388
404
  @sslsession = sslsession
389
405
 
metadata CHANGED
@@ -1,49 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-secure-forward
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.0.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - TAGOMORI Satoshi
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-08 00:00:00.000000000 Z
11
+ date: 2013-07-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: fluentd
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: fluent-mixin-config-placeholders
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
- description: This version is HIGHLY EXPERIMENTAL. DON'T USE IN PRODUCTION
41
+ - !ruby/object:Gem::Dependency
42
+ name: resolve-hostname
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: This version is HIGHLY EXPERIMENTAL.
47
56
  email:
48
57
  - tagomoris@gmail.com
49
58
  executables: []
@@ -70,28 +79,28 @@ files:
70
79
  - test/plugin/test_out_secure_forward.rb
71
80
  homepage: https://github.com/tagomoris/fluent-plugin-secure-forward
72
81
  licenses: []
82
+ metadata: {}
73
83
  post_install_message:
74
84
  rdoc_options: []
75
85
  require_paths:
76
86
  - lib
77
87
  required_ruby_version: !ruby/object:Gem::Requirement
78
- none: false
79
88
  requirements:
80
- - - ! '>='
89
+ - - '>='
81
90
  - !ruby/object:Gem::Version
82
91
  version: '0'
83
92
  required_rubygems_version: !ruby/object:Gem::Requirement
84
- none: false
85
93
  requirements:
86
- - - ! '>='
94
+ - - '>='
87
95
  - !ruby/object:Gem::Version
88
96
  version: '0'
89
97
  requirements: []
90
98
  rubyforge_project:
91
- rubygems_version: 1.8.23
99
+ rubygems_version: 2.0.2
92
100
  signing_key:
93
- specification_version: 3
101
+ specification_version: 4
94
102
  summary: Fluentd input/output plugin to forward over SSL with authentications
95
103
  test_files:
96
104
  - test/plugin/test_in_secure_forward.rb
97
105
  - test/plugin/test_out_secure_forward.rb
106
+ has_rdoc: