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.
Latest Posts
- How to Choose a Technology Partner in Southeast Asia: A Practical Evaluation Guide for Enterprise Teams June 24, 2026
- On-Device AI in React Native: Run LLMs Locally with ExecuTorch June 22, 2026
- How to Add an AI Chatbot to Your React Native App (with FastAPI Backend) June 21, 2026
- pgvector Tutorial: Add Vector Search to PostgreSQL for RAG and Semantic Search June 14, 2026
- MES vs ERP: What’s the Difference and Which Does Your Factory Actually Need? June 7, 2026
- React Native vs Flutter in 2026: How to Actually Choose June 4, 2026
