Collect Cisco IOS logs
This document explains how to ingest Cisco IOS logs to Google Security Operations using the Bindplane agent.
Cisco IOS devices generate syslog messages for system events, interface state changes, ACL matches, authentication, and routing events. The parser extracts fields using grok patterns and maps them to the Unified Data Model (UDM).
Before you begin
Make sure you have the following prerequisites:
- A Google SecOps instance
- Windows Server 2016 or later, or Linux host with
systemd - Network connectivity between the Bindplane agent and the Cisco IOS device
- If running behind a proxy, ensure firewall ports are open per the Bindplane agent requirements
- Privileged access to the Cisco IOS device usingng SSH or console
Get Google SecOps ingestion authentication file
- Sign in to the Google SecOps console.
- Go to SIEM Settings > Collection Agents.
- Download the Ingestion Authentication File.
Save the file securely on the system where the Bindplane agent will be installed.
Get Google SecOps customer ID
- Sign in to the Google SecOps console.
- Go to SIEM Settings > Profile.
Copy and save the Customer ID from the Organization Details section.
Install the Bindplane agent
Install the Bindplane agent on your Windows or Linux operating system according to the following instructions.
Windows installation
- Open Command Prompt or PowerShell as an administrator.
Run the following command:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quietWait for the installation to complete.
Verify the installation by running:
sc query observiq-otel-collectorThe service should show as RUNNING.
Linux installation
- Open a terminal with root or sudo privileges.
Run the following command:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.shWait for the installation to complete.
Verify the installation by running:
sudo systemctl status observiq-otel-collectorThe service should show as active (running).
Additional installation resources
For additional installation options and troubleshooting, see Bindplane agent installation guide.
Configure the Bindplane agent to ingest syslog and send to Google SecOps
Locate the configuration file
Linux:
sudo nano /etc/bindplane-agent/config.yamlWindows:
notepad "C:\Program Files\observIQ OpenTelemetry Collector\config.yaml"
Edit the configuration file
Replace the entire contents of
config.yamlwith the following configuration:receivers: udplog: listen_address: "0.0.0.0:514" exporters: chronicle/cisco_ios: compression: gzip creds_file_path: '/etc/bindplane-agent/ingestion-auth.json' customer_id: '<customer_id>' endpoint: malachiteingestion-pa.googleapis.com log_type: CISCO_IOS raw_log_field: body service: pipelines: logs/cisco_ios_to_chronicle: receivers: - udplog exporters: - chronicle/cisco_ios
Configuration parameters
Replace the following placeholders:
Receiver configuration:
listen_address: IP address and port to listen on:0.0.0.0to listen on all interfaces (recommended)- Port
514is the standard syslog port (requires root on Linux; use1514for non-root)
Exporter configuration:
creds_file_path: Full path to ingestion authentication file:- Linux:
/etc/bindplane-agent/ingestion-auth.json - Windows:
C:\Program Files\observIQ OpenTelemetry Collector\ingestion-auth.json
- Linux:
customer_id: Customer ID copied from the Google SecOps consoleendpoint: Regional endpoint URL:- US:
malachiteingestion-pa.googleapis.com - Europe:
europe-malachiteingestion-pa.googleapis.com - Asia:
asia-southeast1-malachiteingestion-pa.googleapis.com - See Regional Endpoints for complete list
- US:
Save the configuration file
- After editing, save the file:
- Linux: Press
Ctrl+O, thenEnter, thenCtrl+X - Windows: Click File > Save
- Linux: Press
Restart the Bindplane agent to apply the changes
To restart the Bindplane agent in Linux, run the following command:
sudo systemctl restart observiq-otel-collectorVerify the service is running:
```bash sudo systemctl status observiq-otel-collector ```Check logs for errors:
```bash sudo journalctl -u observiq-otel-collector -f ```
To restart the Bindplane agent in Windows, choose one of the following options:
Command Prompt or PowerShell as administrator:
net stop observiq-otel-collector && net start observiq-otel-collectorServices console:
- Press
Win+R, typeservices.msc, and press Enter. - Locate observIQ OpenTelemetry Collector.
- Right-click and select Restart.
Verify the service is running:
sc query observiq-otel-collectorCheck logs for errors:
type "C:\Program Files\observIQ OpenTelemetry Collector\log\collector.log"
- Press
Configure syslog on Cisco IOS device
- Sign in to the Cisco IOS device using SSH or a console connection.
Enter privileged mode:
enableEnter configuration mode:
conf tConfigure syslog:
logging <BINDPLANE_IP> logging source-interface <INTERFACE>- Replace
<BINDPLANE_IP>with the actual Bindplane agent IP address. - Replace
<INTERFACE>with the actual communication interface.
- Replace
Configure the priority level:
logging trap information logging console informationConfigure the syslog facility:
logging facility syslogSave the configuration:
copy running-config startup-config
UDM mapping table
| Log field | UDM mapping | Logic |
|---|---|---|
| AcsSessionID | network.session_id | Value taken from AcsSessionID field. |
| AcctRequest-Flags | security_result.summary | Value taken from AcctRequest-Flags field. |
| AcctRequest-Flags | security_result.action | If AcctRequest-Flags contains Start, set to ALLOW. If AcctRequest-Flags contains Stop, set to BLOCK. |
| AuthenticationIdentityStore | additional.fields.key = AuthenticationIdentityStore, value = AuthenticationIdentityStore |
Value taken from AuthenticationIdentityStore field. |
| AuthenticationMethod | additional.fields.key = AuthenticationMethod, value = AuthenticationMethod |
Value taken from AuthenticationMethod field. |
| AuthenticationStatus | security_result.summary | Value taken from AuthenticationStatus field. |
| Authen-Method | security_result.detection_fields.key = Authen-Method, value = Authen-Method |
Value taken from Authen-Method field. |
| Authen-Method | extensions.auth.type | If Authen-Method contains TacacsPlus, set to TACACS. |
| AVPair_priv-lvl | security_result.detection_fields.key = AVPair_priv-lvl, value = AVPair_priv-lvl |
Value taken from AVPair_priv-lvl field. |
| AVPair_start_time | additional.fields.key = AVPair_start_time, value = AVPair_start_time |
Value taken from AVPair_start_time field. |
| AVPair_task_id | additional.fields.key = AVPair_task_id, value = AVPair_task_id |
Value taken from AVPair_task_id field. |
| AVPair_timezone | additional.fields.key = AVPair_timezone, value = AVPair_timezone |
Value taken from AVPair_timezone field. |
| auditid | metadata.product_log_id | Value taken from auditid field. |
| cisco_facility | Not mapped to the IDM object. | |
| cisco_message | metadata.description | Value taken from cisco_message field. |
| cisco_mnemonic | security_result.rule_name | Value taken from cisco_mnemonic field. |
| cisco_severity | security_result.severity | Mapped to different severity levels based on the value: 0: ALERT, 1: CRITICAL, 2: HIGH, 3: ERROR, 4: MEDIUM, 5: LOW, 6: INFORMATIONAL, 7: INFORMATIONAL. |
| cisco_severity | security_result.severity_details | Mapped to different severity details based on the value: 0: System unusable, 1: Immediate action needed, 2: Critical condition, 3: Error condition, 4: Warning condition, 5: Normal but significant condition, 6: Informational message only, 7: Appears during debugging only. |
| cisco_tag | metadata.product_event_type | Value taken from cisco_tag field. |
| cisco_tag | metadata.event_type | Mapped to different event types based on the value: SYS-6-LOGGINGHOST_STARTSTOP, TRACK-6-STATE, SYS-3-LOGGINGHOST_FAIL, CRYPTO-4-IKMP_NO_SA, HA_EM-3-FMPD_ACTION_NOTRACK, HA_EM-3-FMPD_ERROR: GENERIC_EVENT; IPSEC-3-REPLAY_ERROR, CRYPTO-4-RECVD_PKT_INV_SPI, IPSEC-3-HMAC_ERROR, FW-6-DROP_PKT, SEC-6-IPACCESSLOGP: NETWORK_UNCATEGORIZED; CRYPTO-4-IKMP_BAD_MESSAGE, CRYPTO-6-IKMP_NOT_ENCRYPTED, CRYPTO-6-IKMP_MODE_FAILURE: STATUS_UNCATEGORIZED; SYS-5-CONFIG_I: USER_UNCATEGORIZED. |
| ClientLatency | additional.fields.key = ClientLatency, value = ClientLatency |
Value taken from ClientLatency field. |
| CmdSet | additional.fields.key = CmdSet, value = CmdSet |
Value taken from CmdSet field. |
| command | principal.process.command_line | Value taken from command field. |
| CPMSessionID | additional.fields.key = CPMSessionID, value = CPMSessionID |
Value taken from CPMSessionID field. |
| description | metadata.description | Value taken from description field. |
| DestinationIPAddress | target.asset.ip | Value taken from DestinationIPAddress field. |
| DestinationIPAddress | target.ip | Value taken from DestinationIPAddress field. |
| DestinationPort | target.port | Value taken from DestinationPort field. |
| Device_IP_Address | principal.asset.ip | Value taken from Device_IP_Address field. |
| Device_IP_Address | principal.ip | Value taken from Device_IP_Address field. |
| Device_Type | additional.fields.key = Device_Type, value = Device_Type |
Value taken from Device_Type field. |
| dst_ip | target.asset.ip | Value taken from dst_ip field. |
| dst_ip | target.ip | Value taken from dst_ip field. |
| dst_port | target.port | Value taken from dst_port field. |
| dst_user | target.user.userid | Value taken from dst_user field. |
| EnableFlag | security_result.detection_fields.key = EnableFlag, value = EnableFlag |
Value taken from EnableFlag field. |
| IdentityGroup | additional.fields.key = IdentityGroup, value = IdentityGroup |
Value taken from IdentityGroup field. |
| IdentitySelectionMatchedRule | security_result.detection_fields.key = IdentitySelectionMatchedRule, value = IdentitySelectionMatchedRule |
Value taken from IdentitySelectionMatchedRule field. |
| intermediary_host | intermediary.hostname | Value taken from intermediary_host field. |
| intermediary_ip | intermediary.ip | Value taken from intermediary_ip field. |
| IPSEC | additional.fields.key = IPSEC, value = IPSEC |
Value taken from IPSEC field. |
| ISEPolicySetName | extensions.auth.type | If ISEPolicySetName contains Tacacs, set to TACACS. |
| IsMachineAuthentication | additional.fields.key = IsMachineAuthentication, value = IsMachineAuthentication |
Value taken from IsMachineAuthentication field. |
| IsMachineIdentity | security_result.detection_fields.key = IsMachineIdentity, value = IsMachineIdentity |
Value taken from IsMachineIdentity field. |
| Location | additional.fields.key = Location, value = Location |
Value taken from Location field. |
| MatchedCommandSet | additional.fields.key = MatchedCommandSet, value = MatchedCommandSet |
Value taken from MatchedCommandSet field. |
| message | Not mapped to the IDM object. | |
| metadata_event_type | metadata.event_type | Value taken from metadata_event_type field. If empty or GENERIC_EVENT, set to NETWORK_UNCATEGORIZED if principal_mid_present and target_mid_present are true, USER_UNCATEGORIZED if principal_userid_present is true, STATUS_UPDATE if principal_mid_present is true, or GENERIC_EVENT otherwise. If Service contains Login, set to USER_LOGIN if principal_userid_present, principal_mid_present, and target_mid_present are true, or USER_UNCATEGORIZED if principal_userid_present is true. |
| Model_Name | additional.fields.key = Model_Name, value = Model_Name |
Value taken from Model_Name field. |
| Name | additional.fields.key = Name, value = Name |
Value taken from Name field. |
| Network_Device_Profile | additional.fields.key = Network_Device_Profile, value = Network_Device_Profile |
Value taken from Network_Device_Profile field. |
| NetworkDeviceGroups | additional.fields.key = NetworkDeviceGroups, value = NetworkDeviceGroups |
Value taken from NetworkDeviceGroups field. |
| NetworkDeviceName | principal.asset.hostname | Value taken from NetworkDeviceName field. |
| NetworkDeviceName | principal.hostname | Value taken from NetworkDeviceName field. |
| NetworkDeviceProfileId | principal.resource.product_object_id | Value taken from NetworkDeviceProfileId field. |
| pid | principal.process.pid | Value taken from pid field. |
| Port | principal.resource.attribute.labels.key = Port, value = Port |
Value taken from Port field. |
| Privilege-Level | security_result.detection_fields.key = Privilege-Level, value = Privilege-Level |
Value taken from Privilege-Level field. |
| product_event_type | metadata.product_event_type | Value taken from product_event_type field. |
| Protocol | additional.fields.key = Protocol, value = Protocol |
Value taken from Protocol field. |
| protocol | network.application_protocol | If protocol is HTTPS, set to HTTPS. |
| protocol | network.ip_protocol | If protocol is TCP or UDP, set to the uppercase value of protocol. |
| reason | security_result.summary | Value taken from reason field. |
| region | principal.location.country_or_region | Value taken from region field. |
| Remote-Address | target.asset.ip | Value taken from Remote-Address field after validating it as an IP address. |
| Remote-Address | target.ip | Value taken from Remote-Address field after validating it as an IP address. |
| RequestLatency | security_result.detection_fields.key = RequestLatency, value = RequestLatency |
Value taken from RequestLatency field. |
| Response | additional.fields.key = Response, value = Response |
Value taken from Response field. |
| SelectedAccessService | security_result.action_details | Value taken from SelectedAccessService field. |
| SelectedAuthenticationIdentityStores | security_result.detection_fields.key = SelectedAuthenticationIdentityStores, value = SelectedAuthenticationIdentityStores |
Value taken from SelectedAuthenticationIdentityStores field. |
| SelectedCommandSet | additional.fields.key = SelectedCommandSet, value = SelectedCommandSet |
Value taken from SelectedCommandSet field. |
| Service | additional.fields.key = Service, value = Service |
Value taken from Service field. |
| Service-Argument | additional.fields.key = Service-Argument, value = Service-Argument |
Value taken from Service-Argument field. |
| severity | security_result.severity | If severity contains Notice, set to INFORMATIONAL. |
| Software_Version | additional.fields.key = Software_Version, value = Software_Version |
Value taken from Software_Version field. |
| source_facility | principal.asset.hostname | Value taken from source_facility field. |
| source_facility | principal.hostname | Value taken from source_facility field. |
| src_ip | principal.asset.ip | Value taken from src_ip field. |
| src_ip | principal.ip | Value taken from src_ip field. |
| src_mac | principal.mac | Value taken from src_mac field after replacing . with :. |
| src_port | principal.port | Value taken from src_port field. |
| src_user_id | principal.user.userid | Value taken from src_user_id field. If empty, take value from User field. If still empty, take value from StepData_9 field. |
| src_user_name | principal.user.user_display_name | Value taken from src_user_name field. |
| Step | additional.fields.key = Step, value = Step |
Value taken from Step field. |
| StepData_10 | principal.asset.hostname | Value taken from StepData_10 field. |
| StepData_10 | principal.hostname | Value taken from StepData_10 field. |
| StepData_13 | security_result.summary | Value taken from StepData_13 field. |
| StepData_14 | security_result.detection_fields.key = StepData_14, value = StepData_14 |
Value taken from StepData_14 field. |
| StepData_15 | security_result.detection_fields.key = StepData_15, value = StepData_15 |
Value taken from StepData_15 field. |
| StepData_20 | security_result.detection_fields.key = StepData_20, value = StepData_20 |
Value taken from StepData_20 field. |
| StepData_21 | security_result.detection_fields.key = StepData_21, value = StepData_21 |
Value taken from StepData_21 field. |
| StepData_3 | additional.fields.key = StepData_3, value = StepData_3 |
Value taken from StepData_3 field. |
| StepData_4 | security_result.detection_fields.key = StepData_4, value = StepData_4 |
Value taken from StepData_4 field. |
| StepData_6 | security_result.detection_fields.key = StepData_6, value = StepData_6 |
Value taken from StepData_6 field. |
| StepData_7 | security_result.detection_fields.key = StepData_7, value = StepData_7 |
Value taken from StepData_7 field. |
| StepData_8 | security_result.detection_fields.key = StepData_8, value = StepData_8 |
Value taken from StepData_8 field. |
| StepData_9 | principal.user.userid | Value taken from StepData_9 field if src_user_id and User fields are empty. |
| target_host | target.asset.hostname | Value taken from target_host field. |
| target_host | target.hostname | Value taken from target_host field. |
| timestamp | metadata.event_timestamp | Value taken from timestamp field after removing extra spaces and parsing the date. |
| TotalAuthenLatency | additional.fields.key = TotalAuthenLatency, value = TotalAuthenLatency |
Value taken from TotalAuthenLatency field. |
| ts | metadata.event_timestamp | Value taken from ts field after parsing the date. |
| Type | security_result.category_details | Value taken from Type field. |
| User | principal.user.userid | Value taken from User field if src_user_id is empty. |
| UserType | additional.fields.key = UserType, value = UserType |
Value taken from UserType field. |
| metadata.vendor_name | Set to CISCO. |
|
| metadata.product_name | Set to CISCO_IOS. |
|
| metadata.log_type | Set to CISCO_IOS. |
Need more help? Get answers from Community members and Google SecOps professionals.