fluent-plugin-mailrelay 0.0.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 +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +101 -0
- data/Rakefile +12 -0
- data/fluent-plugin-mailrelay.gemspec +24 -0
- data/lib/fluent/plugin/out_mailrelay.rb +194 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 357f205e699a6ec3f301864d4bdd08e588c2904e
|
4
|
+
data.tar.gz: 98b3bdbd6e3db7ce34197bb83e5896ab09a41f33
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6fdedc25155aedaff0b9109fd0b21aff04bc4b10bb107d51fe3afe67297f2becd3e0c55edb3a923c78538794cc24e9499a33792d8983071166e5c013872a9f57
|
7
|
+
data.tar.gz: f74e64fde377851d5584f9fae1a3c0f2f3adbdd72815cd20df76c6651c85a3dd9c5fa1dfafd30429b78a31b84ade37a9bd0d71d2ab9c46cafdbf9181fdaea019
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 TODO: Write your name
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Fluent::Plugin::Mailrelay
|
2
|
+
|
3
|
+
Fluentd plugin to tracking mail relay in your networks.
|
4
|
+
This plugin expects fluent-plugin-sendmail `unbundled' JSON outputs.
|
5
|
+
|
6
|
+
## Configuration
|
7
|
+
|
8
|
+
```
|
9
|
+
<source>
|
10
|
+
type sendmail
|
11
|
+
path /var/log/maillog
|
12
|
+
tag sendmail
|
13
|
+
unbundle yes
|
14
|
+
</source>
|
15
|
+
|
16
|
+
<match sendmail>
|
17
|
+
type mailrelay
|
18
|
+
mynetworks ["127.0.0.1", "1.1.1.0/24"]
|
19
|
+
flush_interval 60
|
20
|
+
@label @relay
|
21
|
+
</match>
|
22
|
+
|
23
|
+
<label @relay>
|
24
|
+
<match sendmail>
|
25
|
+
type file
|
26
|
+
path /var/log/sendmail
|
27
|
+
</match>
|
28
|
+
</label>
|
29
|
+
```
|
30
|
+
|
31
|
+
example of sendmail log
|
32
|
+
|
33
|
+
```
|
34
|
+
|
35
|
+
@centos001
|
36
|
+
|
37
|
+
Jul 7 19:47:51 centos001 sendmail[22886]: u67AlmbO022886: from=<grandeur09+from@gmail.com>, size=5, class=0, nrcpts=1, msgid=<201607071047.u67AlmbO022886@centos001.localdomain>, proto=SMTP, daemon=MTA, relay=localhost [127.0.0.1]
|
38
|
+
Jul 7 19:47:51 centos001 sendmail[22888]: u67AlmbO022886: to=<grandeur09+to@gmail.com>, delay=00:00:00, xdelay=00:00:00, mailer=smtp, pri=120005, relay=[1.1.1.2] [1.1.1.2], dsn=2.0.0, stat=Sent (u67Alp74018025 Message accepted for delivery)
|
39
|
+
|
40
|
+
@centos002
|
41
|
+
|
42
|
+
Jul 7 19:47:51 centos002 sendmail[18025]: u67Alp74018025: from=<grandeur09+from@gmail.com>, size=417, class=0, nrcpts=1, msgid=<201607071047.u67AlmbO022886@centos001.localdomain>, proto=ESMTP, daemon=MTA, relay=[1.1.1.1]
|
43
|
+
Jul 7 19:47:53 centos002 sendmail[18027]: u67Alp74018025: to=<grandeur09+to@gmail.com>, delay=00:00:02, xdelay=00:00:02, mailer=esmtp, pri=120417, relay=gmail-smtp-in.l.google.com. [74.125.204.27], dsn=2.0.0, stat=Sent (OK 1467888473 d129si502387itc.63 - gsmtp)
|
44
|
+
|
45
|
+
```
|
46
|
+
|
47
|
+
This plugin emit record like below:
|
48
|
+
|
49
|
+
```
|
50
|
+
2016-07-07T19:47:53+09:00 sendmail
|
51
|
+
{
|
52
|
+
"from":"<grandeur09+from@gmail.com>",
|
53
|
+
"to":"<grandeur09+to@gmail.com>",
|
54
|
+
"msgid":"<201607071047.u67AlmbO022886@centos001.localdomain>",
|
55
|
+
"delay_sec_sum":2,
|
56
|
+
"relay":[
|
57
|
+
{
|
58
|
+
"mta":"centos001",
|
59
|
+
"relay_to":{
|
60
|
+
"ip":"1.1.1.2",
|
61
|
+
"host":null
|
62
|
+
},
|
63
|
+
"stat":"sent",
|
64
|
+
"dsn":"2.0.0",
|
65
|
+
"delay":"00:00:00",
|
66
|
+
"arrived_at_mta":1467888471
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"mta":"centos002",
|
70
|
+
"relay_to":{
|
71
|
+
"ip":"74.125.204.27",
|
72
|
+
"host":"gmail-smtp-in.l.google.com."
|
73
|
+
},
|
74
|
+
"stat":"sent",
|
75
|
+
"dsn":"2.0.0",
|
76
|
+
"delay":"00:00:02",
|
77
|
+
"arrived_at_mta":1467888473
|
78
|
+
}
|
79
|
+
]
|
80
|
+
}
|
81
|
+
```
|
82
|
+
|
83
|
+
## TODO
|
84
|
+
|
85
|
+
* writing test code.
|
86
|
+
|
87
|
+
## ChangeLog
|
88
|
+
|
89
|
+
See [CHANGELOG.md](CHANGELOG.md) for details.
|
90
|
+
|
91
|
+
## Contributing
|
92
|
+
|
93
|
+
1. Fork it
|
94
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
95
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
96
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
97
|
+
5. Create new Pull Request
|
98
|
+
|
99
|
+
## Copyright
|
100
|
+
|
101
|
+
Copyright (c) 2014 yudai09. See [LICENSE](LICENSE) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fluent-plugin-mailrelay"
|
7
|
+
spec.version = "0.0.0"
|
8
|
+
spec.authors = ["Yudai Kato"]
|
9
|
+
spec.email = ["grandeur09@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Output plugin to trace mail relayed in intranetwork.}
|
12
|
+
spec.description = %q{trace mail relayed in intra network.}
|
13
|
+
spec.homepage = "https://github.com/yudai09/fluent-plugin-mailrelay.git"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_runtime_dependency "fluentd"
|
23
|
+
spec.add_runtime_dependency("lru_redux", [">= 0.8.4"])
|
24
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module Fluent
|
2
|
+
class MailRelayOutput < Fluent::BufferedOutput
|
3
|
+
Fluent::Plugin.register_output('mailrelay', self)
|
4
|
+
config_param :lrucache_size, :integer, :default => (1024*1024)
|
5
|
+
config_param :mynetworks, :array, :default => ['127.0.0.1']
|
6
|
+
|
7
|
+
require 'time'
|
8
|
+
require 'lru_redux'
|
9
|
+
require 'ipaddr'
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super
|
13
|
+
@transactions = LruRedux::ThreadSafeCache.new(@lrucache_size)
|
14
|
+
end
|
15
|
+
|
16
|
+
def str2ipaddr(sipaddrs)
|
17
|
+
ipaddrs = Array.new()
|
18
|
+
sipaddrs.each do |sipaddr|
|
19
|
+
ipaddr = IPAddr.new(sipaddr)
|
20
|
+
ipaddrs.push(ipaddr)
|
21
|
+
end
|
22
|
+
ipaddrs
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure(conf)
|
26
|
+
super
|
27
|
+
@mynetworks = str2ipaddr(@mynetworks)
|
28
|
+
end
|
29
|
+
|
30
|
+
def start
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def shutdown
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def format(tag, time, record)
|
39
|
+
[tag, time, record].to_msgpack
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(chunk)
|
43
|
+
begin
|
44
|
+
# Fluentd doesn't guarantee message order
|
45
|
+
# For tracking relay of mail, this plugin should buffer logs and sort it by date order.
|
46
|
+
messages = sort_messages(chunk.to_enum(:msgpack_each))
|
47
|
+
readys = []
|
48
|
+
messages.each do |tag, time, record|
|
49
|
+
ready, mail_id = push2relaylog(tag, time, record)
|
50
|
+
# this plugin does not output relay log until the mail relayed to outer mynetworks.
|
51
|
+
# Therefore, if a mail is deferred, the relay log will not be outputed until the mail is bounced or sent.
|
52
|
+
if ready
|
53
|
+
readys.push([mail_id, tag, time])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
readys.each { |ready|
|
57
|
+
mail_id, tag, time = ready
|
58
|
+
log = @transactions[mail_id]
|
59
|
+
router.emit(tag, time, log.record)
|
60
|
+
@transactions.delete(mail_id)
|
61
|
+
}
|
62
|
+
rescue
|
63
|
+
$log.warn 'mailrelay: error write() ', :error=>$!.to_s
|
64
|
+
$log.debug_backtrace
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def sort_messages(messages)
|
70
|
+
messages = sort_by_time(messages)
|
71
|
+
end
|
72
|
+
|
73
|
+
def sort_by_time(messages)
|
74
|
+
messages.sort_by do |tag, time, record|
|
75
|
+
record[:time]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def push2relaylog(tag, time, record)
|
80
|
+
from = get_fromaddr(record)
|
81
|
+
to = get_toaddr(record)
|
82
|
+
msgid = get_msgid(record)
|
83
|
+
|
84
|
+
mail_id = from + to + msgid
|
85
|
+
$log.warn 'mailrelay: ', from, ', ', to, ',', msgid, ',', mail_id
|
86
|
+
|
87
|
+
mta = get_mta(record)
|
88
|
+
relay_to = get_relay_to(record)
|
89
|
+
stat = get_stat(record)
|
90
|
+
dsn = get_dsn(record)
|
91
|
+
delay = get_delay(record)
|
92
|
+
arrived_at_mta = time
|
93
|
+
|
94
|
+
log = nil
|
95
|
+
if @transactions.has_key?(mail_id)
|
96
|
+
log = @transactions[mail_id]
|
97
|
+
else
|
98
|
+
log = MailRelayLog.new(from, to, msgid)
|
99
|
+
@transactions[mail_id] = log
|
100
|
+
end
|
101
|
+
|
102
|
+
log.merge(mta, relay_to, stat, dsn, delay, arrived_at_mta)
|
103
|
+
if not relay_to.nil? and not relay_to_mynetworks(relay_to['ip']) or
|
104
|
+
stat == 'sent_local'
|
105
|
+
return true, mail_id
|
106
|
+
end
|
107
|
+
return false, mail_id
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_fromaddr(record)
|
111
|
+
record['from']['from']
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_toaddr(record)
|
115
|
+
record['to']['to']
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_msgid(record)
|
119
|
+
record['from']['msgid']
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_mta(record)
|
123
|
+
record['mta']
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_relay_to(record)
|
127
|
+
record['to']['relay']
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_stat(record)
|
131
|
+
record['to']['canonical_status']
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_dsn(record)
|
135
|
+
record['to']['dsn']
|
136
|
+
end
|
137
|
+
|
138
|
+
def get_delay(record)
|
139
|
+
record['to']['delay']
|
140
|
+
end
|
141
|
+
|
142
|
+
def relay_to_mynetworks(ip)
|
143
|
+
@mynetworks.each {|mynetwork|
|
144
|
+
if mynetwork.include?(ip)
|
145
|
+
return true
|
146
|
+
end
|
147
|
+
}
|
148
|
+
return false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
class MailRelayLog
|
154
|
+
def initialize(from, to, msgid)
|
155
|
+
@relay = []
|
156
|
+
@status = :init
|
157
|
+
@from = from
|
158
|
+
@to = to
|
159
|
+
@msgid = msgid
|
160
|
+
@delay_sum = 0
|
161
|
+
end
|
162
|
+
|
163
|
+
def record
|
164
|
+
return {
|
165
|
+
'from' => @from,
|
166
|
+
'to' => @to,
|
167
|
+
'msgid' => @msgid,
|
168
|
+
'delay_sec_sum' => @delay_sum,
|
169
|
+
'relay' => @relay.each {|relay|
|
170
|
+
{
|
171
|
+
'relay' => relay['relay'],
|
172
|
+
'stat' => relay['stat'],
|
173
|
+
'dsn' => relay['dsn'],
|
174
|
+
'delay' => relay['delay'],
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def merge(mta, relay_to, stat, dsn, delay, arrived_at_mta)
|
181
|
+
@relay.push({
|
182
|
+
'mta' => mta,
|
183
|
+
'relay_to' => relay_to,
|
184
|
+
'stat' => stat,
|
185
|
+
'dsn' => dsn,
|
186
|
+
'delay' => delay,
|
187
|
+
'arrived_at_mta' => arrived_at_mta
|
188
|
+
})
|
189
|
+
dtime = Time.parse(delay)
|
190
|
+
if stat =='sent' or stat == 'bounced'
|
191
|
+
@delay_sum += (dtime.hour * 60 * 60) + (dtime.min * 60) + (dtime.sec)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-mailrelay
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yudai Kato
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fluentd
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: lru_redux
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.4
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.4
|
55
|
+
description: trace mail relayed in intra network.
|
56
|
+
email:
|
57
|
+
- grandeur09@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- CHANGELOG.md
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- fluent-plugin-mailrelay.gemspec
|
68
|
+
- lib/fluent/plugin/out_mailrelay.rb
|
69
|
+
homepage: https://github.com/yudai09/fluent-plugin-mailrelay.git
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 2.4.8
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Output plugin to trace mail relayed in intranetwork.
|
93
|
+
test_files: []
|