This document provides instructions for manually configuring Linux systems to forward audit logs to IBM QRadar SIEM. These instructions are an alternative to using the provided installer scripts and have been verified against official documentation for rsyslog, auditd, and SELinux.
- Rsyslog Version: Some parameters like
forceSingleInstancerequire rsyslog v8.38.0 or later - RHEL 8+ Changes: audispd functionality is integrated into auditd with path changes
- Rocky Linux: Minimal installations do NOT include rsyslog by default - manual installation required
The goal of this setup is to configure auditd to collect system audit events, rsyslog to forward these events to QRadar using TCP (recommended over UDP), and a Python script to parse and format the logs for better readability and analysis in QRadar.
This guide is divided into two main sections:
- Debian/Ubuntu Setup
- RHEL/CentOS/Rocky/AlmaLinux Setup
Please follow the instructions for your specific distribution.
- Root Access: You must have
sudoorrootprivileges to complete these steps. - QRadar Server: You must have a QRadar server with a configured log source to receive the forwarded logs.
- Network Connectivity: The system you are configuring must be able to reach the QRadar server on the specified IP address and port.
- Rsyslog Version Check: Run
rsyslogd -vto check your version (some features require v8.38.0+)
These instructions apply to Debian 9+ and Ubuntu 18.04+.
First, update your package list and install the necessary packages:
sudo apt-get update
sudo apt-get install -y auditd audispd-plugins rsyslog python3Create a new audit rules file for QRadar:
sudo nano /etc/audit/rules.d/99-qradar.rulesCopy and paste the following rules into the file:
# QRadar Audit Rules
-D
-b 16384
-f 1
-r 150
-i
-w /etc/passwd -p wa -k identity_changes
-w /etc/shadow -p wa -k credential_access
-w /etc/group -p wa -k identity_changes
-w /etc/gshadow -p wa -k credential_access
-w /etc/sudoers -p wa -k privilege_escalation
-w /etc/sudoers.d/ -p wa -k privilege_escalation
-w /etc/pam.d/ -p wa -k authentication_config
-w /etc/security/ -p wa -k security_config
-w /etc/login.defs -p wa -k login_config
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /etc/ssh/ssh_config -p wa -k ssh_config
-w /root/.ssh/ -p wa -k ssh_keys
-w /home/*/.ssh/ -p wa -k ssh_keys
-a always,exit -F arch=b64 -S execve -k root_commands
-a always,exit -F arch=b32 -S execve -k root_commands
-w /bin/su -p x -k privilege_escalation
-w /usr/bin/sudo -p x -k privilege_escalation
-w /usr/bin/pkexec -p x -k privilege_escalation
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network_config
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k network_config
-w /etc/hosts -p wa -k network_config
-w /etc/resolv.conf -p wa -k network_config
-w /etc/hostname -p wa -k network_config
-w /etc/network/interfaces -p wa -k network_config
-w /etc/netplan/ -p wa -k network_config
-w /etc/NetworkManager/ -p wa -k network_config
-w /sbin/shutdown -p x -k system_shutdown
-w /sbin/poweroff -p x -k system_shutdown
-w /sbin/reboot -p x -k system_shutdown
-w /sbin/halt -p x -k system_shutdown
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k file_permissions
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k file_permissions
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k file_ownership
-a always,exit -F arch=b32 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k file_ownership
-w /usr/bin/wget -p x -k network_tools
-w /usr/bin/curl -p x -k network_tools
-w /bin/nc -p x -k network_tools
-w /usr/bin/ncat -p x -k network_tools
-w /usr/bin/netcat -p x -k network_tools
-w /usr/bin/ssh -p x -k remote_access
-w /usr/bin/scp -p x -k remote_access
-w /usr/bin/sftp -p x -k remote_access
-w /usr/bin/rsync -p x -k remote_access
-w /usr/bin/whoami -p x -k system_discovery
-w /usr/bin/id -p x -k system_discovery
-w /usr/bin/w -p x -k system_discovery
-w /usr/bin/who -p x -k system_discovery
-w /etc/cron.d/ -p wa -k scheduled_tasks
-w /etc/cron.daily/ -p wa -k scheduled_tasks
-w /etc/cron.hourly/ -p wa -k scheduled_tasks
-w /etc/cron.monthly/ -p wa -k scheduled_tasks
-w /etc/cron.weekly/ -p wa -k scheduled_tasks
-w /var/spool/cron/ -p wa -k scheduled_tasks
-w /etc/crontab -p wa -k scheduled_tasks
-w /etc/systemd/system/ -p wa -k systemd_services
-w /lib/systemd/system/ -p wa -k systemd_services
-w /usr/lib/systemd/system/ -p wa -k systemd_services
-a always,exit -F arch=b64 -S init_module,delete_module -k kernel_modules
-a always,exit -F arch=b32 -S init_module,delete_module -k kernel_modules
-w /sbin/insmod -p x -k kernel_modules
-w /sbin/rmmod -p x -k kernel_modules
-w /sbin/modprobe -p x -k kernel_modules
-w /var/log/auth.log -p wa -k log_modification
-w /var/log/syslog -p wa -k log_modification
-w /var/log/audit/ -p wa -k audit_log_modification
-w /etc/audit/ -p wa -k audit_config
-w /sbin/auditctl -p x -k audit_tools
-w /sbin/auditd -p x -k audit_tools
Edit the syslog.conf file to enable forwarding of audit events to syslog:
# For Ubuntu 20.04+ and Debian 10+
sudo nano /etc/audit/plugins.d/syslog.conf
# For older versions
sudo nano /etc/audisp/plugins.d/syslog.confEnsure the file contains the following:
active = yes
direction = out
path = builtin_syslog
type = builtin
args = LOG_LOCAL3
format = string
Create the Python script to parse and format the EXECVE logs:
sudo nano /usr/local/bin/qradar_execve_parser.pyCopy and paste the following code into the file:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
QRadar EXECVE Log Parser for rsyslog omprog module
IMPORTANT: Uses readline() to avoid buffering issues with rsyslog
"""
import sys
import re
import signal
class ExecveParser:
def __init__(self):
signal.signal(signal.SIGTERM, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# Compile regex patterns for better performance
self.args_pattern = re.compile(r'a(\d+)="([^"]*)"')
self.cleanup_patterns = [
re.compile(r'a\d+="[^"]*"\s*'),
re.compile(r'argc=\d+\s*')
]
def _signal_handler(self, signum, frame):
sys.exit(0)
def process_execve_line(self, line):
if "type=EXECVE" not in line:
return line
if "proctitle=" in line or "PROCTITLE" in line:
return None
try:
args_matches = self.args_pattern.findall(line)
if not args_matches:
return line
args_dict = {int(index): value for index, value in args_matches}
sorted_args = sorted(args_dict.items())
combined_command = " ".join(arg[1] for arg in sorted_args)
# Clean up the original line
cleaned_line = line
for pattern in self.cleanup_patterns:
cleaned_line = pattern.sub('', cleaned_line)
cleaned_line = cleaned_line.strip()
processed_line = f"{cleaned_line} cmd=\"{combined_command}\""
return processed_line
except Exception:
return line
def run(self):
"""
Main processing loop using readline() to avoid buffering issues
CRITICAL: Do NOT use 'for line in sys.stdin' with rsyslog omprog
"""
try:
while True:
line = sys.stdin.readline()
if not line: # EOF
break
line = line.strip()
if line:
processed_line = self.process_execve_line(line)
if processed_line is not None:
print(processed_line)
sys.stdout.flush() # Critical for omprog communication
except (KeyboardInterrupt, BrokenPipeError):
pass
except Exception:
sys.exit(1)
if __name__ == "__main__":
parser = ExecveParser()
parser.run()Make the script executable:
sudo chmod +x /usr/local/bin/qradar_execve_parser.pyCreate a new rsyslog configuration file for QRadar:
sudo nano /etc/rsyslog.d/99-qradar.confCopy and paste the following configuration into the file, replacing <QRADAR_IP> and <QRADAR_PORT> with your QRadar server's IP address and port:
# QRadar Log Forwarding Configuration
# Load required modules
module(load="omprog")
# QRadar-compatible template (RFC 3339 time stamp)
template(name="QRadarFormat" type="string"
string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %app-name%: %msg%\n")
# Only process messages from facility local3
if $syslogfacility-text == 'local3' then {
# Process EXECVE events with parser
if $msg contains 'type=EXECVE' then {
action(
type="omprog"
binary="/usr/local/bin/qradar_execve_parser.py"
template="RSYSLOG_TraditionalFileFormat"
# Note: forceSingleInstance requires rsyslog v8.38.0+
# Uncomment if your version supports it:
# forceSingleInstance="on"
queue.workerThreads="1"
)
}
# Forward all audit logs to QRadar using TCP (recommended)
action(
type="omfwd"
target="<QRADAR_IP>"
port="<QRADAR_PORT>"
protocol="tcp" # Use TCP for reliable delivery
template="QRadarFormat"
# Reliable async queue with production-ready settings
queue.type="linkedlist"
queue.size="50000"
queue.maxdiskspace="2g"
queue.saveOnShutdown="on"
queue.highWatermark="40000"
queue.lowWatermark="10000"
queue.discardMark="45000"
queue.discardSeverity="4"
action.resumeRetryCount="-1" # Infinite retries for reliability
action.resumeInterval="30"
)
stop # Prevent further rule processing
}
Restart the auditd and rsyslog services to apply the changes:
sudo systemctl restart auditd
sudo systemctl restart rsyslogVerify the configuration and test log forwarding:
# Check rsyslog version
rsyslogd -v
# Check rsyslog configuration syntax
sudo rsyslogd -N1
# Test the parser script
echo 'type=EXECVE msg=audit(123:456): argc=3 a0="ls" a1="-la" a2="/tmp"' | sudo /usr/local/bin/qradar_execve_parser.py
# Send test logs
logger -p local3.info "Test QRadar forwarding"
logger -p local3.info 'type=EXECVE msg=audit(1234:567): argc=3 a0="test" a1="-la" a2="/tmp"'
# Monitor traffic to QRadar (should show TCP connection)
sudo tcpdump -i any host <QRADAR_IP> and port <QRADAR_PORT> -A -nThese instructions apply to RHEL 7+, CentOS 7+, Rocky Linux, AlmaLinux, and other RHEL-based distributions.
First, install the necessary packages using yum or dnf:
# For RHEL 7/CentOS 7
sudo yum install -y audit audispd-plugins rsyslog python3
# For RHEL 8+ and derivatives (Rocky Linux, AlmaLinux)
sudo dnf install -y audit rsyslog python3
# Note: Rocky Linux minimal installation requires rsyslog installation
# Verify rsyslog is installed:
rpm -q rsyslog || sudo dnf install -y rsyslogCreate a new audit rules file for QRadar:
sudo nano /etc/audit/rules.d/99-qradar.rulesCopy and paste the following rules into the file:
# QRadar Audit Rules
-D
-b 16384
-f 1
-r 150
-i
-w /etc/passwd -p wa -k identity_changes
-w /etc/shadow -p wa -k credential_access
-w /etc/group -p wa -k identity_changes
-w /etc/gshadow -p wa -k credential_access
-w /etc/sudoers -p wa -k privilege_escalation
-w /etc/sudoers.d/ -p wa -k privilege_escalation
-w /etc/pam.d/ -p wa -k authentication_config
-w /etc/security/ -p wa -k security_config
-w /etc/login.defs -p wa -k login_config
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /etc/ssh/ssh_config -p wa -k ssh_config
-w /root/.ssh/ -p wa -k ssh_keys
-w /home/*/.ssh/ -p wa -k ssh_keys
-a always,exit -F arch=b64 -S execve -k root_commands
-a always,exit -F arch=b32 -S execve -k root_commands
-w /bin/su -p x -k privilege_escalation
-w /usr/bin/sudo -p x -k privilege_escalation
-w /usr/bin/pkexec -p x -k privilege_escalation
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network_config
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k network_config
-w /etc/hosts -p wa -k network_config
-w /etc/resolv.conf -p wa -k network_config
-w /etc/hostname -p wa -k network_config
-w /etc/sysconfig/network -p wa -k network_config
-w /etc/sysconfig/network-scripts/ -p wa -k network_config
-w /etc/NetworkManager/ -p wa -k network_config
-w /sbin/shutdown -p x -k system_shutdown
-w /sbin/poweroff -p x -k system_shutdown
-w /sbin/reboot -p x -k system_shutdown
-w /sbin/halt -p x -k system_shutdown
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k file_permissions
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k file_permissions
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k file_ownership
-a always,exit -F arch=b32 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k file_ownership
-w /usr/bin/wget -p x -k network_tools
-w /usr/bin/curl -p x -k network_tools
-w /bin/nc -p x -k network_tools
-w /usr/bin/ncat -p x -k network_tools
-w /usr/bin/netcat -p x -k network_tools
-w /usr/bin/ssh -p x -k remote_access
-w /usr/bin/scp -p x -k remote_access
-w /usr/bin/sftp -p x -k remote_access
-w /usr/bin/rsync -p x -k remote_access
-w /usr/bin/whoami -p x -k system_discovery
-w /usr/bin/id -p x -k system_discovery
-w /usr/bin/w -p x -k system_discovery
-w /usr/bin/who -p x -k system_discovery
-w /etc/cron.d/ -p wa -k scheduled_tasks
-w /etc/cron.daily/ -p wa -k scheduled_tasks
-w /etc/cron.hourly/ -p wa -k scheduled_tasks
-w /etc/cron.monthly/ -p wa -k scheduled_tasks
-w /etc/cron.weekly/ -p wa -k scheduled_tasks
-w /var/spool/cron/ -p wa -k scheduled_tasks
-w /etc/crontab -p wa -k scheduled_tasks
-w /etc/systemd/system/ -p wa -k systemd_services
-w /lib/systemd/system/ -p wa -k systemd_services
-w /usr/lib/systemd/system/ -p wa -k systemd_services
-a always,exit -F arch=b64 -S init_module,delete_module -k kernel_modules
-a always,exit -F arch=b32 -S init_module,delete_module -k kernel_modules
-w /sbin/insmod -p x -k kernel_modules
-w /sbin/rmmod -p x -k kernel_modules
-w /sbin/modprobe -p x -k kernel_modules
-w /var/log/messages -p wa -k log_modification
-w /var/log/secure -p wa -k log_modification
-w /var/log/audit/ -p wa -k audit_log_modification
-w /etc/audit/ -p wa -k audit_config
-w /sbin/auditctl -p x -k audit_tools
-w /sbin/auditd -p x -k audit_tools
Important: The path differs based on RHEL version:
# For RHEL 7/CentOS 7
sudo nano /etc/audisp/plugins.d/syslog.conf
# For RHEL 8+ (including Rocky Linux, AlmaLinux)
# Note: audispd is integrated into auditd in RHEL 8+
sudo nano /etc/audit/plugins.d/syslog.confEnsure the file contains the following:
active = yes
direction = out
path = builtin_syslog
type = builtin
args = LOG_LOCAL3
format = string
Create the Python script to parse and format the EXECVE logs:
sudo nano /usr/local/bin/qradar_execve_parser.pyCopy and paste the following code into the file:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
QRadar EXECVE Log Parser for rsyslog omprog module
IMPORTANT: Uses readline() to avoid buffering issues with rsyslog
"""
import sys
import re
import signal
class ExecveParser:
def __init__(self):
signal.signal(signal.SIGTERM, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# Compile regex patterns for better performance
self.args_pattern = re.compile(r'a(\d+)="([^"]*)"')
self.cleanup_patterns = [
re.compile(r'a\d+="[^"]*"\s*'),
re.compile(r'argc=\d+\s*')
]
def _signal_handler(self, signum, frame):
sys.exit(0)
def process_execve_line(self, line):
if "type=EXECVE" not in line:
return line
if "proctitle=" in line or "PROCTITLE" in line:
return None
try:
args_matches = self.args_pattern.findall(line)
if not args_matches:
return line
args_dict = {int(index): value for index, value in args_matches}
sorted_args = sorted(args_dict.items())
combined_command = " ".join(arg[1] for arg in sorted_args)
# Clean up the original line
cleaned_line = line
for pattern in self.cleanup_patterns:
cleaned_line = pattern.sub('', cleaned_line)
cleaned_line = cleaned_line.strip()
processed_line = f"{cleaned_line} cmd=\"{combined_command}\""
return processed_line
except Exception:
return line
def run(self):
"""
Main processing loop using readline() to avoid buffering issues
CRITICAL: Do NOT use 'for line in sys.stdin' with rsyslog omprog
"""
try:
while True:
line = sys.stdin.readline()
if not line: # EOF
break
line = line.strip()
if line:
processed_line = self.process_execve_line(line)
if processed_line is not None:
print(processed_line)
sys.stdout.flush() # Critical for omprog communication
except (KeyboardInterrupt, BrokenPipeError):
pass
except Exception:
sys.exit(1)
if __name__ == "__main__":
parser = ExecveParser()
parser.run()Make the script executable:
sudo chmod +x /usr/local/bin/qradar_execve_parser.pyIf SELinux is enabled on your system, configure the necessary permissions:
# Check SELinux status
getenforce
# If SELinux is enabled, proceed with the following:
# Set proper context for the Python script
sudo semanage fcontext -a -t bin_t "/usr/local/bin/qradar_execve_parser.py"
sudo restorecon -v /usr/local/bin/qradar_execve_parser.py
# IMPORTANT: rsyslog_can_network_connect boolean does NOT exist
# Instead, ensure rsyslog can connect to syslog ports
sudo semanage port -l | grep syslog
# If your QRadar port is not in the syslog_port_t list, add it:
# sudo semanage port -a -t syslogd_port_t -p tcp <QRADAR_PORT>
# Allow rsyslog to execute external programs (if needed)
# Check for denials first
sudo ausearch -c 'rsyslogd' --raw | audit2allow -M my-rsyslogd
# Review the generated policy before applying
sudo cat my-rsyslogd.te
# Apply only if necessary
sudo semodule -i my-rsyslogd.pp
# Alternative: If you encounter issues, you can temporarily set permissive mode for rsyslog
# sudo semanage permissive -a rsyslogd_t
# Note: This is less secure and should only be used for troubleshootingIf FirewallD is enabled, configure it to allow outbound traffic to QRadar:
# Check if firewalld is running
sudo systemctl status firewalld
# Most environments allow outbound traffic by default
# If you need to explicitly allow it:
sudo firewall-cmd --permanent --add-port=<QRADAR_PORT>/tcp
sudo firewall-cmd --reload
# Verify the rule
sudo firewall-cmd --list-allCreate a new rsyslog configuration file for QRadar:
sudo nano /etc/rsyslog.d/99-qradar.confCopy and paste the following configuration into the file, replacing <QRADAR_IP> and <QRADAR_PORT> with your QRadar server's IP address and port:
# QRadar Log Forwarding Configuration
# Load required modules
module(load="omprog")
# QRadar-compatible template (RFC 3339 time stamp)
template(name="QRadarFormat" type="string"
string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %app-name%: %msg%\n")
# Only process messages from facility local3
if $syslogfacility-text == 'local3' then {
# Process EXECVE events with parser
if $msg contains 'type=EXECVE' then {
action(
type="omprog"
binary="/usr/local/bin/qradar_execve_parser.py"
template="RSYSLOG_TraditionalFileFormat"
# Note: forceSingleInstance requires rsyslog v8.38.0+
# Uncomment if your version supports it:
# forceSingleInstance="on"
queue.workerThreads="1"
)
}
# Forward all audit logs to QRadar using TCP (recommended)
action(
type="omfwd"
target="<QRADAR_IP>"
port="<QRADAR_PORT>"
protocol="tcp" # Use TCP for reliable delivery
template="QRadarFormat"
# Reliable async queue with production-ready settings
queue.type="linkedlist"
queue.size="50000"
queue.maxdiskspace="2g"
queue.saveOnShutdown="on"
queue.highWatermark="40000"
queue.lowWatermark="10000"
queue.discardMark="45000"
queue.discardSeverity="4"
action.resumeRetryCount="-1" # Infinite retries for reliability
action.resumeInterval="30"
)
stop # Prevent further rule processing
}
Restart the auditd and rsyslog services to apply the changes:
sudo systemctl restart auditd
sudo systemctl restart rsyslogVerify the configuration and test log forwarding:
# Check rsyslog version
rsyslogd -v
# Check rsyslog configuration syntax
sudo rsyslogd -N1
# Test the parser script
echo 'type=EXECVE msg=audit(123:456): argc=3 a0="ls" a1="-la" a2="/tmp"' | sudo /usr/local/bin/qradar_execve_parser.py
# Send test logs
logger -p local3.info "Test QRadar forwarding"
logger -p local3.info 'type=EXECVE msg=audit(1234:567): argc=3 a0="test" a1="-la" a2="/tmp"'
# Monitor traffic to QRadar (should show TCP connection)
sudo tcpdump -i any host <QRADAR_IP> and port <QRADAR_PORT> -A -n
# Check for SELinux denials
sudo ausearch -m avc -ts recent# Check auditd status
sudo systemctl status auditd
# Check rsyslog status
sudo systemctl status rsyslog
# View rsyslog errors
sudo journalctl -u rsyslog -f
# Check audit daemon logs
sudo ausearch -m daemon_start -ts recent# Run rsyslog in debug mode
sudo rsyslogd -dn 2>&1 | grep -i "qradar\|omprog\|omfwd\|local3"
# Check rsyslog statistics
sudo pkill -USR1 rsyslogd && sudo tail -f /var/log/messages | grep rsyslogd-pstats
# Verify rsyslog is receiving audit logs
sudo tail -f /var/log/messages | grep local3-
SELinux Denials:
- Check
/var/log/audit/audit.logfor denials - Use
audit2allowto create custom policies only if needed - Remember:
rsyslog_can_network_connectboolean does NOT exist
- Check
-
Network Connectivity:
- Ensure TCP connectivity to QRadar:
telnet <QRADAR_IP> <QRADAR_PORT> - Check for firewall blocks:
sudo iptables -L -n | grep <QRADAR_PORT>
- Ensure TCP connectivity to QRadar:
-
Parser Errors:
- Test the parser script manually with sample EXECVE logs
- Ensure Python script uses
readline()notfor line in sys.stdin - Check script has executable permissions
-
Queue Overflow:
- Monitor queue statistics in rsyslog stats
- Adjust queue sizes based on your log volume
- Consider disk-assisted queues for very high volumes
-
RHEL 8+ audispd Path:
- Remember the path change from
/etc/audisp/to/etc/audit/plugins.d/ - Verify correct path exists before editing
- Remember the path change from
For high-volume environments, consider these optimizations:
# In /etc/audit/rules.d/99-qradar.rules, increase buffer size:
-b 32768 # or higher for very busy systems (max: 65536)# Add to /etc/rsyslog.conf:
global(
maxMessageSize="64k"
workDirectory="/var/spool/rsyslog"
)
# Or legacy format:
$MaxMessageSize 64k
$WorkDirectory /var/spool/rsyslog# Modify the queue configuration in 99-qradar.conf:
queue.type="linkedlist"
queue.filename="qradar_queue" # Enables disk assistance
queue.maxdiskspace="5g"
queue.highwatermark="500000"
queue.lowwatermark="200000"# Create /etc/logrotate.d/qradar-audit:
/var/log/audit/audit.log {
daily
rotate 7
compress
delaycompress
notifempty
create 0600 root root
sharedscripts
postrotate
/usr/bin/pkill -HUP rsyslogd > /dev/null 2>&1 || true
/sbin/service auditd restart > /dev/null 2>&1 || true
endscript
}Always use TCP instead of UDP for QRadar log forwarding:
- TCP ensures reliable delivery with acknowledgments
- UDP can result in log loss during network congestion
- QRadar handles TCP connections efficiently
- Use
protocol="tcp"in the omfwd action
- v8.38.0+: Supports
forceSingleInstanceparameter - v8.30.0+: Improved default queue sizes
- v7.x: May require different module loading syntax
- RHEL 8+: audispd integrated into auditd, different plugin path
- Rocky Linux: Minimal install doesn't include rsyslog
- Ubuntu 20.04+: Uses
/etc/audit/plugins.d/path - Debian 9: Uses older
/etc/audisp/plugins.d/path
- Use TCP with Encryption: Consider TLS for sensitive environments
- Limit Parser Permissions: Run with minimal required privileges
- Monitor Queue Sizes: Prevent DoS through queue exhaustion
- Regular Updates: Keep rsyslog and audit packages updated
- Access Control: Restrict access to audit rules and configuration files
- The Python parser script formats EXECVE logs for better readability in QRadar
- All audit events are forwarded to QRadar, with EXECVE events being pre-processed
- The configuration uses reliable queuing to prevent log loss during network issues
- TCP protocol is strongly recommended over UDP for reliability
- Adjust queue parameters based on your environment's log volume and network reliability
- Test thoroughly in a non-production environment before deploying