Logstash Filter for Cisco ASA Source Destination and Communication

I want to configure logstash filter to see asa logs with communication detail.

LOG Sample:

Dec 27 02:48:08 Test-FW : %ASA-6-302014: Teardown TCP connection 3505833084 for Test-OUT:192.168.1.10/58538 to Mgmt-IN:192.168.100.10/1159 duration 0:00:00 bytes 4153 TCP FINs from Test-OUT

Need for Below Data filter: Source IP: 192.168.1.10 Destination IP: 192.168.100.10 Source Port: 58538 Destination Port: 1159 Source Zone: Test-OUT Destination Zone: Mgmt-IN Protocol: TCP Device Name: Test-FW Size: 4153 Bytes (Optional)

Below configuraiton not working:

input {
beats {
port => 5044
}
}
filter {
grok {
id => "ASA"
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:[%{POSINT:syslog_pid}])?: %{GREEDYDATA:syslog_message}" }
#       add_field => [ "received_at", "%{@timestamp}" ]
#       add_field => [ "received_from", "%{host}" ] }

}
grok {
id => "ALLOW-SRC-DST"
match => { "syslog_message" => "inside:%{HOSTNAME:inside_host}/%{NUMBER:inside_port} to outside:%{HOSTNAME:outside_host}/%{NUMBER:outside_port}" }
}
#syslog_pri { }
#      date { match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
#    }
}

output {
if [@metadata][pipeline] {
elasticsearch {
hosts => ["http://localhost:9200"]
manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
pipeline => "%{[@metadata][pipeline]}"
}
}
else {
elasticsearch {
hosts => ["http://localhost:9200"]
manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
}
}

Why not use the predefined firewall patterns that know how to parse ASA log messages?

its not working, i just pasted the filter mentioned in link to logstash filter.conf and getting errors.

Config file

filter {
#== Cisco ASA ==
CISCO_TAGGED_SYSLOG ^<%{POSINT:syslog_pri}>%{CISCOTIMESTAMP:timestamp}( %{SYSLOGHOST:sysloghost})? ?: %%{CISCOTAG:ciscotag}:
CISCOTIMESTAMP %{MONTH} +%{MONTHDAY}(?: %{YEAR})? %{TIME}
CISCOTAG [A-Z0-9]+-%{INT}-(?:[A-Z0-9_]+)

Common Particles

CISCO_ACTION Built|Teardown|Deny|Denied|denied|requested|permitted|denied by ACL|discarded|est-allowed|Dropping|created|deleted
CISCO_REASON Duplicate TCP SYN|Failed to locate egress interface|Invalid transport field|No matching connection|DNS Response|DNS Query|(?:%{WORD}\s*)*
CISCO_DIRECTION Inbound|inbound|Outbound|outbound
CISCO_INTERVAL first hit|%{INT}-second interval
CISCO_XLATE_TYPE static|dynamic

ASA-1-104001

CISCOFW104001 ((?:Primary|Secondary)) Switching to ACTIVE - %{GREEDYDATA:switch_reason}

ASA-1-104002

CISCOFW104002 ((?:Primary|Secondary)) Switching to STANDBY - %{GREEDYDATA:switch_reason}

ASA-1-104003

CISCOFW104003 ((?:Primary|Secondary)) Switching to FAILED.

ASA-1-104004

CISCOFW104004 ((?:Primary|Secondary)) Switching to OK.

ASA-1-105003

CISCOFW105003 ((?:Primary|Secondary)) Monitoring on [Ii]nterface %{GREEDYDATA:interface_name} waiting

ASA-1-105004

CISCOFW105004 ((?:Primary|Secondary)) Monitoring on [Ii]nterface %{GREEDYDATA:interface_name} normal

ASA-1-105005

CISCOFW105005 ((?:Primary|Secondary)) Lost Failover communications with mate on [Ii]nterface %{GREEDYDATA:interface_name}

ASA-1-105008

CISCOFW105008 ((?:Primary|Secondary)) Testing [Ii]nterface %{GREEDYDATA:interface_name}

ASA-1-105009

CISCOFW105009 ((?:Primary|Secondary)) Testing on [Ii]nterface %{GREEDYDATA:interface_name} (?:Passed|Failed)

ASA-2-106001

CISCOFW106001 %{CISCO_DIRECTION:direction} %{WORD:protocol} connection %{CISCO_ACTION:action} from %{IP:src_ip}/%{INT:src_port} to %{IP:dst_ip}/%{INT:dst_port} flags %{GREEDYDATA:tcp_flags} on interface %{GREEDYDATA:interface}

ASA-2-106006, ASA-2-106007, ASA-2-106010

CISCOFW106006_106007_106010 %{CISCO_ACTION:action} %{CISCO_DIRECTION:direction} %{WORD:protocol} (?:from|src) %{IP:src_ip}/%{INT:src_port}((%{DATA:src_fwuser}))? (?:to|dst) %{IP:dst_ip}/%{INT:dst_port}((%{DATA:dst_fwuser}))? (?:on interface %{DATA:interface}|due to %{CISCO_REASON:reason})

ASA-3-106014

CISCOFW106014 %{CISCO_ACTION:action} %{CISCO_DIRECTION:direction} %{WORD:protocol} src %{DATA:src_interface}:%{IP:src_ip}((%{DATA:src_fwuser}))? dst %{DATA:dst_interface}:%{IP:dst_ip}((%{DATA:dst_fwuser}))? (type %{INT:icmp_type}, code %{INT:icmp_code})

ASA-6-106015

CISCOFW106015 %{CISCO_ACTION:action} %{WORD:protocol} (%{DATA:policy_id}) from %{IP:src_ip}/%{INT:src_port} to %{IP:dst_ip}/%{INT:dst_port} flags %{DATA:tcp_flags} on interface %{GREEDYDATA:interface}

ASA-1-106021

CISCOFW106021 %{CISCO_ACTION:action} %{WORD:protocol} reverse path check from %{IP:src_ip} to %{IP:dst_ip} on interface %{GREEDYDATA:interface}

ASA-4-106023

CISCOFW106023 %{CISCO_ACTION:action}( protocol)? %{WORD:protocol} src %{DATA:src_interface}:%{DATA:src_ip}(/%{INT:src_port})?((%{DATA:src_fwuser}))? dst %{DATA:dst_interface}:%{DATA:dst_ip}(/%{INT:dst_port})?((%{DATA:dst_fwuser}))?( (type %{INT:icmp_type}, code %{INT:icmp_code}))? by access-group "?%{DATA:policy_id}"? [%{DATA:hashcode1}, %{DATA:hashcode2}]

ASA-4-106100, ASA-4-106102, ASA-4-106103

CISCOFW106100_2_3 access-list %{NOTSPACE:policy_id} %{CISCO_ACTION:action} %{WORD:protocol} for user '%{DATA:src_fwuser}' %{DATA:src_interface}/%{IP:src_ip}(%{INT:src_port}) -> %{DATA:dst_interface}/%{IP:dst_ip}(%{INT:dst_port}) hit-cnt %{INT:hit_count} %{CISCO_INTERVAL:interval} [%{DATA:hashcode1}, %{DATA:hashcode2}]

ASA-5-106100

CISCOFW106100 access-list %{NOTSPACE:policy_id} %{CISCO_ACTION:action} %{WORD:protocol} %{DATA:src_interface}/%{IP:src_ip}(%{INT:src_port})((%{DATA:src_fwuser}))? -> %{DATA:dst_interface}/%{IP:dst_ip}(%{INT:dst_port})((%{DATA:src_fwuser}))? hit-cnt %{INT:hit_count} %{CISCO_INTERVAL:interval} [%{DATA:hashcode1}, %{DATA:hashcode2}]

ASA-5-304001

CISCOFW304001 %{IP:src_ip}((%{DATA:src_fwuser}))? Accessed URL %{IP:dst_ip}:%{GREEDYDATA:dst_url}

ASA-6-110002

CISCOFW110002 %{CISCO_REASON:reason} for %{WORD:protocol} from %{DATA:src_interface}:%{IP:src_ip}/%{INT:src_port} to %{IP:dst_ip}/%{INT:dst_port}

ASA-6-302010

CISCOFW302010 %{INT:connection_count} in use, %{INT:connection_count_max} most used

ASA-6-302013, ASA-6-302014, ASA-6-302015, ASA-6-302016

CISCOFW302013_302014_302015_302016 %{CISCO_ACTION:action}(?: %{CISCO_DIRECTION:direction})? %{WORD:protocol} connection %{INT:connection_id} for %{DATA:src_interface}:%{IP:src_ip}/%{INT:src_port}( (%{IP:src_mapped_ip}/%{INT:src_mapped_port}))?((%{DATA:src_fwuser}))? to %{DATA:dst_interface}:%{IP:dst_ip}/%{INT:dst_port}( (%{IP:dst_mapped_ip}/%{INT:dst_mapped_port}))?((%{DATA:dst_fwuser}))?( duration %{TIME:duration} bytes %{INT:bytes})?(?: %{CISCO_REASON:reason})?( (%{DATA:user}))?

ASA-6-302020, ASA-6-302021

CISCOFW302020_302021 %{CISCO_ACTION:action}(?: %{CISCO_DIRECTION:direction})? %{WORD:protocol} connection for faddr %{IP:dst_ip}/%{INT:icmp_seq_num}(?:(%{DATA:fwuser}))? gaddr %{IP:src_xlated_ip}/%{INT:icmp_code_xlated} laddr %{IP:src_ip}/%{INT:icmp_code}( (%{DATA:user}))?

ASA-6-305011

CISCOFW305011 %{CISCO_ACTION:action} %{CISCO_XLATE_TYPE:xlate_type} %{WORD:protocol} translation from %{DATA:src_interface}:%{IP:src_ip}(/%{INT:src_port})?((%{DATA:src_fwuser}))? to %{DATA:src_xlated_interface}:%{IP:src_xlated_ip}/%{DATA:src_xlated_port}

ASA-3-313001, ASA-3-313004, ASA-3-313008

CISCOFW313001_313004_313008 %{CISCO_ACTION:action} %{WORD:protocol} type=%{INT:icmp_type}, code=%{INT:icmp_code} from %{IP:src_ip} on interface %{DATA:interface}( to %{IP:dst_ip})?

ASA-4-313005

CISCOFW313005 %{CISCO_REASON:reason} for %{WORD:protocol} error message: %{WORD:err_protocol} src %{DATA:err_src_interface}:%{IP:err_src_ip}((%{DATA:err_src_fwuser}))? dst %{DATA:err_dst_interface}:%{IP:err_dst_ip}((%{DATA:err_dst_fwuser}))? (type %{INT:err_icmp_type}, code %{INT:err_icmp_code}) on %{DATA:interface} interface. Original IP payload: %{WORD:protocol} src %{IP:orig_src_ip}/%{INT:orig_src_port}((%{DATA:orig_src_fwuser}))? dst %{IP:orig_dst_ip}/%{INT:orig_dst_port}((%{DATA:orig_dst_fwuser}))?

ASA-5-321001

CISCOFW321001 Resource '%{WORD:resource_name}' limit of %{POSINT:resource_limit} reached for system

ASA-4-402117

CISCOFW402117 %{WORD:protocol}: Received a non-IPSec packet (protocol= %{WORD:orig_protocol}) from %{IP:src_ip} to %{IP:dst_ip}

ASA-4-402119

CISCOFW402119 %{WORD:protocol}: Received an %{WORD:orig_protocol} packet (SPI= %{DATA:spi}, sequence number= %{DATA:seq_num}) from %{IP:src_ip} (user= %{DATA:user}) to %{IP:dst_ip} that failed anti-replay checking

ASA-4-419001

CISCOFW419001 %{CISCO_ACTION:action} %{WORD:protocol} packet from %{DATA:src_interface}:%{IP:src_ip}/%{INT:src_port} to %{DATA:dst_interface}:%{IP:dst_ip}/%{INT:dst_port}, reason: %{GREEDYDATA:reason}

ASA-4-419002

CISCOFW419002 %{CISCO_REASON:reason} from %{DATA:src_interface}:%{IP:src_ip}/%{INT:src_port} to %{DATA:dst_interface}:%{IP:dst_ip}/%{INT:dst_port} with different initial sequence number

ASA-4-500004

CISCOFW500004 %{CISCO_REASON:reason} for protocol=%{WORD:protocol}, from %{IP:src_ip}/%{INT:src_port} to %{IP:dst_ip}/%{INT:dst_port}

ASA-6-602303, ASA-6-602304

CISCOFW602303_602304 %{WORD:protocol}: An %{CISCO_DIRECTION:direction} %{GREEDYDATA:tunnel_type} SA (SPI= %{DATA:spi}) between %{IP:src_ip} and %{IP:dst_ip} (user= %{DATA:user}) has been %{CISCO_ACTION:action}

ASA-7-710001, ASA-7-710002, ASA-7-710003, ASA-7-710005, ASA-7-710006

CISCOFW710001_710002_710003_710005_710006 %{WORD:protocol} (?:request|access) %{CISCO_ACTION:action} from %{IP:src_ip}/%{INT:src_port} to %{DATA:dst_interface}:%{IP:dst_ip}/%{INT:dst_port}

ASA-6-713172

CISCOFW713172 Group = %{GREEDYDATA:group}, IP = %{IP:src_ip}, Automatic NAT Detection Status:\s+Remote end\s*%{DATA:is_remote_natted}\sbehind a NAT device\s+This\s+end\s%{DATA:is_local_natted}\s*behind a NAT device

ASA-4-733100

CISCOFW733100 [\s*%{DATA:drop_type}\s*] drop %{DATA:drop_rate_id} exceeded. Current burst rate is %{INT:drop_rate_current_burst} per second, max configured rate is %{INT:drop_rate_max_burst}; Current average rate is %{INT:drop_rate_current_avg} per second, max configured rate is %{INT:drop_rate_max_avg}; Cumulative total count is %{INT:drop_total_count}
#== End Cisco ASA ==

Shorewall firewall logs

SHOREWALL (%{SYSLOGTIMESTAMP:timestamp}) (%{WORD:nf_host}) .*Shorewall:(%{WORD:nf_action1})?:(%{WORD:nf_action2})?.IN=(%{USERNAME:nf_in_interface})?.(OUT= *MAC=(%{COMMONMAC:nf_dst_mac}):(%{COMMONMAC:nf_src_mac})?|OUT=%{USERNAME:nf_out_interface}).*SRC=(%{IPV4:nf_src_ip}).*DST=(%{IPV4:nf_dst_ip}).LEN=(%{WORD:nf_len}).?TOS=(%{WORD:nf_tos}).?PREC=(%{WORD:nf_prec}).?TTL=(%{INT:nf_ttl}).?ID=(%{INT:nf_id}).?PROTO=(%{WORD:nf_protocol}).?SPT=(%{INT:nf_src_port}?.DPT=%{INT:nf_dst_port}?.)
#== End Shorewall
#== SuSE Firewall 2 ==
SFW2 ((%{SYSLOGTIMESTAMP:timestamp})|(%{TIMESTAMP_ISO8601:timestamp}))\s
%{HOSTNAME}\s
kernel\S+\s
(?:%{NAGIOSTIME}\s
)?SFW2-INext-%{NOTSPACE:nf_action}\s
IN=%{USERNAME:nf_in_interface}.OUT=(\s%{USERNAME:nf_out_interface})?\s
MAC=((%{COMMONMAC:nf_dst_mac}:%{COMMONMAC:nf_src_mac})|(\s
)).SRC=%{IP:nf_src_ip}\sDST=%{IP:nf_dst_ip}.*PROTO=%{WORD:nf_protocol}((.*SPT=%{INT:nf_src_port}.DPT=%{INT:nf_dst_port}.)|())
#== End SuSE ==
}

=============================================================================
ERROR

[2022-12-28T23:59:35,246][INFO ][logstash.runner ] Log4j configuration path used is: /etc/logstash/log4j2.properties
[2022-12-28T23:59:35,255][INFO ][logstash.runner ] Starting Logstash {"logstash.version"=>"7.17.8", "jruby.version"=>"jruby 9.2.20.1 (2.5.8) 2021-11-30 2a2962fbd1 OpenJDK 64-Bit Server VM 11.0.17+8 on 11.0.17+8 +indy +jit [linux-x86_64]"}
[2022-12-28T23:59:35,257][INFO ][logstash.runner ] JVM bootstrap flags: [-Xms1g, -Xmx1g, -XX:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -Djdk.io.File.enableADS=true, -Djruby.compile.invokedynamic=true, -Djruby.jit.threshold=0, -Djruby.regexp.interruptible=true, -XX:+HeapDumpOnOutOfMemoryError, -Djava.security.egd=file:/dev/urandom, -Dlog4j2.isThreadContextMapInheritable=true]
[2022-12-28T23:59:35,525][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2022-12-28T23:59:36,530][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600, :ssl_enabled=>false}
[2022-12-28T23:59:37,192][ERROR][logstash.agent ] Failed to execute action {:action=>LogStash::PipelineAction::Create/pipeline_id:main, :exception=>"LogStash::ConfigurationError", :message=>"Expected one of [ \t\r\n], "#", "{" at line 3, column 21 (byte 47) after filter {\n#== Cisco ASA ==\nCISCO_TAGGED_SYSLOG ", :backtrace=>["/usr/share/logstash/logstash-core/lib/logstash/compiler.rb:32:in compile_imperative'", "org/logstash/execution/AbstractPipelineExt.java:189:in initialize'", "org/logstash/execution/JavaBasePipelineExt.java:72:in initialize'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:48:in initialize'", "/usr/share/logstash/logstash-core/lib/logstash/pipeline_action/create.rb:52:in execute'", "/usr/share/logstash/logstash-core/lib/logstash/agent.rb:392:in block in converge_state'"]}
[2022-12-28T23:59:37,261][INFO ][logstash.runner ] Logstash shut down.
[2022-12-28T23:59:37,269][FATAL][org.logstash.Logstash ] Logstash stopped processing because of an error: (SystemExit) exit

This will not work, your configuration is wrong, you should not paste the patterns in your configuration, they are already available internally to Logstash.

This is the cause of this error:

[2022-12-28T23:59:37,192][ERROR][logstash.agent ] Failed to execute action {:action=>LogStash::PipelineAction::Create/pipeline_id:main, :exception=>"LogStash::ConfigurationError", :message=>"Expected one of [ \t\r\n], "#", "{" at line 3, column 21 (byte 47) after filter {\n#== Cisco ASA ==\nCISCO_TAGGED_SYSLOG "

What you need to do is use them in your grok filters.

Something like this:

grok {
    match => { "syslog_message" => "%{CISCOFW302013_302014_302015_302016}" }
}

still not working:

Using Below:
filter {
grok {
match => { "syslog_message" => "%{CISCOFW302013_302014_302015_302016}" }
}
}
~

Error:

  • beats_input_codec_plain_applied
  • _grokparsefailure

This should work. I have followed logic: # ASA-6-302013, ASA-6-302014, ASA-6-302015, ASA-6-302016. If you want ECS, then use this. TCP FINs is explained here.

filter {
 grok {
  id => "ASA"
  match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:[%{POSINT:syslog_pid}])?: %%{DATA:asa}: %{CISCO_ACTION:action} %{WORD:protocol} connection %{INT:connection_id} for %{DATA:src_interface}:%{IP:src_ip}/%{INT:src_port} to %{DATA:dst_interface}:%{IP:dst_ip}/%{INT:dst_port}( duration %{TIME:duration} bytes %{INT:bytes})? %{CISCO_REASON:reason} from %{GREEDYDATA:src_interface}" }
 }
}

Sorry for the pic, should be a proof.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.