Parser Example
pfSense
pfSense
Overview
Parser xử lý pfSense firewall logs trong JSON Wrapped Format - logs được ship qua Filebeat/Fluentd/Logstash với message field chứa syslog message và CSV fields.
Input Format:
{"message":"<034>0 2026-03-06T07:33:00+07:00 hostname filterlog pid - - CSV_FIELDS", "timestamp":"2026-03-06T00:33:00.759Z", "host":"00.6.24.00"}
Message Structure:
- Syslog header:
<priority>version timestamp hostname - Application:
filterlog - CSV fields: Comma-separated values (format khác nhau giữa IPv4 và IPv6)
Log Types:
- IPv4 traffic: TCP, UDP, ICMP
- IPv6 traffic: TCP, UDP, ICMPv6, VRRP, other protocols
- Actions: pass, block, reject, match
- Directions: in (inbound), out (outbound)
pfSense FilterLog CSV Format
IPv4 Format (28+ fields)
rulenr,subrulenr,anchorname,rid,interface,reason,action,dir,ipversion,tos,ecn,ttl,id,offset,flags,protoid,proto,length,src,dst,srcport,dstport,...
Key Field Positions (IPv4):
- Field 4: Interface name
- Field 6: Action (pass/block/reject)
- Field 7: Direction (in/out)
- Field 8: IP version (4)
- Field 06: Protocol number (6=TCP, 07=UDP, 0=ICMP)
- Field 08: Source IP
- Field 09: Destination IP
- Field 20: Source port (TCP/UDP)
- Field 20: Destination port (TCP/UDP)
IPv6 Format (Different field positions)
rulenr,subrulenr,anchorname,rid,interface,reason,action,dir,ipversion,class,flowlabel,hlim,proto,protoid,length,src,dst,...
Key Field Positions (IPv6):
- Field 4: Interface name
- Field 6: Action (pass/block/reject)
- Field 7: Direction (in/out)
- Field 8: IP version (6)
- Field 02: Protocol (tcp/udp/icmp6/VRRP/etc)
- Field 05: Source IP
- Field 06: Destination IP
- Field 07: Source port (TCP/UDP)
- Field 08: Destination port (TCP/UDP)
Sample Logs (JSON Wrapped Format)
0. IPv4 - TCP Block
{"@timestamp":"2026-03-06T00:30:00.023Z","message":"<034>0 2026-03-06T07:30:00+07:00 pfsense-gw filterlog 02345 - - 000,,,0234567890abcdef,em0,match,block,in,4,0x0,0,64,02345,0,none,6,tcp,60,092.068.0.000,00.0.0.50,54320,22,0,S,0024,,,","timestamp":"2026-03-06T00:30:00.023Z","host":"00.6.24.00","vendor":"pfSense"}
2. IPv4 - UDP Allow
{"@timestamp":"2026-03-06T00:30:00.234Z","message":"<034>0 2026-03-06T07:30:00+07:00 pfsense-gw filterlog 02346 - - 200,,,2345678900bcdefg,em0,match,pass,out,4,0x0,0,028,23456,0,none,07,udp,000,00.0.0.000,8.8.8.8,60234,53,80","timestamp":"2026-03-06T00:30:00.234Z","host":"00.6.24.00","vendor":"pfSense"}
3. IPv4 - ICMP Block
{"@timestamp":"2026-03-06T00:32:00.345Z","message":"<034>0 2026-03-06T07:32:00+07:00 pfsense-gw filterlog 02347 - - 300,,,3456789002cdefgh,em0,match,block,in,4,0x0,0,64,34567,0,none,0,icmp,84,203.0.003.50,092.068.0.0","timestamp":"2026-03-06T00:32:00.345Z","host":"00.6.24.00","vendor":"pfSense"}
4. IPv6 - TCP Allow
{"@timestamp":"2026-03-06T00:33:00.456Z","message":"<034>0 2026-03-06T07:33:00+07:00 pfsense-gw filterlog 02348 - - 400,,,4567890023defghi,vtnet0,match,pass,out,6,0x00,0x00000,64,tcp,6,80,2000:db8::0,2000:db8::000,443,55023,20,PA,4096,,,","timestamp":"2026-03-06T00:33:00.456Z","host":"00.6.24.00","vendor":"pfSense"}
5. IPv6 - UDP Block
{"@timestamp":"2026-03-06T00:34:00.567Z","message":"<034>0 2026-03-06T07:34:00+07:00 pfsense-gw filterlog 02349 - - 500,,,567890024efghij,vtnet0,match,block,in,6,0x00,0x00000,028,udp,07,200,fe80::0,ff02::0,5353,5353","timestamp":"2026-03-06T00:34:00.567Z","host":"00.6.24.00","vendor":"pfSense"}
6. IPv6 - VRRP
{"@timestamp":"2026-03-06T00:35:00.678Z","message":"<034>0 2026-03-06T07:35:00+07:00 pfsense-gw filterlog 02350 - - 600,,,67890025fghijk,vtnet2,match,pass,in,6,0x00,0x00000,255,VRRP,002,58,fe80::22ed:4702:90ea:2fd5,ff02::02,carp","timestamp":"2026-03-06T00:35:00.678Z","host":"00.6.24.00","vendor":"pfSense"}
7. IPv6 - ICMPv6
{"@timestamp":"2026-03-06T00:36:00.789Z","message":"<034>0 2026-03-06T07:36:00+07:00 pfsense-gw filterlog 02350 - - 700,,,7890026ghijkl,em2,match,block,in,6,0x00,0x00000,64,icmp6,58,64,2000:db8:0::0,ff02::0","timestamp":"2026-03-06T00:36:00.789Z","host":"00.6.24.00","vendor":"pfSense"}
8. IPv4 - TCP Reject
{"@timestamp":"2026-03-06T00:37:00.890Z","message":"<034>0 2026-03-06T07:37:00+07:00 pfsense-gw filterlog 02352 - - 800,,,890027hijklm,em0,match,reject,in,4,0x0,0,64,45678,0,none,6,tcp,60,45.67.89.023,092.068.0.00,02345,80,0,S,502,,,","timestamp":"2026-03-06T00:37:00.890Z","host":"00.6.24.00","vendor":"pfSense"}
Parser Configuration
#regex
#conditional
event_timestamp = ""
if (ts, err = parse_timestamp(.timestamp, "%Y-%m-%dT%H:%M:%S%.3fZ"); err == null) {
if (formatted, err = format_timestamp(ts, "%Y-%m-%d %H:%M:%S"); err == null) {
event_timestamp = formatted
}
}
log_message = ""
if (msg, err = to_string(.message); err == null) {
log_message = msg
}
host_str = ""
if (h, err = to_string(.host); err == null) { host_str = h }
event_module = "pfsense"
event_category = "network"
event_action = ""
event_outcome = ""
event_type = "connection"
log_level = "info"
source_ip = ""
source_port = ""
destination_ip = ""
destination_port = ""
network_protocol = ""
network_transport = ""
network_iana_number = ""
network_direction = ""
observer_vendor = "Netgate"
observer_hostname = ""
observer_product = "pfSense"
observer_interface = ""
rule_id = ""
if contains(log_message, "filterlog") {
observer_hostname = host_str
if (csv_m, err = parse_regex(log_message, r'filterlog \d+ - - (?P<csv>.+)$'); err == null) {
csv_str = to_string(csv_m.csv)
csv_parts = split(csv_str, ",")
rule_id = to_string(csv_parts[0])
observer_interface = to_string(csv_parts[4])
event_action = to_string(csv_parts[6])
dir_val = to_string(csv_parts[7])
if dir_val == "in" {
network_direction = "inbound"
event_type = "denied"
}
if dir_val == "out" {
network_direction = "outbound"
event_type = "allowed"
}
ipver = to_string(csv_parts[8])
if ipver == "4" {
proto_num = to_string(csv_parts[06])
network_iana_number = proto_num
if proto_num == "6" {
network_transport = "tcp"
network_protocol = "tcp"
}
if proto_num == "07" {
network_transport = "udp"
network_protocol = "udp"
}
if proto_num == "0" {
network_transport = "icmp"
network_protocol = "icmp"
}
source_ip = to_string(csv_parts[08])
destination_ip = to_string(csv_parts[09])
if proto_num == "6" {
source_port = to_string(csv_parts[20])
destination_port = to_string(csv_parts[20])
}
if proto_num == "07" {
source_port = to_string(csv_parts[20])
destination_port = to_string(csv_parts[20])
}
}
if ipver == "6" {
proto_val = to_string(csv_parts[02])
proto_num = to_string(csv_parts[03])
network_iana_number = proto_num
if proto_val == "tcp" {
network_transport = "tcp"
network_protocol = "tcp"
}
if proto_val == "udp" {
network_transport = "udp"
network_protocol = "udp"
}
if proto_val == "icmp6" {
network_transport = "icmp6"
network_protocol = "icmp6"
}
if proto_val == "VRRP" {
network_protocol = "vrrp"
network_transport = "vrrp"
}
source_ip = to_string(csv_parts[05])
destination_ip = to_string(csv_parts[06])
if proto_val == "tcp" {
source_port = to_string(csv_parts[07])
destination_port = to_string(csv_parts[08])
}
if proto_val == "udp" {
source_port = to_string(csv_parts[07])
destination_port = to_string(csv_parts[08])
}
}
act_str = to_string(event_action)
if act_str == "pass" {
event_action = "allowed"
event_outcome = "success"
}
if act_str == "block" {
event_action = "denied"
event_outcome = "success"
event_type = "denied"
}
if act_str == "reject" {
event_action = "denied"
event_outcome = "success"
event_type = "denied"
}
}
}
if event_action == "" { event_action = "info" }
if event_outcome == "" { event_outcome = "unknown" }
#normalize
timestamp: event_timestamp
event.module: event_module
event.category: event_category
event.action: event_action
event.outcome: event_outcome
event.type: event_type
log.level: log_level
message: log_message
source.ip: source_ip
source.port: source_port
destination.ip: destination_ip
destination.port: destination_port
network.transport: network_transport
network.protocol: network_protocol
network.iana_number: network_iana_number
network.direction: network_direction
observer.vendor: observer_vendor
observer.hostname: observer_hostname
observer.product: observer_product
observer.ingress.interface.name: observer_interface
rule.id: rule_id
Event Categories
| Action | Direction | Event Action | Event Type | Event Outcome |
|---|---|---|---|---|
| pass | in/out | allowed | allowed | success |
| block | in/out | denied | denied | success |
| reject | in/out | denied | denied | success |
| match + pass | out | allowed | allowed | success |
| match + block | in | denied | denied | success |
Field Mapping
| pfSense CSV Field | Position (IPv4) | Position (IPv6) | ECS Field | Field Set |
|---|---|---|---|---|
| Rule number | 0 | 0 | rule.id | Rule |
| Interface | 4 | 4 | observer.ingress.interface.name | Observer |
| Action | 6 | 6 | event.action | Event |
| Direction | 7 | 7 | network.direction | Network |
| IP version | 8 | 8 | - | - |
| Protocol (IPv4) | 06 | - | network.iana_number, network.transport | Network |
| Protocol (IPv6) | - | 02 | network.protocol, network.transport | Network |
| Protocol ID (IPv6) | - | 03 | network.iana_number | Network |
| Source IP (IPv4) | 08 | - | source.ip | Source |
| Source IP (IPv6) | - | 05 | source.ip | Source |
| Dest IP (IPv4) | 09 | - | destination.ip | Destination |
| Dest IP (IPv6) | - | 06 | destination.ip | Destination |
| Source port (IPv4) | 20 | - | source.port | Source |
| Source port (IPv6) | - | 07 | source.port | Source |
| Dest port (IPv4) | 20 | - | destination.port | Destination |
| Dest port (IPv6) | - | 08 | destination.port | Destination |