Complete Guide to Linux Kernel Log Monitoring with Wazuh: From Zero to Hero
Introduction: Why Kernel Logs Matter
Linux kernel logs are the heartbeat of your system’s security posture. They reveal:
- 🔍 Hardware failures and driver issues
- 🛡️ Security violations and exploit attempts
- 📊 System performance degradation
- 🚨 Memory corruption and segmentation faults
- 🔐 Unauthorized kernel module loading
Today, we’ll build a comprehensive kernel log monitoring system using Wazuh that catches everything from rootkit installations to memory exploits.
Architecture Overview
flowchart TB
subgraph "Linux Kernel Space"
K1[Kernel Ring Buffer]
K2[printk Messages]
K3[Security Events]
K4[Driver Messages]
K5[System Calls]
end
subgraph "User Space Logging"
U1[/dev/kmsg]
U2[klogd/rsyslog]
U3[systemd-journald]
U4[/var/log/kern.log]
U5[dmesg Buffer]
end
subgraph "Wazuh Agent"
W1[Log Collector]
W2[journald Module]
W3[syslog Module]
W4[Command Module]
W5[Agent Buffer]
end
subgraph "Wazuh Manager"
M1[Log Analysis]
M2[Decoders]
M3[Rules Engine]
M4[Alert Generation]
M5[Integration]
end
K1 --> U1
K2 --> U1
K3 --> U1
K4 --> U1
K5 --> U1
U1 --> U2
U1 --> U3
U2 --> U4
U1 --> U5
U3 --> W2
U4 --> W3
U5 --> W4
W2 --> W1
W3 --> W1
W4 --> W1
W1 --> W5
W5 --> M1
M1 --> M2
M2 --> M3
M3 --> M4
M4 --> M5
style K1 fill:#ff6b6b,stroke:#c92a2a
style K3 fill:#ff6b6b,stroke:#c92a2a
style W1 fill:#4dabf7,stroke:#1864ab
style M3 fill:#51cf66,stroke:#2b8a3e
style M4 fill:#ffd43b,stroke:#fab005
Part 1: Modern Approach - Journald Integration
Understanding Journald for Kernel Logs
Modern Linux distributions use systemd-journald to collect all system logs, including kernel messages. This provides structured logging with metadata.
Basic Journald Configuration
Edit /var/ossec/etc/ossec.conf:
<ossec_config> <!-- Basic kernel log collection via journald --> <localfile> <location>journald</location> <log_format>journald</log_format> </localfile></ossec_config>Advanced Journald Filtering
For production environments, filter kernel logs to reduce noise:
<ossec_config> <!-- Only kernel transport messages --> <localfile> <location>journald</location> <log_format>journald</log_format> <filter field="_TRANSPORT">kernel</filter> </localfile>
<!-- High-priority kernel messages only --> <localfile> <location>journald</location> <log_format>journald</log_format> <query>_TRANSPORT=kernel AND PRIORITY<=3</query> <target>critical-kernel</target> </localfile>
<!-- Security-related kernel events --> <localfile> <location>journald</location> <log_format>journald</log_format> <query>_TRANSPORT=kernel AND (MESSAGE~".*SELinux.*" OR MESSAGE~".*audit.*" OR MESSAGE~".*security.*")</query> <target>kernel-security</target> </localfile></ossec_config>Manual Testing of Journald Filters
Before applying configurations, test your filters:
# View all kernel messagesjournalctl _TRANSPORT=kernel
# Test priority filterjournalctl _TRANSPORT=kernel PRIORITY=0..3
# Security-related kernel eventsjournalctl _TRANSPORT=kernel | grep -E "(SELinux|audit|security)"
# Real-time kernel log monitoringjournalctl -f _TRANSPORT=kernel
# Last 100 kernel messages with timestampsjournalctl -k -n 100 --no-pagerPart 2: Traditional Syslog Approach
Classic Kernel Log Files
For systems using traditional syslog:
<ossec_config> <!-- Ubuntu/Debian kernel logs --> <localfile> <log_format>syslog</log_format> <location>/var/log/kern.log</location> </localfile>
<!-- RHEL/CentOS system messages --> <localfile> <log_format>syslog</log_format> <location>/var/log/messages</location> </localfile>
<!-- Generic syslog --> <localfile> <log_format>syslog</log_format> <location>/var/log/syslog</location> </localfile></ossec_config>Multi-file Monitoring
Monitor multiple log locations for comprehensive coverage:
<ossec_config> <!-- Wildcard pattern for all system logs --> <localfile> <location>/var/log/*.log</location> <log_format>syslog</log_format> </localfile>
<!-- Rotated kernel logs --> <localfile> <location>/var/log/kern.log*</location> <log_format>syslog</log_format> <exclude>/var/log/kern.log*.gz</exclude> </localfile></ossec_config>Part 3: Advanced Kernel Monitoring Techniques
Direct Kernel Ring Buffer Access
<ossec_config> <!-- Real-time dmesg monitoring --> <localfile> <log_format>command</log_format> <command>dmesg -T --follow --level=err,crit,alert,emerg</command> <alias>kernel-errors</alias> </localfile>
<!-- Periodic full kernel buffer snapshot --> <localfile> <log_format>command</log_format> <command>dmesg -T | tail -100</command> <frequency>300</frequency> <alias>kernel-snapshot</alias> </localfile></ossec_config>Kernel Module Monitoring
Track kernel module loading/unloading:
<ossec_config> <!-- Monitor loaded modules --> <localfile> <log_format>command</log_format> <command>lsmod | md5sum</command> <frequency>600</frequency> <alias>loaded-modules-hash</alias> </localfile>
<!-- Detailed module info --> <localfile> <log_format>full_command</log_format> <command>for mod in $(lsmod | awk '{print $1}' | tail -n +2); do modinfo $mod 2>/dev/null | grep -E "^(filename|description|author|license):" | sed "s/^/$mod: /"; done</command> <frequency>3600</frequency> <alias>module-details</alias> </localfile></ossec_config>Security-Focused Kernel Monitoring
<ossec_config> <!-- OOM killer events --> <localfile> <log_format>command</log_format> <command>dmesg | grep -i "killed process" | tail -10</command> <frequency>60</frequency> <alias>oom-killer</alias> </localfile>
<!-- Segmentation faults --> <localfile> <log_format>command</log_format> <command>dmesg | grep -i segfault | tail -10</command> <frequency>60</frequency> <alias>segfaults</alias> </localfile>
<!-- USB device connections --> <localfile> <log_format>command</log_format> <command>dmesg | grep -E "USB.*: (new|Product|Manufacturer)" | tail -20</command> <frequency>30</frequency> <alias>usb-devices</alias> </localfile></ossec_config>Part 4: Custom Rules for Kernel Events
Creating Kernel-Specific Rules
Add to /var/ossec/etc/rules/local_rules.xml:
<group name="kernel,linux,"> <!-- Kernel module loading --> <rule id="110001" level="7"> <decoded_as>syslog</decoded_as> <match>kernel: module</match> <regex>loaded|inserted</regex> <description>Kernel module loaded: $(log)</description> <group>kernel_modules,</group> </rule>
<!-- Critical: Unknown module --> <rule id="110002" level="10"> <if_sid>110001</if_sid> <regex>TAINT</regex> <description>Tainted kernel module loaded - possible rootkit</description> <group>kernel_modules,rootkit,</group> </rule>
<!-- Memory corruption --> <rule id="110003" level="12"> <decoded_as>syslog</decoded_as> <match>kernel:</match> <regex>segfault|general protection fault</regex> <description>Kernel detected memory corruption: $(log)</description> <group>kernel_security,exploit,</group> </rule>
<!-- OOM Killer --> <rule id="110004" level="9"> <decoded_as>syslog</decoded_as> <match>kernel: Out of memory: Kill process</match> <description>Out of Memory: Process killed by kernel</description> <group>kernel_resource,system_error,</group> </rule>
<!-- USB device detection --> <rule id="110005" level="5"> <decoded_as>syslog</decoded_as> <match>kernel: usb</match> <regex>new USB device found</regex> <description>New USB device connected</description> <group>kernel_hardware,</group> </rule>
<!-- Suspicious USB --> <rule id="110006" level="10"> <if_sid>110005</if_sid> <regex>BadUSB|Rubber Ducky|WHID</regex> <description>Suspicious USB device detected</description> <group>kernel_hardware,attack,</group> </rule>
<!-- SELinux violations --> <rule id="110007" level="8"> <decoded_as>syslog</decoded_as> <match>kernel: audit</match> <regex>denied|violation</regex> <description>SELinux security violation</description> <group>kernel_security,access_denied,</group> </rule>
<!-- Kernel panic indicators --> <rule id="110008" level="12"> <decoded_as>syslog</decoded_as> <match>kernel:</match> <regex>panic|Oops|BUG:|Unable to handle kernel</regex> <description>Kernel panic or critical error detected</description> <group>kernel_error,system_error,</group> </rule></group>Advanced Correlation Rules
<group name="kernel_correlation,"> <!-- Multiple module loads in short time --> <rule id="110020" level="12" frequency="5" timeframe="60"> <if_matched_sid>110001</if_matched_sid> <same_field>agent.id</same_field> <description>Multiple kernel modules loaded rapidly - possible rootkit installation</description> <group>kernel_modules,rootkit,</group> </rule>
<!-- Repeated segfaults --> <rule id="110021" level="14" frequency="3" timeframe="300"> <if_matched_sid>110003</if_matched_sid> <same_field>agent.id</same_field> <description>Multiple memory corruption events - active exploitation attempt</description> <group>kernel_security,active_attack,</group> </rule></group>Part 5: Performance Optimization
Agent Buffer Configuration
Optimize for high-volume kernel logs:
<ossec_config> <client_buffer> <disabled>no</disabled> <queue_size>20000</queue_size> <events_per_second>2000</events_per_second> </client_buffer>
<!-- Specific buffer for kernel logs --> <localfile> <location>journald</location> <log_format>journald</log_format> <filter field="_TRANSPORT">kernel</filter> <out_format>json</out_format> <target>kernel</target> <reconnect_time>10</reconnect_time> </localfile></ossec_config>Rate Limiting and Filtering
<ossec_config> <!-- Priority-based filtering --> <localfile> <location>journald</location> <log_format>journald</log_format> <query>_TRANSPORT=kernel AND (PRIORITY=0 OR PRIORITY=1 OR PRIORITY=2)</query> <target>kernel-critical</target> <only-future-events>yes</only-future-events> </localfile>
<!-- Exclude noisy drivers --> <localfile> <location>/var/log/kern.log</location> <log_format>syslog</log_format> <exclude>nvidia|nouveau|iwlwifi</exclude> </localfile></ossec_config>Part 6: Troubleshooting Guide
Common Issues and Solutions
Issue 1: No Kernel Logs Received
Diagnosis:
# Check if wazuh user can access logssudo -u wazuh journalctl --since "1 minute ago" --no-pager
# Verify permissionsls -la /var/log/kern.loggroups wazuhSolution:
# Add wazuh to systemd-journal groupsudo usermod -a -G systemd-journal wazuhsudo usermod -a -G adm wazuh
# Restart agentsudo systemctl restart wazuh-agentIssue 2: High CPU Usage
Diagnosis:
# Check agent resource usagetop -p $(pgrep -f wazuh-agent)
# Review log collection ratesudo /var/ossec/bin/agent_control -i $(hostname) -sSolution:
<!-- Implement rate limiting --><localfile> <location>journald</location> <log_format>journald</log_format> <filter field="_TRANSPORT">kernel</filter> <frequency>10</frequency> <max-log-size>1MB</max-log-size></localfile>Issue 3: Missing Critical Events
Debug Process:
# Test log collectionecho "Test kernel message" | sudo tee /dev/kmsg
# Check if receivedsudo tail -f /var/ossec/logs/archives/archives.log | grep "Test kernel"
# Verify decoderecho 'Jan 6 10:00:00 hostname kernel: [12345.678] Test message' | sudo /var/ossec/bin/ossec-logtestPart 7: Real-World Security Scenarios
Scenario 1: Rootkit Detection
# Simulate suspicious module loadsudo insmod /path/to/suspicious.ko
# Expected alertRule: 110002 (level 10) -> 'Tainted kernel module loaded - possible rootkit'Scenario 2: Memory Exploitation
# Generate segfault./vulnerable_program
# Expected alertRule: 110003 (level 12) -> 'Kernel detected memory corruption'Scenario 3: Resource Exhaustion
# Trigger OOM killerstress-ng --vm 1 --vm-bytes 100G --timeout 10s
# Expected alertRule: 110004 (level 9) -> 'Out of Memory: Process killed by kernel'Part 8: Integration with SIEM Dashboard
Creating Kernel Security Dashboard
Key Visualizations
-
Kernel Events Timeline
Query: rule.groups: kernelVisualization: Line chartX-axis: @timestampY-axis: Count -
Top Kernel Security Events
Query: rule.groups: kernel AND rule.level >= 7Visualization: Data tableMetrics: CountBuckets: rule.description -
Module Loading Activity
Query: rule.id: 110001Visualization: Bar chartSplit series: agent.name
Alert Queries
# Critical kernel security eventsrule.groups: kernel AND rule.level >= 10
# Memory corruption attemptsrule.id: 110003 OR rule.id: 110021
# Suspicious USB devicesrule.id: 110006
# Kernel module changesrule.groups: kernel_modules
# System stability issuesrule.groups: kernel_error OR rule.groups: system_errorPart 9: Automation and Response
Active Response Configuration
<ossec_config> <active-response> <command>disable-usb</command> <location>local</location> <rules_id>110006</rules_id> <timeout>0</timeout> </active-response>
<active-response> <command>snapshot-memory</command> <location>local</location> <rules_id>110003</rules_id> <timeout>0</timeout> </active-response></ossec_config>Custom Response Scripts
Create /var/ossec/active-response/bin/disable-usb.sh:
#!/bin/bash# Disable USB storage when suspicious device detected
ACTION=$1USER=$2IP=$3ALERTID=$4RULEID=$5
if [ "$ACTION" = "add" ]; then # Disable USB storage echo 'install usb-storage /bin/true' > /etc/modprobe.d/disable-usb-storage.conf
# Log action logger -t wazuh-usb "USB storage disabled due to alert $ALERTID"
# Remove existing USB storage module rmmod usb_storage 2>/dev/nullfi
exit 0Part 10: Best Practices
1. Storage Management
# Implement log rotationcat > /etc/logrotate.d/wazuh-kernel << EOF/var/ossec/logs/archives/kernel-*.log { daily rotate 30 compress delaycompress missingok notifempty create 0640 wazuh wazuh}EOF2. Regular Maintenance
#!/bin/bash# Weekly kernel log analysis
# Check for unusual module activityecho "=== Kernel Module Analysis ==="lsmod | awk '{print $1}' | sort | comm -13 /etc/wazuh/baseline/modules.txt -
# Review high-severity kernel eventsecho "=== High Severity Events (Last 7 days) ==="grep -E "level\":(10|11|12|13|14|15)" /var/ossec/logs/alerts/alerts.json | \ jq -r 'select(.rule.groups[]? | contains("kernel"))'
# Performance metricsecho "=== Kernel Log Volume ==="journalctl --since "7 days ago" _TRANSPORT=kernel | wc -l3. Documentation
Maintain a runbook for kernel security events:
## Kernel Security Event Response Playbook
### Event: Tainted Module Detected (Rule 110002)1. Isolate affected system2. Capture module information: `modinfo <module_name>`3. Check module signature: `modprobe --dump-modversions <module>`4. Review system logs for related activity5. If confirmed malicious, remove and block
### Event: Memory Corruption (Rule 110003)1. Identify affected process2. Collect memory dump if possible3. Review application logs4. Check for known exploits5. Apply patches or mitigationsConclusion
Kernel log monitoring with Wazuh provides deep visibility into system security and stability. By implementing the configurations in this guide, you’ll be able to:
- 🔍 Detect kernel-level attacks and rootkits
- 🛡️ Identify memory corruption and exploitation attempts
- 📊 Monitor system resource issues
- 🚨 Track hardware changes and USB devices
- 🔐 Enforce security policies at the kernel level
Remember: The kernel is the last line of defense. Monitor it well, and you’ll catch attacks that bypass user-space security.
Additional Resources
Building robust security monitoring, one kernel message at a time. Stay vigilant! 🛡️