Do you use Cisco’s network infrastructure? Would you like to view its logs through the syslog protocol in an Elasticsearch database? Find out below about the filters and templates needed for the Logstash setup.
As you probably already know, you need a Logstash instance in order to get indexed data into the Elasticsearch database. Cisco is a well-known network device provider, so it is crucial to have a workable solution to index the logs that can be retrieved from these devices.
This article mainly deals with two types of Cisco logs from three types of devices:
I have divided these elements into two filters since the Radius logs are completely different and have nothing in common with “normal” Cisco logs. Thus I used the following models:
CISCOTIMESTAMPTZ %{CISCOTIMESTAMP}( %{TZ})?
NEXUSTIMESTAMP %{YEAR} %{MONTH} %{MONTHDAY} %{TIME}( %{TZ})?
ISETIMESTAMP %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})? %{ISO8601_TIMEZONE}?
And then I wrote the following filtering rules:
# # FILTER - Try to parse the cisco log format # # Configuration: # clock timezone Europe +1 # no clock summer-time # ntp server 0.0.0.0 prefer # ntp server 129.6.15.28 # ntp server 131.107.13.100 # service timestamps log datetime msec show-timezone # service timestamps debug datetime msec show-timezone # logging source-interface Loopback0 # ! Two logging servers for redundancy # logging host 0.0.0.0 transport tcp port 8514 # logging host 0.0.0.0 transport tcp port 8514 # logging trap 6 filter { # NOTE: The frontend logstash servers set the type of incoming messages. if [type] == "syslog" and [host_group] == "Netzwerk" { # Parse the log entry into sections. Cisco doesn't use a consistent log format, unfortunately. grok { patterns_dir => "/var/lib/neteye/logstash/etc/pattern.d" match => [ # IOS "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} ((%{NUMBER:log_sequence#})?:( %{NUMBER}:)? )?%{CISCOTIMESTAMPTZ:log_date}: %%{CISCO_REASON:facility}-%{INT:severity_level}-%{CISCO_REASON:facility_mnemonic}: %{GREEDYDATA:message}", "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} ((%{NUMBER:log_sequence#})?:( %{NUMBER}:)? )?%{CISCOTIMESTAMPTZ:log_date}: %%{CISCO_REASON:facility}-%{CISCO_REASON:facility_sub}-%{INT:severity_level}-%{CISCO_REASON:facility_mnemonic}: %{GREEDYDATA:message}", # Nexus "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} ((%{NUMBER:log_sequence#})?: )?%{NEXUSTIMESTAMP:log_date}: %%{CISCO_REASON:facility}-%{INT:severity_level}-%{CISCO_REASON:facility_mnemonic}: %{GREEDYDATA:message}", "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} ((%{NUMBER:log_sequence#})?: )?%{NEXUSTIMESTAMP:log_date}: %%{CISCO_REASON:facility}-%{CISCO_REASON:facility_sub}-%{INT:severity_level}-%{CISCO_REASON:facility_mnemonic}: %{GREEDYDATA:message}", # WLC "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} %{SYSLOGHOST:wlc_host}: %{DATA:wlc_action}: %{CISCOTIMESTAMP:log_date}: %{DATA:wlc_mnemonic}: %{DATA:wlc_mnemonic_message} %{GREEDYDATA:message}" ] overwrite => [ "message" ] add_tag => [ "cisco" ] } } # If we made it here, the grok was sucessful if "cisco" in [tags] { date { match => [ "log_date", # IOS "MMM dd HH:mm:ss.SSS ZZZ", "MMM dd HH:mm:ss ZZZ", "MMM dd HH:mm:ss.SSS", # Nexus "YYYY MMM dd HH:mm:ss.SSS ZZZ", "YYYY MMM dd HH:mm:ss ZZZ", "YYYY MMM dd HH:mm:ss.SSS", # Hail marry "ISO8601" ] } # Add the log level's name instead of just a number. mutate { gsub => [ "severity_level", "0", "0 - Emergency", "severity_level", "1", "1 - Alert", "severity_level", "2", "2 - Critical", "severity_level", "3", "3 - Error", "severity_level", "4", "4 - Warning", "severity_level", "5", "5 - Notification", "severity_level", "6", "6 - Informational" ] } } # if } # filter
For Cisco Radius logs I used the following filters instead:
# # FILTER - Try to parse the ise logfiles (Radius) # filter { if [type] == "syslog" and [host_group] == "ISE" { grok { patterns_dir => "/var/lib/neteye/logstash/etc/pattern.d" match => [ "message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} %{DATA:ise_log_type} %{NUMBER:ise_log_sequence} %{INT:ise_log_lines_split} %{INT:ise_log_line_sequence} %{ISETIMESTAMP} %{NUMBER:ise_log_number} %{NUMBER:ise_log_id} %{DATA:ise_log_facility} %{DATA:ise_log_id_description},.* Device IP Address=%{IP:ise_device_ip},.* UserName=%{DATA:ise_username},.* NetworkDeviceName=%{DATA:ise_network_device_name},.* User-Name=%{DATA:ise_user_name},.* (NAS-Port-Id=%{DATA:ise_nas_port_id},.* )?(cisco-av-pair=%{DATA:ise_cisco_av_pair},.* )?AuthenticationMethod=%{DATA:ise_authentication_method},.* (AuthenticationStatus=%{DATA:ise_authentication_status}, .*)?(EndPointMACAddress=%{DATA:ise_endpoint_mac_address},.*)? Location=%{DATA:ise_location},%{GREEDYDATA:message}" ] add_tag => [ "ISE" ] remove_tag => [ "_grokparsefailure" ] tag_on_failure => [ "_iseparsefailure" ] } } } # filter
The entire solution now provides well-formatted Cisco logs in Elasticsearch, from which you can perform structured analyses and views. You can download the above-mentioned files from the following link ( Cisco-Logstash – Elasticsearch ).