fluent-plugin-secure-forward 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: