logstash-filter-real_ip 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03a6d392653c84b6e9979c4242b33addc2bef2b9edbc06a02ab12bf4b0e817eb
4
- data.tar.gz: b86af8b9cb8beeb0018548058bda54666cc96a8c9a79dfa808e537ea24910ef9
3
+ metadata.gz: df7a4bbe848333419b6bd9cdddcb6396caa6469e1e80db081282c0ce3d6afe1a
4
+ data.tar.gz: d56cd9f9f44694175f181777d3b25244236c80c97d129a8bd4eb90c42c8ad2c4
5
5
  SHA512:
6
- metadata.gz: 80d539a35dc6a9ae7957e2051e75a3440aed0a885ea52bc565d757d5166a6623f17e54a933d4c1440922d89a44d1b0d19ab98b4e9613d298a8a71ba979e0ba9c
7
- data.tar.gz: c8a5626f432719c803a2abd375f31ae4d23390702e124cd9ed90233dd9bbd32c9f2ab77569d5ba7155c18e16999123783c120360d6fd88686a33eed975677d73
6
+ metadata.gz: d2f799ae54fffe451882944901b007d426f6aaa2a9909ed339bf50f5112f38a186d49e48d667d4513eb0722035aea2f3a05b9da6ed0e2aa56444c5838e653d68
7
+ data.tar.gz: 7df5f2176930a09f686bc63a2f5841a9b9985acef23d33ce0f461b0d23f002c866a2b141545323af6636b2369d7c85e442dce1c0c74ef26b549df541775f9e20
data/CHANGELOG.md CHANGED
@@ -1,4 +1,8 @@
1
1
 
2
+ ## 0.2.0
3
+ - Feature: Write all x-forwarded-for IPs as array in new field
4
+ and detect invalid IPs, tagging the event if necessary
5
+
2
6
  ## 0.1.1
3
7
  - fix: Fix edge case where x-forwarded-for is empty or only contains trusted IPs
4
8
 
@@ -98,6 +98,16 @@ class LogStash::Filters::RealIp < LogStash::Filters::Base
98
98
  # address to.
99
99
  config :target_field, :validate => :string, :default => "real_ip"
100
100
 
101
+ # writes all valid IPs found in the x_forwarded_for header to this field
102
+ config :x_forwarded_for_target, :validate => :string, :default => ""
103
+
104
+ # In case any IPs processed are invalid IP addresses,
105
+ # write all of them as one string to the field specified.
106
+ config :target_on_invalid_ip, :validate => :string, :default => ""
107
+
108
+ # In case any IPs processed are invalid IP addresses, these tags will be set.
109
+ config :tags_in_invalid_ip, :valudate => :array, :default => ["_real_ip_invalid_ip"]
110
+
101
111
  # In case of error during evaluation, these tags will be set.
102
112
  config :tags_on_failure, :validate => :array, :default => ["_real_ip_lookup_failure"]
103
113
 
@@ -122,6 +132,7 @@ class LogStash::Filters::RealIp < LogStash::Filters::Base
122
132
  end
123
133
 
124
134
  @trusted_networks.map! {|e| IPAddr.new(e)}
135
+ @need_all = x_forwarded_for_target.length > 0
125
136
  end # def register
126
137
 
127
138
  private
@@ -151,7 +162,7 @@ class LogStash::Filters::RealIp < LogStash::Filters::Base
151
162
 
152
163
  # check for presence of x_forwarded_for_field
153
164
  if fwdfor == nil
154
- @logger.info("x_forwarded_for_field missing from event", :event => event)
165
+ @logger.debug? and @logger.debug("x_forwarded_for_field missing from event", :event => event)
155
166
  event.set(@target_field, remote_addr)
156
167
  filter_matched(event)
157
168
  return
@@ -206,29 +217,43 @@ class LogStash::Filters::RealIp < LogStash::Filters::Base
206
217
  return
207
218
  end
208
219
 
220
+ found = false
221
+ fatal = false
222
+ target = []
209
223
  # check each IP in x_forwarded_for_field from last to first
210
224
  (fwdfor.length - 1).downto(0) do |i|
211
225
  begin
212
226
  ip = IPAddr.new(fwdfor[i])
213
227
  rescue ArgumentError => e
214
228
  @logger.warn("Invalid IP address", :address => fwdfor[i], :event => event)
215
- @tags_on_failure.each {|tag| event.tag(tag)}
216
- return
229
+ if not found
230
+ @tags_on_failure.each {|tag| event.tag(tag)}
231
+ fatal = true
232
+ end
233
+ @tags_in_invalid_ip.each {|tag| event.tag(tag)}
234
+ next
217
235
  end
218
236
 
237
+ target.unshift(ip.to_s()) if @need_all
238
+
219
239
  # return on the first non-match against our trusted networks
220
- if match(ip) == false
240
+ if found == false and fatal == false and match(ip) == false
221
241
  event.set(@target_field, fwdfor[i])
222
242
  filter_matched(event)
223
- return
243
+ return if not @need_all
244
+ found = true
224
245
  end
225
246
  end
226
247
 
227
- # in case remote_addr and all x_forwarded_for IPs are trusted, use the
228
- # left-most IP from x_forwarded_for
229
- event.set(@target_field, fwdfor[0])
230
- filter_matched(event)
231
- return
248
+ event.set(@x_forwarded_for_target, target) if @need_all
249
+
250
+ if found == false and fatal == false
251
+ # in case remote_addr and all x_forwarded_for IPs are trusted, use the
252
+ # left-most IP from x_forwarded_for
253
+ event.set(@target_field, fwdfor[0])
254
+ filter_matched(event)
255
+ return
256
+ end
232
257
 
233
258
  end # def filter
234
259
  end # class LogStash::Filters::RealIp
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-filter-real_ip'
3
- s.version = '0.1.1'
3
+ s.version = '0.2.0'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = 'Evaluates real client IP from X-Forwarded-For header'
6
6
  s.description = 'See https://github.com/fholzer/logstash-filter-real_ip/blob/master/README.md for details.'
@@ -10,57 +10,81 @@ describe LogStash::Filters::RealIp do
10
10
  remote_address_field => "remote_addr"
11
11
  x_forwarded_for_field => "xfwdfor"
12
12
  trusted_networks => ["10.0.0.0/8", "192.168.0.0/16"]
13
+ add_field => { "success" => "success" }
13
14
  }
14
15
  }
15
16
  CONFIG
16
17
  end
17
18
 
18
19
  sample("dummy") do
20
+ expect(subject).not_to include("success")
19
21
  expect(subject).to include("tags")
20
22
  expect(subject.get('tags')).to include("_real_ip_lookup_failure")
21
23
  end
22
24
 
23
25
  sample("remote_addr" => "1.2.3.4") do
24
- if subject.get('tags') then expect(subject.get('tags')).not_to include("_real_ip_lookup_failure") end
26
+ expect(subject).to include("success")
27
+ expect(subject).not_to include("tags")
25
28
  expect(subject).to include("real_ip")
26
29
  expect(subject.get('real_ip')).to eq('1.2.3.4')
27
30
  end
28
31
 
29
32
  sample("remote_addr" => "10.2.3.4") do
33
+ expect(subject).to include("success")
30
34
  expect(subject).not_to include("tags")
31
35
  expect(subject).to include("real_ip")
32
36
  expect(subject.get('real_ip')).to eq('10.2.3.4')
33
37
  end
34
38
 
35
39
  sample("remote_addr" => "1.2.3.4", "xfwdfor" => "") do
40
+ expect(subject).to include("success")
36
41
  expect(subject).not_to include("tags")
37
42
  expect(subject).to include("real_ip")
38
43
  expect(subject.get('real_ip')).to eq('1.2.3.4')
39
44
  end
40
45
 
41
46
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "1.2.3.4") do
42
- expect(subject.get("tags")).to eq(nil)
47
+ expect(subject).to include("success")
48
+ expect(subject).not_to include("tags")
43
49
  expect(subject).to include("real_ip")
44
50
  expect(subject.get('real_ip')).to eq('1.2.3.4')
45
51
  end
46
52
 
47
53
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["1.2.3.4", "192.168.3.4"]) do
54
+ expect(subject).to include("success")
48
55
  expect(subject).not_to include("tags")
49
56
  expect(subject).to include("real_ip")
50
57
  expect(subject.get('real_ip')).to eq('1.2.3.4')
51
58
  end
52
59
 
53
60
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["192.168.5.6", "192.168.3.4"]) do
61
+ expect(subject).to include("success")
54
62
  expect(subject).not_to include("tags")
55
63
  expect(subject).to include("real_ip")
56
64
  expect(subject.get('real_ip')).to eq('192.168.5.6')
57
65
  end
58
66
 
59
67
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => []) do
68
+ expect(subject).to include("success")
60
69
  expect(subject).not_to include("tags")
61
70
  expect(subject).to include("real_ip")
62
71
  expect(subject.get('real_ip')).to eq('10.2.3.4')
63
72
  end
73
+
74
+ sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["10.5", "1.2.3.4", "192.168.3.4"]) do
75
+ expect(subject).to include("success")
76
+ expect(subject).not_to include("tags")
77
+ expect(subject).to include("real_ip")
78
+ expect(subject.get('real_ip')).to eq('1.2.3.4')
79
+ end
80
+
81
+ sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["10.5", "192.168.3.4"]) do
82
+ expect(subject).not_to include("success")
83
+ expect(subject).to include("tags")
84
+ expect(subject).not_to include("real_ip")
85
+ expect(subject.get('tags')).to include('_real_ip_invalid_ip')
86
+ expect(subject.get('tags')).to include('_real_ip_lookup_failure')
87
+ end
64
88
  end
65
89
 
66
90
  describe "Evaluates real IP correctly with flat string xfwfor" do
@@ -71,24 +95,28 @@ describe LogStash::Filters::RealIp do
71
95
  x_forwarded_for_field => "xfwdfor"
72
96
  x_forwarded_for_is_string => true
73
97
  trusted_networks => ["10.0.0.0/8", "192.168.0.0/16"]
98
+ add_field => { "success" => "success" }
74
99
  }
75
100
  }
76
101
  CONFIG
77
102
  end
78
103
 
79
104
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "1.2.3.4") do
80
- expect(subject.get("tags")).to eq(nil)
105
+ expect(subject).to include("success")
106
+ expect(subject).not_to include("tags")
81
107
  expect(subject).to include("real_ip")
82
108
  expect(subject.get('real_ip')).to eq('1.2.3.4')
83
109
  end
84
110
 
85
111
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "1.2.3.4,+192.168.3.4") do
112
+ expect(subject).to include("success")
86
113
  expect(subject).not_to include("tags")
87
114
  expect(subject).to include("real_ip")
88
115
  expect(subject.get('real_ip')).to eq('1.2.3.4')
89
116
  end
90
117
 
91
118
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "1.2.3.4, 192.168.3.4,+ 192.168.4.5") do
119
+ expect(subject).to include("success")
92
120
  expect(subject).not_to include("tags")
93
121
  expect(subject).to include("real_ip")
94
122
  expect(subject.get('real_ip')).to eq('1.2.3.4')
@@ -103,30 +131,35 @@ describe LogStash::Filters::RealIp do
103
131
  x_forwarded_for_field => "xfwdfor"
104
132
  target_field => "evaluated_ip"
105
133
  trusted_networks => ["10.0.0.0/8", "192.168.0.0/16"]
134
+ add_field => { "success" => "success" }
106
135
  }
107
136
  }
108
137
  CONFIG
109
138
  end
110
139
 
111
140
  sample("remote_addr" => "1.2.3.4") do
141
+ expect(subject).to include("success")
112
142
  expect(subject).not_to include("tags")
113
143
  expect(subject).to include("evaluated_ip")
114
144
  expect(subject.get('evaluated_ip')).to eq('1.2.3.4')
115
145
  end
116
146
 
117
147
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "") do
148
+ expect(subject).to include("success")
118
149
  expect(subject).not_to include("tags")
119
150
  expect(subject).to include("evaluated_ip")
120
151
  expect(subject.get('evaluated_ip')).to eq('10.2.3.4')
121
152
  end
122
153
 
123
154
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => "1.2.3.4") do
124
- expect(subject.get("tags")).to eq(nil)
155
+ expect(subject).to include("success")
156
+ expect(subject).not_to include("tags")
125
157
  expect(subject).to include("evaluated_ip")
126
158
  expect(subject.get('evaluated_ip')).to eq('1.2.3.4')
127
159
  end
128
160
 
129
161
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["1.2.3.4", "192.168.3.4"]) do
162
+ expect(subject).to include("success")
130
163
  expect(subject).not_to include("tags")
131
164
  expect(subject).to include("evaluated_ip")
132
165
  expect(subject.get('evaluated_ip')).to eq('1.2.3.4')
@@ -140,15 +173,60 @@ describe LogStash::Filters::RealIp do
140
173
  remote_address_field => "remote_addr"
141
174
  x_forwarded_for_field => "xfwdfor"
142
175
  trusted_networks => ["10.0.0.0/8", "2606:2800:220:1:248:1893:25c8:1946/120"]
176
+ add_field => { "success" => "success" }
143
177
  }
144
178
  }
145
179
  CONFIG
146
180
  end
147
181
 
148
182
  sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["1.2.3.4", "2606:2800:220:1:248:1893:25c8:1946"]) do
183
+ expect(subject).to include("success")
184
+ expect(subject).not_to include("tags")
185
+ expect(subject).to include("real_ip")
186
+ expect(subject.get('real_ip')).to eq('1.2.3.4')
187
+ end
188
+ end
189
+
190
+ describe "writes IPs to target array" do
191
+ let(:config) do <<-CONFIG
192
+ filter {
193
+ real_ip {
194
+ remote_address_field => "remote_addr"
195
+ x_forwarded_for_field => "xfwdfor"
196
+ x_forwarded_for_target => "xtarget"
197
+ trusted_networks => ["10.0.0.0/8", "192.168.0.0/16"]
198
+ add_field => { "success" => "success" }
199
+ }
200
+ }
201
+ CONFIG
202
+ end
203
+
204
+ sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["5.6.7.8", "1.2.3.4", "192.168.3.4"]) do
205
+ expect(subject).to include("success")
149
206
  expect(subject).not_to include("tags")
150
207
  expect(subject).to include("real_ip")
151
208
  expect(subject.get('real_ip')).to eq('1.2.3.4')
209
+ expect(subject.get('xtarget')).to eq(["5.6.7.8", "1.2.3.4", "192.168.3.4"])
210
+ end
211
+
212
+ sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["10.5", "1.2.3.4", "192.168.3.4"]) do
213
+ expect(subject).to include("success")
214
+ expect(subject).to include("tags")
215
+ expect(subject).to include("real_ip")
216
+ expect(subject.get('real_ip')).to eq('1.2.3.4')
217
+ expect(subject.get('xtarget')).to eq(["1.2.3.4", "192.168.3.4"])
218
+ expect(subject.get('tags')).to include('_real_ip_invalid_ip')
219
+ expect(subject.get('tags')).not_to include('_real_ip_lookup_failure')
220
+ end
221
+
222
+ sample("remote_addr" => "10.2.3.4", "xfwdfor" => ["10.5", "192.168.3.4"]) do
223
+ expect(subject).not_to include("success")
224
+ expect(subject).to include("tags")
225
+ expect(subject).not_to include("real_ip")
226
+ expect(subject.get('xtarget')).to eq(["192.168.3.4"])
227
+ expect(subject.get('tags')).to include('_real_ip_invalid_ip')
228
+ expect(subject.get('tags')).to include('_real_ip_lookup_failure')
152
229
  end
153
230
  end
231
+
154
232
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-real_ip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ferdinand Holzer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-04 00:00:00.000000000 Z
11
+ date: 2018-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement