fluent-plugin-netflow 0.2.8 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +16 -1
- data/VERSION +1 -1
- data/fluent-plugin-netflow.gemspec +1 -1
- data/lib/fluent/plugin/in_netflow.rb +12 -52
- data/lib/fluent/plugin/netflow_records.rb +1 -1
- data/lib/fluent/plugin/parser_netflow.rb +8 -8
- data/lib/fluent/plugin/vash.rb +1 -1
- data/test/test_in_netflow.rb +3 -1
- data/test/test_parser_netflow.rb +7 -7
- data/test/test_parser_netflow9.rb +1 -2
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d4c63738c6b09eef497f26c714a2834fdce3e78
|
4
|
+
data.tar.gz: d6883ea9b5f1f7ab29cec7557ca305c5260e74b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c0577832be1c6aab86590a93df190bdb02a532ad8a3ab0f99925ae18f27b4a927c9cc76fb97dcd0aa4fa900e2e58a26726ec3e08b057c08ba73f19157a2b282
|
7
|
+
data.tar.gz: '0712933f971b7aa748e8b97dd1ce0ee0526ddadc110d8db0ccd6b536f78ba01ffbbd17a6a3dd481ec3d057628c401d76b9c9ea8f6e094f1a0907038be43e1d68'
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -26,6 +26,7 @@ Use RubyGems:
|
|
26
26
|
port 2055
|
27
27
|
cache_ttl 6000
|
28
28
|
versions [5, 9]
|
29
|
+
definitions /path/to/custom_fields.yaml
|
29
30
|
</source>
|
30
31
|
|
31
32
|
**bind**
|
@@ -53,6 +54,15 @@ Netflow versions which are acceptable.
|
|
53
54
|
When set to true, the plugin stores system uptime for ```first_switched``` and ```last_switched``` instead of ISO8601-formatted absolute time.
|
54
55
|
(Defaults: false)
|
55
56
|
|
57
|
+
**definitions**
|
58
|
+
|
59
|
+
YAML file containing Netflow field definitions to overfide pre-defined templates. Example is like below
|
60
|
+
|
61
|
+
---
|
62
|
+
4: # field value
|
63
|
+
- :uint8 # field length
|
64
|
+
- :protocol # field type
|
65
|
+
|
56
66
|
|
57
67
|
## Performance Evaluation
|
58
68
|
|
@@ -92,7 +102,7 @@ And configuration:
|
|
92
102
|
```ruby
|
93
103
|
require 'fluent/plugin/parser_netflow'
|
94
104
|
|
95
|
-
parser =
|
105
|
+
parser = Fluent::Plugin::NetflowParser.new
|
96
106
|
parser.configure(conf)
|
97
107
|
|
98
108
|
# Netflow v5
|
@@ -154,6 +164,11 @@ The definitions don't exactly reflect RFC3954 in order to cover some illegal imp
|
|
154
164
|
- :flow_sampler_id
|
155
165
|
```
|
156
166
|
|
167
|
+
### PaloAlto Netflow
|
168
|
+
|
169
|
+
PaloAlto Netflow has different field definitionas:
|
170
|
+
See this definitions for PaloAlto Netflow: https://github.com/repeatedly/fluent-plugin-netflow/issues/27#issuecomment-269197495
|
171
|
+
|
157
172
|
### More speed ?
|
158
173
|
|
159
174
|
:bullettrain_side: Try ```switched_times_from_uptime true``` option !
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0.rc1
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
gem.require_paths = ['lib']
|
19
19
|
|
20
|
-
gem.add_dependency "fluentd", [">= 0.10
|
20
|
+
gem.add_dependency "fluentd", [">= 0.14.10", "< 2"]
|
21
21
|
gem.add_dependency "bindata", "~> 2.1"
|
22
22
|
gem.add_development_dependency "rake", ">= 0.9.2"
|
23
23
|
gem.add_development_dependency "test-unit", "~> 3.0"
|
@@ -15,14 +15,15 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
|
19
|
-
require 'fluent/input'
|
20
|
-
require 'fluent/plugin/socket_util'
|
18
|
+
|
19
|
+
require 'fluent/plugin/input'
|
21
20
|
require 'fluent/plugin/parser_netflow'
|
22
21
|
|
23
|
-
module Fluent
|
22
|
+
module Fluent::Plugin
|
24
23
|
class NetflowInput < Input
|
25
|
-
Plugin.register_input('netflow', self)
|
24
|
+
Fluent::Plugin.register_input('netflow', self)
|
25
|
+
|
26
|
+
helpers :server
|
26
27
|
|
27
28
|
config_param :port, :integer, default: 5140
|
28
29
|
config_param :bind, :string, default: '0.0.0.0'
|
@@ -32,41 +33,29 @@ module Fluent
|
|
32
33
|
when 'udp'
|
33
34
|
:udp
|
34
35
|
else
|
35
|
-
raise ConfigError, "netflow input protocol type should be 'udp'"
|
36
|
+
raise Fluent::ConfigError, "netflow input protocol type should be 'udp'"
|
36
37
|
end
|
37
38
|
end
|
39
|
+
config_param :max_bytes, :integer, default: 2048
|
38
40
|
|
39
41
|
def configure(conf)
|
40
42
|
super
|
41
43
|
|
42
|
-
@parser =
|
44
|
+
@parser = Fluent::Plugin::NetflowParser.new
|
43
45
|
@parser.configure(conf)
|
44
46
|
end
|
45
47
|
|
46
48
|
def start
|
47
49
|
super
|
48
|
-
@
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@thread = Thread.new(&method(:run))
|
50
|
+
server_create(:in_netflow_server, @port, bind: @bind, proto: @protocol_type, max_bytes: @max_bytes) do |data, sock|
|
51
|
+
receive_data(sock.remote_host, data)
|
52
|
+
end
|
53
53
|
end
|
54
54
|
|
55
55
|
def shutdown
|
56
|
-
@loop.watchers.each { |w| w.detach }
|
57
|
-
@loop.stop
|
58
|
-
@handler.close
|
59
|
-
@thread.join
|
60
56
|
super
|
61
57
|
end
|
62
58
|
|
63
|
-
def run
|
64
|
-
@loop.run
|
65
|
-
rescue => e
|
66
|
-
log.error "unexpected error", error_class: e.class, error: e.message
|
67
|
-
log.error_backtrace
|
68
|
-
end
|
69
|
-
|
70
59
|
protected
|
71
60
|
|
72
61
|
def receive_data(host, data)
|
@@ -85,34 +74,5 @@ module Fluent
|
|
85
74
|
log.warn "unexpected error on parsing", data: data.dump, error_class: e.class, error: e.message
|
86
75
|
log.warn_backtrace
|
87
76
|
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def listen(callback)
|
92
|
-
log.info "listening netflow socket on #{@bind}:#{@port} with #{@protocol_type}"
|
93
|
-
if @protocol_type == :udp
|
94
|
-
@usock = SocketUtil.create_udp_socket(@bind)
|
95
|
-
@usock.bind(@bind, @port)
|
96
|
-
UdpHandler.new(@usock, callback)
|
97
|
-
else
|
98
|
-
Coolio::TCPServer.new(@bind, @port, TcpHandler, log, callback)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
class UdpHandler < Coolio::IO
|
103
|
-
def initialize(io, callback)
|
104
|
-
super(io)
|
105
|
-
@io = io
|
106
|
-
@callback = callback
|
107
|
-
end
|
108
|
-
|
109
|
-
def on_readable
|
110
|
-
msg, addr = @io.recvfrom_nonblock(4096)
|
111
|
-
@callback.call(addr[3], msg)
|
112
|
-
rescue => e
|
113
|
-
log.error "unexpected error on reading from socket", error_class: e.class, error: e.message
|
114
|
-
log.error_backtrace
|
115
|
-
end
|
116
|
-
end
|
117
77
|
end
|
118
78
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require "ipaddr"
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
-
require 'fluent/parser'
|
4
|
+
require 'fluent/plugin/parser'
|
5
5
|
|
6
6
|
require_relative 'netflow_records'
|
7
7
|
require_relative 'vash'
|
8
8
|
|
9
9
|
module Fluent
|
10
|
-
|
10
|
+
module Plugin
|
11
11
|
# port from logstash's netflow parser
|
12
12
|
class NetflowParser < Parser
|
13
|
-
Plugin.register_parser('netflow', self)
|
13
|
+
Fluent::Plugin.register_parser('netflow', self)
|
14
14
|
|
15
15
|
config_param :switched_times_from_uptime, :bool, default: false
|
16
16
|
config_param :cache_ttl, :integer, default: 4000
|
@@ -33,16 +33,16 @@ module Fluent
|
|
33
33
|
begin
|
34
34
|
@template_fields = YAML.load_file(filename)
|
35
35
|
rescue => e
|
36
|
-
raise ConfigError, "Bad syntax in definitions file #{filename}, error_class = #{e.class.name}, error = #{e.message}"
|
36
|
+
raise Fluent::ConfigError, "Bad syntax in definitions file #{filename}, error_class = #{e.class.name}, error = #{e.message}"
|
37
37
|
end
|
38
38
|
|
39
39
|
# Allow the user to augment/override/rename the supported Netflow fields
|
40
40
|
if @definitions
|
41
|
-
raise ConfigError, "definitions file #{@definitions} doesn't exist" unless File.exist?(@definitions)
|
41
|
+
raise Fluent::ConfigError, "definitions file #{@definitions} doesn't exist" unless File.exist?(@definitions)
|
42
42
|
begin
|
43
43
|
@template_fields['option'].merge!(YAML.load_file(@definitions))
|
44
44
|
rescue => e
|
45
|
-
raise ConfigError, "Bad syntax in definitions file #{@definitions}, error_class = #{e.class.name}, error = #{e.message}"
|
45
|
+
raise Fluent::ConfigError, "Bad syntax in definitions file #{@definitions}, error_class = #{e.class.name}, error = #{e.message}"
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -145,7 +145,7 @@ module Fluent
|
|
145
145
|
sampling_algorithm = (sampling & 0b1100000000000000) >> 14
|
146
146
|
sampling_interval = sampling & 0b0011111111111111
|
147
147
|
|
148
|
-
time = unix_sec.to_i
|
148
|
+
time = Time.at(unix_sec, unix_nsec / 1000).to_i # TODO: Fluent::EventTime
|
149
149
|
|
150
150
|
records_bytes = payload.bytesize - NETFLOW_V5_HEADER_BYTES
|
151
151
|
|
@@ -289,7 +289,7 @@ module Fluent
|
|
289
289
|
next
|
290
290
|
end
|
291
291
|
|
292
|
-
time = pdu.unix_sec
|
292
|
+
time = pdu.unix_sec # TODO: Fluent::EventTime (see: forV5)
|
293
293
|
event = {}
|
294
294
|
|
295
295
|
# Fewer fields in the v9 header
|
data/lib/fluent/plugin/vash.rb
CHANGED
data/test/test_in_netflow.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'fluent/test/driver/input'
|
2
3
|
|
3
4
|
class NetflowInputTest < Test::Unit::TestCase
|
4
5
|
def setup
|
@@ -13,7 +14,7 @@ class NetflowInputTest < Test::Unit::TestCase
|
|
13
14
|
]
|
14
15
|
|
15
16
|
def create_driver(conf=CONFIG)
|
16
|
-
Fluent::Test::
|
17
|
+
Fluent::Test::Driver::Input.new(Fluent::Plugin::NetflowInput).configure(conf)
|
17
18
|
end
|
18
19
|
|
19
20
|
def test_configure
|
@@ -22,6 +23,7 @@ class NetflowInputTest < Test::Unit::TestCase
|
|
22
23
|
assert_equal '127.0.0.1', d.instance.bind
|
23
24
|
assert_equal 'test.netflow', d.instance.tag
|
24
25
|
assert_equal :udp, d.instance.protocol_type
|
26
|
+
assert_equal 2048, d.instance.max_bytes
|
25
27
|
|
26
28
|
assert_raise Fluent::ConfigError do
|
27
29
|
d = create_driver CONFIG + %[
|
data/test/test_parser_netflow.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'fluent/test/driver/parser'
|
2
3
|
|
3
4
|
class NetflowParserTest < Test::Unit::TestCase
|
4
5
|
def setup
|
@@ -6,7 +7,7 @@ class NetflowParserTest < Test::Unit::TestCase
|
|
6
7
|
end
|
7
8
|
|
8
9
|
def create_parser(conf={})
|
9
|
-
parser = Fluent::
|
10
|
+
parser = Fluent::Plugin::NetflowParser.new
|
10
11
|
parser.configure(Fluent::Config::Element.new('ROOT', '', conf, []))
|
11
12
|
parser
|
12
13
|
end
|
@@ -218,7 +219,6 @@ class NetflowParserTest < Test::Unit::TestCase
|
|
218
219
|
end
|
219
220
|
|
220
221
|
assert_equal 1, parsed.size
|
221
|
-
assert_instance_of Integer, parsed.first[0]
|
222
222
|
assert_equal time1, parsed.first[0]
|
223
223
|
|
224
224
|
event = parsed.first[1]
|
@@ -311,25 +311,25 @@ class NetflowParserTest < Test::Unit::TestCase
|
|
311
311
|
|
312
312
|
require 'fluent/plugin/netflow_records'
|
313
313
|
def ipv4addr(v)
|
314
|
-
addr = Fluent::
|
314
|
+
addr = Fluent::Plugin::NetflowParser::IP4Addr.new
|
315
315
|
addr.set(v)
|
316
316
|
addr
|
317
317
|
end
|
318
318
|
|
319
319
|
def ipv6addr(v)
|
320
|
-
addr = Fluent::
|
320
|
+
addr = Fluent::Plugin::NetflowParser::IP6Addr.new
|
321
321
|
addr.set(v)
|
322
322
|
addr
|
323
323
|
end
|
324
324
|
|
325
325
|
def macaddr(v)
|
326
|
-
addr = Fluent::
|
326
|
+
addr = Fluent::Plugin::NetflowParser::MacAddr.new
|
327
327
|
addr.set(v)
|
328
328
|
addr
|
329
329
|
end
|
330
330
|
|
331
331
|
def mplslabel(v)
|
332
|
-
label = Fluent::
|
332
|
+
label = Fluent::Plugin::NetflowParser::MplsLabel.new
|
333
333
|
label.set(v)
|
334
334
|
label
|
335
335
|
end
|
@@ -366,7 +366,7 @@ class NetflowParserTest < Test::Unit::TestCase
|
|
366
366
|
end
|
367
367
|
r
|
368
368
|
}
|
369
|
-
Fluent::
|
369
|
+
Fluent::Plugin::NetflowParser::Netflow5PDU.new(hash)
|
370
370
|
end
|
371
371
|
|
372
372
|
def v9_template(hash)
|
@@ -6,7 +6,7 @@ class Netflow9ParserTest < Test::Unit::TestCase
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def create_parser(conf={})
|
9
|
-
parser = Fluent::
|
9
|
+
parser = Fluent::Plugin::NetflowParser.new
|
10
10
|
parser.configure(Fluent::Config::Element.new('ROOT', '', conf, []))
|
11
11
|
parser
|
12
12
|
end
|
@@ -68,7 +68,6 @@ class Netflow9ParserTest < Test::Unit::TestCase
|
|
68
68
|
end
|
69
69
|
|
70
70
|
assert_equal 1, parsed.size
|
71
|
-
assert_instance_of Integer, parsed.first[0]
|
72
71
|
assert_equal Time.parse('2016-02-12T04:02:25Z').to_i, parsed.first[0]
|
73
72
|
expected_record = {
|
74
73
|
# header
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-netflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masahiro Nakagawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.10
|
19
|
+
version: 0.14.10
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.10
|
29
|
+
version: 0.14.10
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2'
|
@@ -120,12 +120,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
120
|
version: '0'
|
121
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - "
|
123
|
+
- - ">"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
125
|
+
version: 1.3.1
|
126
126
|
requirements: []
|
127
127
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.5.2
|
129
129
|
signing_key:
|
130
130
|
specification_version: 4
|
131
131
|
summary: Netflow plugin for Fluentd
|