fluent-plugin-secure-forward-addproxy 0.3.3dev2
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +444 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/secure-forward-ca-generate +34 -0
- data/bin/setup +7 -0
- data/example/auth_client.conf +19 -0
- data/example/auth_server.conf +30 -0
- data/example/cert_client.conf +21 -0
- data/example/cert_server.conf +35 -0
- data/example/certs/cert.pem +18 -0
- data/example/certs/key.pem +15 -0
- data/example/client.conf +24 -0
- data/example/client_proxy.conf +26 -0
- data/example/insecure_client.conf +23 -0
- data/example/insecure_server.conf +10 -0
- data/example/server.conf +13 -0
- data/fluent-plugin-secure-forward-addproxy.gemspec +23 -0
- data/lib/fluent/plugin/in_secure_forward.rb +278 -0
- data/lib/fluent/plugin/input_session.rb +219 -0
- data/lib/fluent/plugin/openssl_util.rb +38 -0
- data/lib/fluent/plugin/out_secure_forward.rb +280 -0
- data/lib/fluent/plugin/output_node.rb +348 -0
- data/lib/fluent/plugin/secure/forward/addproxy/version.rb +11 -0
- data/lib/fluent/plugin/secure/forward/addproxy.rb +13 -0
- data/lib/fluent/plugin/secure/forward/v033dev2/addproxy/version.rb +13 -0
- data/lib/fluent/plugin/secure/forward/v033dev2/addproxy.rb +15 -0
- data/lib/fluent/plugin/secure_forward/cert_util.rb +85 -0
- data/test/helper.rb +66 -0
- data/test/plugin/test_in_secure_forward.rb +237 -0
- data/test/plugin/test_input_session.rb +43 -0
- data/test/plugin/test_out_secure_forward.rb +147 -0
- metadata +169 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Fluent
|
4
|
+
module SecureForward
|
5
|
+
module CertUtil
|
6
|
+
def self.generate_ca_pair(opts={})
|
7
|
+
key = OpenSSL::PKey::RSA.generate(opts[:private_key_length])
|
8
|
+
|
9
|
+
issuer = subject = OpenSSL::X509::Name.new
|
10
|
+
subject.add_entry('C', opts[:cert_country])
|
11
|
+
subject.add_entry('ST', opts[:cert_state])
|
12
|
+
subject.add_entry('L', opts[:cert_locality])
|
13
|
+
subject.add_entry('CN', opts[:cert_common_name])
|
14
|
+
|
15
|
+
digest = OpenSSL::Digest::SHA1.new
|
16
|
+
|
17
|
+
cert = OpenSSL::X509::Certificate.new
|
18
|
+
cert.not_before = Time.at(0)
|
19
|
+
cert.not_after = Time.now + 5 * 365 * 86400 # 5 years after
|
20
|
+
cert.public_key = key
|
21
|
+
cert.serial = 1
|
22
|
+
cert.issuer = issuer
|
23
|
+
cert.subject = subject
|
24
|
+
cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)]))
|
25
|
+
cert.sign(key, digest)
|
26
|
+
|
27
|
+
return cert, key
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.generate_server_pair(opts={})
|
31
|
+
key = OpenSSL::PKey::RSA.generate(opts[:private_key_length])
|
32
|
+
|
33
|
+
ca_key = OpenSSL::PKey::RSA.new(File.read(opts[:ca_key_path]), opts[:ca_key_passphrase])
|
34
|
+
ca_cert = OpenSSL::X509::Certificate.new(File.read(opts[:ca_cert_path]))
|
35
|
+
issuer = ca_cert.issuer
|
36
|
+
|
37
|
+
subject = OpenSSL::X509::Name.new
|
38
|
+
subject.add_entry('C', opts[:country])
|
39
|
+
subject.add_entry('ST', opts[:state])
|
40
|
+
subject.add_entry('L', opts[:locality])
|
41
|
+
subject.add_entry('CN', opts[:common_name])
|
42
|
+
|
43
|
+
digest = OpenSSL::Digest::SHA1.new
|
44
|
+
|
45
|
+
cert = OpenSSL::X509::Certificate.new
|
46
|
+
cert.not_before = Time.at(0)
|
47
|
+
cert.not_after = Time.now + 5 * 365 * 86400 # 5 years after
|
48
|
+
cert.public_key = key
|
49
|
+
cert.serial = 2
|
50
|
+
cert.issuer = issuer
|
51
|
+
cert.subject = subject
|
52
|
+
|
53
|
+
cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(false)]))
|
54
|
+
cert.add_extension OpenSSL::X509::Extension.new('nsCertType', 'server')
|
55
|
+
|
56
|
+
cert.sign ca_key, digest
|
57
|
+
|
58
|
+
return cert, key
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.generate_self_signed_server_pair(opts={})
|
62
|
+
key = OpenSSL::PKey::RSA.generate(opts[:private_key_length])
|
63
|
+
|
64
|
+
issuer = subject = OpenSSL::X509::Name.new
|
65
|
+
subject.add_entry('C', opts[:country])
|
66
|
+
subject.add_entry('ST', opts[:state])
|
67
|
+
subject.add_entry('L', opts[:locality])
|
68
|
+
subject.add_entry('CN', opts[:common_name])
|
69
|
+
|
70
|
+
digest = OpenSSL::Digest::SHA1.new
|
71
|
+
|
72
|
+
cert = OpenSSL::X509::Certificate.new
|
73
|
+
cert.not_before = Time.at(0)
|
74
|
+
cert.not_after = Time.now + 5 * 365 * 86400 # 5 years after
|
75
|
+
cert.public_key = key
|
76
|
+
cert.serial = 1
|
77
|
+
cert.issuer = issuer
|
78
|
+
cert.subject = subject
|
79
|
+
cert.sign(key, digest)
|
80
|
+
|
81
|
+
return cert, key
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
|
+
require 'fluent/test'
|
15
|
+
|
16
|
+
$log = Fluent::Log.new(Fluent::Test::DummyLogDevice.new, Fluent::Log::LEVEL_INFO)
|
17
|
+
|
18
|
+
require 'fluent/plugin/in_secure_forward'
|
19
|
+
require 'fluent/plugin/out_secure_forward'
|
20
|
+
|
21
|
+
class DummySocket
|
22
|
+
attr_accessor :sync
|
23
|
+
end
|
24
|
+
|
25
|
+
class DummyInputPlugin
|
26
|
+
attr_reader :log, :users, :nodes, :authentication, :allow_anonymous_source, :allow_keepalive
|
27
|
+
attr_reader :shared_key, :self_hostname
|
28
|
+
attr_reader :read_length, :read_interval, :socket_interval
|
29
|
+
|
30
|
+
attr_reader :data
|
31
|
+
|
32
|
+
def initialize(opts={})
|
33
|
+
@log = $log
|
34
|
+
@users = opts.fetch(:users, [])
|
35
|
+
@nodes = opts.fetch(:nodes, [])
|
36
|
+
@authentication = opts.fetch(:authentication, false)
|
37
|
+
@allow_anonymous_source = opts.fetch(:allow_anonymous_source, true)
|
38
|
+
@allow_keepalive = opts.fetch(:allow_keepalive, true)
|
39
|
+
@shared_key = opts.fetch(:shared_key, 'shared key')
|
40
|
+
@self_hostname = opts.fetch(:self_hostname, 'hostname.local')
|
41
|
+
@read_length = opts.fetch(:read_length, 8*1024*1024)
|
42
|
+
@read_interval = opts.fetch(:read_interval, 0.05)
|
43
|
+
@socket_interval = opts.fetch(:socket_interval, 0.2)
|
44
|
+
|
45
|
+
@data = []
|
46
|
+
end
|
47
|
+
|
48
|
+
def select_authenticate_users(node, username)
|
49
|
+
if node.nil? || node[:users].nil?
|
50
|
+
self.users.select{|u| u[:username] == username}
|
51
|
+
else
|
52
|
+
self.users.select{|u| node[:users].include?(u[:username]) && u[:username] == username}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def on_message(data)
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class DummyOutputPlugin
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
class Test::Unit::TestCase
|
66
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class SecureForwardInputTest < Test::Unit::TestCase
|
4
|
+
CONFIG = %[
|
5
|
+
|
6
|
+
]
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Fluent::Test.setup
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_driver(conf=CONFIG,tag='test')
|
13
|
+
Fluent::Test::InputTestDriver.new(Fluent::SecureForwardInput).configure(conf)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_configure
|
17
|
+
p1 = nil
|
18
|
+
assert_nothing_raised { p1 = create_driver(<<CONFIG).instance }
|
19
|
+
type secure_forward
|
20
|
+
secure false
|
21
|
+
shared_key secret_string
|
22
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
23
|
+
CONFIG
|
24
|
+
assert_equal 'secret_string', p1.shared_key
|
25
|
+
assert_equal 'server.fqdn.local', p1.self_hostname
|
26
|
+
|
27
|
+
assert_raise(Fluent::ConfigError){ create_driver(<<CONFIG) }
|
28
|
+
type secure_forward
|
29
|
+
secure no
|
30
|
+
shared_key secret_string
|
31
|
+
self_hostname server.fqdn.local
|
32
|
+
authentication yes # Deny clients without valid username/password
|
33
|
+
<user>
|
34
|
+
username tagomoris
|
35
|
+
password foobar012
|
36
|
+
</user>
|
37
|
+
<user>
|
38
|
+
password yakiniku
|
39
|
+
</user>
|
40
|
+
CONFIG
|
41
|
+
assert_raise(Fluent::ConfigError){ create_driver(<<CONFIG) }
|
42
|
+
type secure_forward
|
43
|
+
secure no
|
44
|
+
shared_key secret_string
|
45
|
+
self_hostname server.fqdn.local
|
46
|
+
authentication yes # Deny clients without valid username/password
|
47
|
+
<user>
|
48
|
+
username tagomoris
|
49
|
+
password foobar012
|
50
|
+
</user>
|
51
|
+
<user>
|
52
|
+
username frsyuki
|
53
|
+
</user>
|
54
|
+
CONFIG
|
55
|
+
|
56
|
+
p2 = nil
|
57
|
+
assert_nothing_raised { p2 = create_driver(<<CONFIG).instance }
|
58
|
+
type secure_forward
|
59
|
+
secure no
|
60
|
+
shared_key secret_string
|
61
|
+
self_hostname server.fqdn.local
|
62
|
+
authentication yes # Deny clients without valid username/password
|
63
|
+
<user>
|
64
|
+
username tagomoris
|
65
|
+
password foobar012
|
66
|
+
</user>
|
67
|
+
<user>
|
68
|
+
username frsyuki
|
69
|
+
password yakiniku
|
70
|
+
</user>
|
71
|
+
CONFIG
|
72
|
+
assert_equal 2, p2.users.size
|
73
|
+
assert_equal 'tagomoris', p2.users[0].username
|
74
|
+
assert_equal 'foobar012', p2.users[0].password
|
75
|
+
|
76
|
+
assert_raise(Fluent::ConfigError){ create_driver(<<CONFIG) }
|
77
|
+
type secure_forward
|
78
|
+
secure no
|
79
|
+
shared_key secret_string
|
80
|
+
self_hostname server.fqdn.local
|
81
|
+
allow_anonymous_source no # Allow to accept from nodes of <client>
|
82
|
+
<client>
|
83
|
+
host 192.168.10.30
|
84
|
+
# network address (ex: 192.168.10.0/24) NOT Supported now
|
85
|
+
</client>
|
86
|
+
<client>
|
87
|
+
host localhost
|
88
|
+
network 192.168.1.1/32
|
89
|
+
</client>
|
90
|
+
<client>
|
91
|
+
network 192.168.16.0/24
|
92
|
+
</client>
|
93
|
+
CONFIG
|
94
|
+
assert_raise(Fluent::ConfigError){ create_driver(<<CONFIG) }
|
95
|
+
type secure_forward
|
96
|
+
secure no
|
97
|
+
shared_key secret_string
|
98
|
+
self_hostname server.fqdn.local
|
99
|
+
allow_anonymous_source no # Allow to accept from nodes of <client>
|
100
|
+
<client>
|
101
|
+
host 192.168.10.30
|
102
|
+
# network address (ex: 192.168.10.0/24) NOT Supported now
|
103
|
+
</client>
|
104
|
+
<client>
|
105
|
+
</client>
|
106
|
+
<client>
|
107
|
+
network 192.168.16.0/24
|
108
|
+
</client>
|
109
|
+
CONFIG
|
110
|
+
|
111
|
+
p3 = nil
|
112
|
+
assert_nothing_raised { p3 = create_driver(<<CONFIG).instance }
|
113
|
+
type secure_forward
|
114
|
+
secure no
|
115
|
+
shared_key secret_string
|
116
|
+
self_hostname server.fqdn.local
|
117
|
+
allow_anonymous_source no # Allow to accept from nodes of <client>
|
118
|
+
<client>
|
119
|
+
host 192.168.10.30
|
120
|
+
# network address (ex: 192.168.10.0/24) NOT Supported now
|
121
|
+
</client>
|
122
|
+
<client>
|
123
|
+
host localhost
|
124
|
+
# wildcard (ex: *.host.fqdn.local) NOT Supported now
|
125
|
+
</client>
|
126
|
+
<client>
|
127
|
+
network 192.168.16.0/24
|
128
|
+
</client>
|
129
|
+
CONFIG
|
130
|
+
assert (not p3.allow_anonymous_source)
|
131
|
+
assert_equal 3, p3.clients.size
|
132
|
+
assert_equal '192.168.16.0/24', p3.clients[2].network
|
133
|
+
assert_equal 3, p3.nodes.size
|
134
|
+
assert_equal IPAddr.new('192.168.10.30'), p3.nodes[0][:address]
|
135
|
+
assert_equal IPAddr.new('192.168.16.0/24'), p3.nodes[2][:address]
|
136
|
+
|
137
|
+
p4 = nil
|
138
|
+
assert_nothing_raised { p4 = create_driver(<<CONFIG).instance }
|
139
|
+
secure no
|
140
|
+
shared_key secret_string
|
141
|
+
self_hostname server.fqdn.local
|
142
|
+
cert_auto_generate yes
|
143
|
+
allow_anonymous_source no # Allow to accept from nodes of <client>
|
144
|
+
authentication yes # Deny clients without valid username/password
|
145
|
+
<user>
|
146
|
+
username tagomoris
|
147
|
+
password foobar012
|
148
|
+
</user>
|
149
|
+
<user>
|
150
|
+
username frsyuki
|
151
|
+
password sukiyaki
|
152
|
+
</user>
|
153
|
+
<user>
|
154
|
+
username repeatedly
|
155
|
+
password sushi
|
156
|
+
</user>
|
157
|
+
<client>
|
158
|
+
host 192.168.10.30 # allow all users to connect from 192.168.10.30
|
159
|
+
</client>
|
160
|
+
<client>
|
161
|
+
host 192.168.10.31
|
162
|
+
users tagomoris,frsyuki # deny repeatedly from 192.168.10.31
|
163
|
+
</client>
|
164
|
+
<client>
|
165
|
+
host 192.168.10.32
|
166
|
+
shared_key less_secret_string # limited shared_key for 192.168.10.32
|
167
|
+
users repeatedly # and repatedly only
|
168
|
+
</client>
|
169
|
+
CONFIG
|
170
|
+
assert_equal ['tagomoris','frsyuki'], p4.nodes[1][:users]
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_configure_secure
|
174
|
+
p = nil
|
175
|
+
assert_raise(Fluent::ConfigError) { p = create_driver(<<CONFIG).instance }
|
176
|
+
type secure_forward
|
177
|
+
shared_key secret_string
|
178
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
179
|
+
CONFIG
|
180
|
+
|
181
|
+
assert_raise(Fluent::ConfigError) { p = create_driver(<<CONFIG).instance }
|
182
|
+
type secure_forward
|
183
|
+
secure true
|
184
|
+
shared_key secret_string
|
185
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
186
|
+
CONFIG
|
187
|
+
|
188
|
+
assert_raise(Fluent::ConfigError) { p = create_driver(<<CONFIG).instance }
|
189
|
+
type secure_forward
|
190
|
+
secure true
|
191
|
+
shared_key secret_string
|
192
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
193
|
+
ca_cert_path /anywhere/cert/file/does/not/exist
|
194
|
+
CONFIG
|
195
|
+
|
196
|
+
passphrase = "testing secret phrase"
|
197
|
+
ca_dir = File.join(Dir.pwd, "test", "tmp", "cadir")
|
198
|
+
unless File.exist?(File.join(ca_dir, 'ca_cert.pem'))
|
199
|
+
FileUtils.mkdir_p(ca_dir)
|
200
|
+
opt = {
|
201
|
+
private_key_length: 2048,
|
202
|
+
cert_country: 'US',
|
203
|
+
cert_state: 'CA',
|
204
|
+
cert_locality: 'Mountain View',
|
205
|
+
cert_common_name: 'SecureForward CA',
|
206
|
+
}
|
207
|
+
cert, key = Fluent::SecureForward::CertUtil.generate_ca_pair(opt)
|
208
|
+
key_data = key.export(OpenSSL::Cipher::Cipher.new('aes256'), passphrase)
|
209
|
+
File.open(File.join(ca_dir, 'ca_key.pem'), 'w') do |file|
|
210
|
+
file.write key_data
|
211
|
+
end
|
212
|
+
File.open(File.join(ca_dir, 'ca_cert.pem'), 'w') do |file|
|
213
|
+
file.write cert.to_pem
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
assert_raise(OpenSSL::PKey::RSAError) { p = create_driver(<<CONFIG).instance }
|
218
|
+
type secure_forward
|
219
|
+
secure true
|
220
|
+
shared_key secret_string
|
221
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
222
|
+
ca_cert_path #{ca_dir}/ca_cert.pem
|
223
|
+
ca_private_key_path #{ca_dir}/ca_key.pem
|
224
|
+
ca_private_key_passphrase wrong phrase
|
225
|
+
CONFIG
|
226
|
+
|
227
|
+
assert_nothing_raised { p = create_driver(<<CONFIG).instance }
|
228
|
+
type secure_forward
|
229
|
+
secure true
|
230
|
+
shared_key secret_string
|
231
|
+
self_hostname server.fqdn.local # This fqdn is used as CN (Common Name) of certificates
|
232
|
+
ca_cert_path #{ca_dir}/ca_cert.pem
|
233
|
+
ca_private_key_path #{ca_dir}/ca_key.pem
|
234
|
+
ca_private_key_passphrase testing secret phrase
|
235
|
+
CONFIG
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
require 'fluent/plugin/input_session'
|
4
|
+
|
5
|
+
require 'ipaddr'
|
6
|
+
|
7
|
+
class InputSessionTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_check_node
|
10
|
+
# def check_node(hostname, ipaddress, port, proto)
|
11
|
+
nodes = [
|
12
|
+
{ address: IPAddr.new('127.0.0.1'), shared_key: 'shared_key', users: ['tagomoris', 'repeatedly'] },
|
13
|
+
{ address: IPAddr.new('2001:DB8::9'), shared_key: 'shared_key2', users: nil },
|
14
|
+
{ address: IPAddr.new('127.0.0.0/24'), shared_key: 'shared_key3', users: ['tagomoris', 'repeatedly'] },
|
15
|
+
]
|
16
|
+
p1 = DummyInputPlugin.new(nodes: nodes)
|
17
|
+
s1 = Fluent::SecureForwardInput::Session.new(p1, DummySocket.new)
|
18
|
+
|
19
|
+
assert s1.check_node('127.0.0.1')
|
20
|
+
assert_equal 'shared_key', s1.check_node('127.0.0.1')[:shared_key]
|
21
|
+
|
22
|
+
assert s1.check_node('127.0.0.127')
|
23
|
+
assert_equal 'shared_key3', s1.check_node('127.0.0.127')[:shared_key]
|
24
|
+
|
25
|
+
assert_nil s1.check_node('192.0.2.8')
|
26
|
+
assert_nil s1.check_node('2001:DB8::8')
|
27
|
+
|
28
|
+
assert s1.check_node('2001:DB8::9')
|
29
|
+
assert_equal 'shared_key2', s1.check_node('2001:DB8::9')[:shared_key]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_generate_helo
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_check_ping
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_generate_pong
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_on_read
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class SecureForwardOutputTest < Test::Unit::TestCase
|
4
|
+
CONFIG = %[
|
5
|
+
]
|
6
|
+
|
7
|
+
def setup
|
8
|
+
Fluent::Test.setup
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_driver(conf=CONFIG,tag='test')
|
12
|
+
Fluent::Test::OutputTestDriver.new(Fluent::SecureForwardOutput, tag).configure(conf)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_configure_secondary
|
16
|
+
p1 = nil
|
17
|
+
assert_nothing_raised { p1 = create_driver(<<CONFIG).instance }
|
18
|
+
type secure_forward
|
19
|
+
secure no
|
20
|
+
shared_key secret_string
|
21
|
+
self_hostname client.fqdn.local
|
22
|
+
<server>
|
23
|
+
host server.fqdn.local # or IP
|
24
|
+
# port 24284
|
25
|
+
</server>
|
26
|
+
<secondary>
|
27
|
+
type forward
|
28
|
+
<server>
|
29
|
+
host localhost
|
30
|
+
</server>
|
31
|
+
</secondary>
|
32
|
+
CONFIG
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_configure_standby_server
|
36
|
+
p1 = nil
|
37
|
+
assert_nothing_raised { p1 = create_driver(<<CONFIG).instance }
|
38
|
+
type secure_forward
|
39
|
+
secure no
|
40
|
+
shared_key secret_string
|
41
|
+
self_hostname client.fqdn.local
|
42
|
+
keepalive 1m
|
43
|
+
<server>
|
44
|
+
host server1.fqdn.local
|
45
|
+
</server>
|
46
|
+
<server>
|
47
|
+
host server2.fqdn.local
|
48
|
+
hostlabel server2
|
49
|
+
</server>
|
50
|
+
<server>
|
51
|
+
host server1.fqdn.local
|
52
|
+
hostlabel server1
|
53
|
+
port 24285
|
54
|
+
shared_key secret_string_more
|
55
|
+
standby
|
56
|
+
</server>
|
57
|
+
CONFIG
|
58
|
+
assert_equal 3, p1.servers.size
|
59
|
+
assert_equal 3, p1.nodes.size
|
60
|
+
|
61
|
+
assert_equal 'server1.fqdn.local', p1.nodes[0].host
|
62
|
+
assert_equal 'server1.fqdn.local', p1.nodes[0].hostlabel
|
63
|
+
assert_equal 24284, p1.nodes[0].port
|
64
|
+
assert_equal false, p1.nodes[0].standby
|
65
|
+
assert_equal 'secret_string', p1.nodes[0].shared_key
|
66
|
+
assert_equal 60, p1.nodes[0].keepalive
|
67
|
+
|
68
|
+
assert_equal 'server2.fqdn.local', p1.nodes[1].host
|
69
|
+
assert_equal 'server2', p1.nodes[1].hostlabel
|
70
|
+
assert_equal 24284, p1.nodes[1].port
|
71
|
+
assert_equal false, p1.nodes[1].standby
|
72
|
+
assert_equal 'secret_string', p1.nodes[1].shared_key
|
73
|
+
assert_equal 60, p1.nodes[1].keepalive
|
74
|
+
|
75
|
+
assert_equal 'server1.fqdn.local', p1.nodes[2].host
|
76
|
+
assert_equal 'server1', p1.nodes[2].hostlabel
|
77
|
+
assert_equal 24285, p1.nodes[2].port
|
78
|
+
assert_equal true, p1.nodes[2].standby
|
79
|
+
assert_equal 'secret_string_more', p1.nodes[2].shared_key
|
80
|
+
assert_equal 60, p1.nodes[2].keepalive
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_configure_standby_server2
|
84
|
+
p1 = nil
|
85
|
+
assert_nothing_raised { p1 = create_driver(<<CONFIG).instance }
|
86
|
+
type secure_forward
|
87
|
+
secure no
|
88
|
+
shared_key secret_string
|
89
|
+
self_hostname client.fqdn.local
|
90
|
+
num_threads 3
|
91
|
+
<server>
|
92
|
+
host server1.fqdn.local
|
93
|
+
</server>
|
94
|
+
<server>
|
95
|
+
host server2.fqdn.local
|
96
|
+
</server>
|
97
|
+
<server>
|
98
|
+
host server3.fqdn.local
|
99
|
+
standby
|
100
|
+
</server>
|
101
|
+
CONFIG
|
102
|
+
assert_equal 3, p1.num_threads
|
103
|
+
assert_equal 1, p1.log.logs.select{|line| line =~ /\[warn\]: Too many num_threads for secure-forward:/}.size
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_configure_with_ca_cert
|
107
|
+
ca_dir = File.join(Dir.pwd, "test", "tmp", "cadir")
|
108
|
+
unless File.exist?(File.join(ca_dir, 'ca_cert.pem'))
|
109
|
+
FileUtils.mkdir_p(ca_dir)
|
110
|
+
opt = {
|
111
|
+
private_key_length: 2048,
|
112
|
+
cert_country: 'US',
|
113
|
+
cert_state: 'CA',
|
114
|
+
cert_locality: 'Mountain View',
|
115
|
+
cert_common_name: 'SecureForward CA',
|
116
|
+
}
|
117
|
+
cert, key = Fluent::SecureForward::CertUtil.generate_ca_pair(opt)
|
118
|
+
key_data = key.export(OpenSSL::Cipher::Cipher.new('aes256'), passphrase)
|
119
|
+
File.open(File.join(ca_dir, 'ca_key.pem'), 'w') do |file|
|
120
|
+
file.write key_data
|
121
|
+
end
|
122
|
+
File.open(File.join(ca_dir, 'ca_cert.pem'), 'w') do |file|
|
123
|
+
file.write cert.to_pem
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
p = nil
|
128
|
+
assert_nothing_raised { p = create_driver(<<CONFIG).instance }
|
129
|
+
type secure_forward
|
130
|
+
secure yes
|
131
|
+
ca_cert_path #{ca_dir}/ca_cert.pem
|
132
|
+
shared_key secret_string
|
133
|
+
self_hostname client.fqdn.local
|
134
|
+
num_threads 3
|
135
|
+
<server>
|
136
|
+
host server1.fqdn.local
|
137
|
+
</server>
|
138
|
+
<server>
|
139
|
+
host server2.fqdn.local
|
140
|
+
</server>
|
141
|
+
<server>
|
142
|
+
host server3.fqdn.local
|
143
|
+
standby
|
144
|
+
</server>
|
145
|
+
CONFIG
|
146
|
+
end
|
147
|
+
end
|