Network Security

Monitoring Cisco Network Devices with Wazuh: A Complete Guide

Network engineers and SOC teams running Cisco infrastructure face a common problem: switches and routers generate thousands of syslog events per day, but without centralized parsing and alerting, most of it sits unread in a log file until something breaks.

This guide covers the complete pipeline — from configuring Cisco devices to send syslog, to writing detection rules in Wazuh that fire on real threats, to building a dashboard that makes the data actionable. By the end you’ll have a working setup that alerts on interface flaps, unauthorized config changes, failed logins, and ACL hits.

What you need before starting:

  • Wazuh Manager 4.x running (single-node or distributed)
  • Cisco device with IOS 12.4+, IOS-XE, ASA 9.x, or NX-OS 7+
  • Network connectivity between the Cisco device and Wazuh Manager on UDP/TCP 514
  • Admin access to both systems

Architecture overview

flowchart TD
    A["Cisco devices\n(IOS / ASA / NX-OS)"] -->|"syslog UDP/TCP 514"| B["Wazuh Manager\nlogcollector"]
    B --> C["Decoder engine\n(cisco-ios / cisco-asa)"]
    C --> D["Rules engine\n(level 3–15 alerts)"]
    D --> E["OpenSearch index\nwazuh-alerts-*"]
    E --> F["Wazuh Dashboard\n(Kibana)"]
    D -->|"level >= 10"| G["Active response\nor SOAR webhook"]

Cisco devices send raw syslog over UDP (default) or TCP. Wazuh’s logcollector receives it on port 514, passes it through the decoder pipeline to extract structured fields, then evaluates rules to determine alert level. Anything level 7+ surfaces in the dashboard; level 10+ can trigger active response or a webhook to your SOAR.


Step 1 — Configure Cisco to send syslog

IOS / IOS-XE switches and routers

conf t

! Point syslog at Wazuh Manager IP
logging host <WAZUH_IP> transport udp port 514

! Set severity level — informational captures logins, config changes, interface events
logging trap informational

! Add timestamps with milliseconds for accurate correlation
service timestamps log datetime msec show-timezone

! Optional: tag logs with hostname so Wazuh can identify the source
logging origin-id hostname

exit
write memory

Severity levels quick reference:

Level Keyword Typical events
0 emergencies System unusable
1 alerts Immediate action needed
2 critical Critical conditions
3 errors Error conditions
4 warnings Warning conditions
5 notifications Normal but significant
6 informational Login success, interface up/down, config changes
7 debugging Very verbose — avoid in production

informational (level 6) is the right default. debugging (level 7) will flood Wazuh with noise.

Cisco ASA (firewall)

logging enable
logging host inside <WAZUH_IP> 17/514
logging trap informational
logging device-id hostname

17/514 means protocol 17 (UDP), port 514. Replace inside with the interface facing your Wazuh Manager.

Cisco NX-OS

conf t
logging server <WAZUH_IP> 6 use-vrf management
logging timestamp milliseconds
logging source-interface mgmt0

Step 2 — Configure Wazuh Manager to receive syslog

Edit /var/ossec/etc/ossec.conf on the Wazuh Manager:

<ossec_config>

  <!-- Syslog listener for Cisco devices -->
  <remote>
    <connection>syslog</connection>
    <port>514</port>
    <protocol>udp</protocol>
    <!-- Restrict to your network device subnets -->
    <allowed-ips>10.10.0.0/16</allowed-ips>
    <allowed-ips>192.168.1.0/24</allowed-ips>
    <!-- Bind to the interface facing your network devices -->
    <local_ip>10.10.0.5</local_ip>
  </remote>

</ossec_config>

If you need TCP (more reliable for high-volume devices):

<remote>
  <connection>syslog</connection>
  <port>514</port>
  <protocol>tcp</protocol>
  <allowed-ips>10.10.0.0/16</allowed-ips>
  <local_ip>10.10.0.5</local_ip>
</remote>

Restart the manager:

sudo systemctl restart wazuh-manager

Verify the listener is up:

sudo ss -ulnp | grep 514
# Should show: udp UNCONN 0.0.0.0:514 process:"wazuh-remoted"

Step 3 — Verify syslog is arriving

Before tuning rules, confirm raw logs are reaching Wazuh:

# Watch the archive log in real time
sudo tail -f /var/ossec/logs/archives/archives.log | grep <CISCO_IP>

# Or check the JSON archive
sudo tail -f /var/ossec/logs/archives/archives.json | python3 -m json.tool | grep -A5 "cisco"

Trigger a test event on the Cisco device — log in via SSH, flap an interface, or run show version. You should see the raw syslog line appear within seconds.

If nothing arrives:

# Check wazuh-remoted is running
sudo systemctl status wazuh-manager

# Check for firewall blocking port 514
sudo iptables -L INPUT -n | grep 514

# Packet capture to confirm traffic is arriving at the host
sudo tcpdump -i any -n "udp port 514 and host <CISCO_IP>"

Step 4 — Wazuh’s built-in Cisco decoders

Wazuh ships decoders for Cisco IOS and ASA out of the box at:

/var/ossec/ruleset/decoders/0025-cisco_decoders.xml
/var/ossec/ruleset/decoders/0180-cisco_asa_decoders.xml

These extract structured fields from raw syslog lines. For example, a Cisco IOS login event:

Raw syslog:

Jun 10 14:23:45 switch01 33954: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] [Source: 192.168.1.50] [localport: 22] at 14:23:45 UTC Wed Jun 10 2025

After decoding, Wazuh extracts:

Field Value
data.srcip 192.168.1.50
data.dstuser admin
data.action LOGIN_SUCCESS
data.facility SEC_LOGIN
rule.groups cisco, authentication

You can test any log line against the decoder pipeline without restarting:

sudo /var/ossec/bin/wazuh-logtest
# Paste a raw syslog line and press Enter
# Output shows which decoder matched and what fields were extracted

Step 5 — Built-in Cisco detection rules

Wazuh’s Cisco rules live at /var/ossec/ruleset/rules/0400-cisco_rules.xml. Key rules to know:

Rule ID Description Default level
4716 Cisco IOS login failed 5
4717 Cisco IOS login success 3
4720 Cisco — interface down 5
4721 Cisco — interface up 3
4730 Cisco ASA — connection denied by ACL 6
4731 Cisco ASA — connection built 3
64001 Cisco — configuration changed 8

Level 8 for config changes means it shows up as a high-priority alert by default — good.


Step 6 — Write custom detection rules

Built-in rules cover the basics. Custom rules let you catch the threats that matter to your environment specifically. Custom rules go in /var/ossec/etc/rules/local_rules.xml.

Brute force login detection

Fire an alert when a source IP fails login 5 times in 2 minutes:

<group name="cisco,authentication,">

  <!-- Parent rule: single failed login -->
  <rule id="100200" level="5">
    <if_sid>4716</if_sid>
    <description>Cisco device login failed</description>
  </rule>

  <!-- Child rule: repeated failures = brute force -->
  <rule id="100201" level="10" frequency="5" timeframe="120">
    <if_matched_sid>100200</if_matched_sid>
    <same_srcip />
    <description>Cisco brute force: 5 failed logins in 2 minutes from $(srcip)</description>
    <group>authentication_failures,</group>
    <mitre>
      <id>T1110</id>
    </mitre>
  </rule>

</group>

Unauthorized config change

Alert when config is modified outside business hours or by a non-admin account:

<rule id="100202" level="12">
  <if_sid>64001</if_sid>
  <description>Cisco configuration changed — verify this was authorized</description>
  <group>config_change,pci_dss_10.2.5,gpg13_4.13,</group>
</rule>

ACL deny spike (potential scan or exfiltration attempt)

<rule id="100203" level="6">
  <if_sid>4730</if_sid>
  <description>Cisco ASA ACL deny</description>
</rule>

<rule id="100204" level="10" frequency="20" timeframe="60">
  <if_matched_sid>100203</if_matched_sid>
  <same_srcip />
  <description>Cisco ASA — 20+ ACL denies from $(srcip) in 60 seconds (possible scan)</description>
  <group>network_scan,</group>
  <mitre>
    <id>T1046</id>
  </mitre>
</rule>

Interface flapping (reliability issue or physical attack)

<rule id="100205" level="7" frequency="3" timeframe="300">
  <if_matched_sid>4720</if_matched_sid>
  <same_field>data.interface</same_field>
  <description>Cisco interface $(data.interface) flapped 3 times in 5 minutes</description>
  <group>network_reliability,</group>
</rule>

After adding custom rules, reload without restarting:

sudo /var/ossec/bin/wazuh-control reload

Test your new rules:

sudo /var/ossec/bin/wazuh-logtest
# Paste the relevant syslog line — output shows which rule matched and at what level

Step 7 — Dashboard setup in Wazuh / OpenSearch

Quick search filters to bookmark

In the Wazuh Dashboard (Discover view), save these KQL filters:

# All Cisco events
rule.groups: "cisco"

# Config changes only
rule.groups: "config_change"

# Authentication events
rule.groups: "cisco" AND rule.groups: "authentication"

# High severity Cisco alerts
rule.groups: "cisco" AND rule.level >= 10

# Specific device
agent.name: "switch01"

Recommended dashboard panels

Build a Cisco monitoring dashboard with these visualizations:

Panel Type KQL filter
Cisco events over time Time series rule.groups: "cisco"
Top alerting devices Pie / table rule.groups: "cisco" — split by agent.name
Failed logins by source IP Data table rule.id: 4716 — split by data.srcip
Interface up/down timeline Time series rule.id: (4720 OR 4721)
Config changes Table rule.id: 64001 OR rule.id: 100202
ACL deny top sources Bar chart rule.id: 4730 — split by data.srcip

Common issues and fixes

Syslog arriving but no decoder match:

# Run wazuh-logtest and paste the raw syslog line
# If it shows "No decoder matched" the format differs from expected
# Check the exact facility/severity prefix — some NX-OS versions format differently
sudo /var/ossec/bin/wazuh-logtest

Logs arriving with wrong source IP (showing Docker gateway instead of device):

This happens when Wazuh Manager runs in Docker. The container NATs incoming traffic. Fix: use host network mode for the Wazuh Manager container, or configure the Cisco device to send to the Docker host IP and add a port-forward rule.

Port 514 already in use by rsyslog:

sudo systemctl stop rsyslog
sudo systemctl disable rsyslog
sudo systemctl restart wazuh-manager

Or configure rsyslog to forward to Wazuh on a different port (1514) and adjust <port> in ossec.conf.

High alert volume / noise from a specific rule:

Add a suppression in local_rules.xml:

<rule id="100299" level="0">
  <if_sid>4717</if_sid>
  <srcip>10.10.0.1</srcip>
  <description>Suppress login success alerts from monitoring system</description>
</rule>

What to monitor — priority alert checklist

Event Rule IDs Why it matters
Failed login (3+) 100201 Brute force or credential stuffing
Config change 100202 Unauthorized change = top compliance finding
ACL deny spike 100204 Active scan or C2 beaconing
Interface flap 100205 Physical issue, loop, or deliberate disruption
Privilege escalation (enable) Custom Admin access outside change window
Unknown source IP login Custom Lateral movement or compromised host

FAQ

Does Wazuh support Cisco Meraki?

Meraki uses a different logging format from IOS/ASA. You’ll need a custom decoder. Meraki does support syslog export — set the syslog server to your Wazuh Manager IP and write a decoder matching the flows and events format Meraki produces.

Can I monitor Cisco Catalyst Center (formerly DNA Center) with Wazuh?

Catalyst Center exposes syslog and REST API events. The syslog path works with the standard setup above. For API-based collection, use a Wazuh custom integration script to poll the Catalyst Center API and inject events as Wazuh alerts.

How many Cisco devices can one Wazuh Manager handle?

A single Wazuh Manager on 4 vCPU / 8 GB RAM handles roughly 1,000–3,000 events per second (EPS). For a campus network with 50–100 switches at informational level, this is well within limits. For high-volume ASA firewalls in busy datacenters, consider Wazuh’s distributed deployment with a worker node dedicated to syslog ingestion.

Should I use UDP or TCP syslog?

UDP is simpler and lower overhead — fine for most environments. Use TCP when you need guaranteed delivery (compliance environments, high-value devices). TCP also supports TLS encryption (logging host <IP> transport tcp port 6514) which is recommended if syslog crosses untrusted segments.

How do I test a custom rule without triggering a real event?

Use wazuh-logtest:

sudo /var/ossec/bin/wazuh-logtest
# Paste any historical syslog line from archives.log
# Shows exactly which rule fires, at what level, with which fields extracted

Next steps

Once Cisco syslog is flowing and alerting, the natural next step is correlating network events with endpoint and server alerts — so a failed login on a switch followed by a successful login on a server from the same IP becomes a single correlated incident.

For a full SOC stack built around Wazuh — including IRIS-web for case management and Shuffle for automated response — see our guide: How to Build a Lightweight SOC Using Wazuh + Open Source.

Need help writing custom decoders for your specific Cisco firmware version, or building dashboards for a multi-site environment? Contact us at hello@simplico.net.