Skip to content

Commit 5a03647

Browse files
author
Andrew Stucki
authored
[Filebeat] Add fortinet/firewall network direction override based on interface (#23072)
* [Filebeat] Add fortinet/firewall network direction override based on interface * Add changelog entry * Don't override categorization if no interface name is set
1 parent 76b7c8c commit 5a03647

10 files changed

Lines changed: 157 additions & 8 deletions

File tree

CHANGELOG.next.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
347347
- Fix network.direction logic in zeek connection fileset. {pull}22967[22967]
348348
- Convert the o365 module's `client.port` and `source.port` to numbers (from strings) in events. {pull}22939[22939]
349349
- Fix Cisco ASA/FTD module's parsing of WebVPN log message 716002. {pull}22966[22966]
350+
- Fix bad `network.direction` values in Fortinet/firewall fileset. {pull}23072[23072]
350351

351352
*Heartbeat*
352353

@@ -763,6 +764,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
763764
- Allow cisco/asa and cisco/ftd filesets to override network directionality based off of zones. {pull}23068[23068]
764765
- Add `network.direction` to netflow/log fileset. {pull}23052[23052]
765766
- Allow cef and checkpoint modules to override network directionality based off of zones {pull}23066[23066]
767+
- Add the ability to override `network.direction` based on interfaces in Fortinet/firewall fileset. {pull}23072[23072]
766768

767769
*Heartbeat*
768770

x-pack/filebeat/filebeat.reference.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,16 @@ filebeat.modules:
798798
# The port to listen for syslog traffic. Defaults to 9004.
799799
#var.syslog_port: 9004
800800

801+
# Set internal interfaces. used to override parsed network.direction
802+
# based on a tagged interface. Both internal and external interfaces must be
803+
# set to leverage this functionality.
804+
#var.internal_interfaces: [ "LAN" ]
805+
806+
# Set external interfaces. used to override parsed network.direction
807+
# based on a tagged interface. Both internal and external interfaces must be
808+
# set to leverage this functionality.
809+
#var.external_interfaces: [ "WAN" ]
810+
801811
clientendpoint:
802812
enabled: true
803813

x-pack/filebeat/module/fortinet/_meta/config.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212
# The port to listen for syslog traffic. Defaults to 9004.
1313
#var.syslog_port: 9004
1414

15+
# Set internal interfaces. used to override parsed network.direction
16+
# based on a tagged interface. Both internal and external interfaces must be
17+
# set to leverage this functionality.
18+
#var.internal_interfaces: [ "LAN" ]
19+
20+
# Set external interfaces. used to override parsed network.direction
21+
# based on a tagged interface. Both internal and external interfaces must be
22+
# set to leverage this functionality.
23+
#var.external_interfaces: [ "WAN" ]
24+
1525
clientendpoint:
1626
enabled: true
1727

x-pack/filebeat/module/fortinet/firewall/config/firewall.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,17 @@ processors:
2828
target: ''
2929
fields:
3030
ecs.version: 1.7.0
31+
32+
{{ if .external_interfaces }}
33+
- add_fields:
34+
target: _temp
35+
fields:
36+
external_interfaces: {{ .external_interfaces | tojson }}
37+
{{ end }}
38+
39+
{{ if .internal_interfaces }}
40+
- add_fields:
41+
target: _temp
42+
fields:
43+
internal_interfaces: {{ .internal_interfaces | tojson }}
44+
{{ end }}

x-pack/filebeat/module/fortinet/firewall/ingest/event.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ processors:
6161
field: fortinet.firewall.remip
6262
target_field: destination.ip
6363
ignore_missing: true
64-
if: "ctx.destination?.ip == null"
64+
if: "ctx.destination?.ip == null"
6565
- convert:
6666
field: fortinet.firewall.dstport
6767
target_field: destination.port
@@ -183,11 +183,30 @@ processors:
183183
field: fortinet.firewall.dir
184184
target_field: network.direction
185185
ignore_missing: true
186+
if: 'ctx.network?.direction == null'
186187
- rename:
187188
field: fortinet.firewall.direction
188189
target_field: network.direction
189190
ignore_missing: true
190191
if: "ctx.network?.direction == null"
192+
# Normalize the network direction
193+
- script:
194+
lang: painless
195+
ignore_failure: true
196+
params:
197+
outgoing: outbound
198+
incoming: inbound
199+
source: >-
200+
if (ctx.network?.direction == null) {
201+
return;
202+
}
203+
def k = ctx.network?.direction.toLowerCase();
204+
def normalized = params.get(k);
205+
if (normalized != null) {
206+
ctx.network.direction = normalized;
207+
return
208+
}
209+
ctx.network.direction = k;
191210
- rename:
192211
field: fortinet.firewall.service
193212
target_field: network.protocol
@@ -320,8 +339,10 @@ processors:
320339
- fortinet.firewall.locport
321340
- fortinet.firewall.filesize
322341
- fortinet.firewall.sess_duration
342+
- fortinet.firewall.dir
343+
- fortinet.firewall.direction
323344
ignore_missing: true
324345
on_failure:
325346
- set:
326347
field: error.message
327-
value: '{{ _ingest.on_failure_message }}'
348+
value: '{{ _ingest.on_failure_message }}'

x-pack/filebeat/module/fortinet/firewall/ingest/pipeline.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,65 @@ processors:
161161
- remove:
162162
field: fortinet.firewall.tunnelip
163163
if: "ctx.fortinet?.firewall?.tunnelip == 'N/A'"
164+
# Handle interface-based network directionality
165+
- set:
166+
field: network.direction
167+
value: inbound
168+
if: >
169+
ctx?._temp?.external_interfaces != null &&
170+
ctx?._temp?.internal_interfaces != null &&
171+
ctx?.observer?.ingress?.interface?.name != null &&
172+
ctx?.observer?.egress?.interface?.name != null &&
173+
ctx._temp.external_interfaces.contains(ctx.observer.ingress.interface.name) &&
174+
ctx._temp.internal_interfaces.contains(ctx.observer.egress.interface.name)
175+
- set:
176+
field: network.direction
177+
value: outbound
178+
if: >
179+
ctx?._temp?.external_interfaces != null &&
180+
ctx?._temp?.internal_interfaces != null &&
181+
ctx?.observer?.ingress?.interface?.name != null &&
182+
ctx?.observer?.egress?.interface?.name != null &&
183+
ctx._temp.external_interfaces.contains(ctx.observer.egress.interface.name) &&
184+
ctx._temp.internal_interfaces.contains(ctx.observer.ingress.interface.name)
185+
- set:
186+
field: network.direction
187+
value: internal
188+
if: >
189+
ctx?._temp?.external_interfaces != null &&
190+
ctx?._temp?.internal_interfaces != null &&
191+
ctx?.observer?.ingress?.interface?.name != null &&
192+
ctx?.observer?.egress?.interface?.name != null &&
193+
ctx._temp.internal_interfaces.contains(ctx.observer.egress.interface.name) &&
194+
ctx._temp.internal_interfaces.contains(ctx.observer.ingress.interface.name)
195+
- set:
196+
field: network.direction
197+
value: external
198+
if: >
199+
ctx?._temp?.external_interfaces != null &&
200+
ctx?._temp?.internal_interfaces != null &&
201+
ctx?.observer?.ingress?.interface?.name != null &&
202+
ctx?.observer?.egress?.interface?.name != null &&
203+
ctx._temp.external_interfaces.contains(ctx.observer.egress.interface.name) &&
204+
ctx._temp.external_interfaces.contains(ctx.observer.ingress.interface.name)
205+
- set:
206+
field: network.direction
207+
value: unknown
208+
if: >
209+
ctx?._temp?.external_interfaces != null &&
210+
ctx?._temp?.internal_interfaces != null &&
211+
ctx?.observer?.egress?.interface?.name != null &&
212+
ctx?.observer?.ingress?.interface?.name != null &&
213+
(
214+
(
215+
!ctx._temp.external_interfaces.contains(ctx.observer.egress.interface.name) &&
216+
!ctx._temp.internal_interfaces.contains(ctx.observer.egress.interface.name)
217+
) ||
218+
(
219+
!ctx._temp.external_interfaces.contains(ctx.observer.ingress.interface.name) &&
220+
!ctx._temp.internal_interfaces.contains(ctx.observer.ingress.interface.name)
221+
)
222+
)
164223
- remove:
165224
field:
166225
- _temp

x-pack/filebeat/module/fortinet/firewall/ingest/utm.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,30 @@ processors:
157157
field: fortinet.firewall.dir
158158
target_field: network.direction
159159
ignore_missing: true
160+
if: 'ctx.network?.direction == null'
160161
- rename:
161162
field: fortinet.firewall.direction
162163
target_field: network.direction
163164
ignore_missing: true
164165
if: "ctx.network?.direction == null"
166+
# Normalize the network direction
167+
- script:
168+
lang: painless
169+
ignore_failure: true
170+
params:
171+
outgoing: outbound
172+
incoming: inbound
173+
source: >-
174+
if (ctx.network?.direction == null) {
175+
return;
176+
}
177+
def k = ctx.network?.direction.toLowerCase();
178+
def normalized = params.get(k);
179+
if (normalized != null) {
180+
ctx.network.direction = normalized;
181+
return
182+
}
183+
ctx.network.direction = k;
165184
- rename:
166185
field: fortinet.firewall.error
167186
target_field: event.message
@@ -431,6 +450,8 @@ processors:
431450
- fortinet.firewall.srcport
432451
- fortinet.firewall.sentbyte
433452
- fortinet.firewall.filesize
453+
- fortinet.firewall.dir
454+
- fortinet.firewall.direction
434455
ignore_missing: true
435456
on_failure:
436457
- set:

x-pack/filebeat/module/fortinet/firewall/manifest.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ var:
99
default: 9004
1010
- name: input
1111
default: udp
12+
- name: internal_interfaces
13+
- name: external_interfaces
1214

1315
ingest_pipeline:
1416
- ingest/pipeline.yml

x-pack/filebeat/module/fortinet/firewall/test/fortinet.log-expected.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"log.offset": 0,
4343
"message": "URL belongs to a denied category in policy",
4444
"network.bytes": 2282,
45-
"network.direction": "outgoing",
45+
"network.direction": "outbound",
4646
"network.iana_number": "6",
4747
"network.protocol": "https",
4848
"observer.egress.interface.name": "wan1",
@@ -189,7 +189,7 @@
189189
"log.offset": 1278,
190190
"message": "URL belongs to an allowed category in policy",
191191
"network.bytes": 10357,
192-
"network.direction": "outgoing",
192+
"network.direction": "outbound",
193193
"network.iana_number": "6",
194194
"network.protocol": "https",
195195
"observer.egress.interface.name": "wan1",
@@ -264,7 +264,7 @@
264264
"log.offset": 1980,
265265
"message": "Web.Client: HTTPS.BROWSER,",
266266
"network.application": "HTTPS.BROWSER",
267-
"network.direction": "outgoing",
267+
"network.direction": "outbound",
268268
"network.iana_number": "6",
269269
"network.protocol": "ssl",
270270
"observer.egress.interface.name": "wan1",
@@ -339,7 +339,7 @@
339339
"log.offset": 2683,
340340
"message": "Web.Client: HTTPS.BROWSER,",
341341
"network.application": "HTTPS.BROWSER",
342-
"network.direction": "outgoing",
342+
"network.direction": "outbound",
343343
"network.iana_number": "6",
344344
"network.protocol": "ssl",
345345
"observer.egress.interface.name": "wan1",
@@ -555,7 +555,7 @@
555555
"log.offset": 4486,
556556
"message": "Web.Client: HTTPS.BROWSER,",
557557
"network.application": "HTTPS.BROWSER",
558-
"network.direction": "outgoing",
558+
"network.direction": "outbound",
559559
"network.iana_number": "6",
560560
"network.protocol": "ssl",
561561
"observer.egress.interface.name": "wan1",
@@ -1941,7 +1941,7 @@
19411941
"log.offset": 16463,
19421942
"message": "Web.Client: HTTPS.BROWSER,",
19431943
"network.application": "HTTPS.BROWSER",
1944-
"network.direction": "outgoing",
1944+
"network.direction": "outbound",
19451945
"network.iana_number": "6",
19461946
"network.protocol": "https",
19471947
"observer.egress.interface.name": "port9",

x-pack/filebeat/modules.d/fortinet.yml.disabled

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
# The port to listen for syslog traffic. Defaults to 9004.
1616
#var.syslog_port: 9004
1717

18+
# Set internal interfaces. used to override parsed network.direction
19+
# based on a tagged interface. Both internal and external interfaces must be
20+
# set to leverage this functionality.
21+
#var.internal_interfaces: [ "LAN" ]
22+
23+
# Set external interfaces. used to override parsed network.direction
24+
# based on a tagged interface. Both internal and external interfaces must be
25+
# set to leverage this functionality.
26+
#var.external_interfaces: [ "WAN" ]
27+
1828
clientendpoint:
1929
enabled: true
2030

0 commit comments

Comments
 (0)