====== Centralizing Pandora FMS audit logs with Rsyslog ====== {{indexmenu_n>64}} ===== Introduction ===== This topic describes how to forward a Pandora FMS //log// through **Rsyslog**. In reality, it would work for any server //log//, but here it focuses on Pandora FMS //logs//. Specifically, for this example, the Pandora FMS Web Console audit //log// located at: /var/www/html/pandora_console/log/audit.log From a production server to a dedicated Rsyslog receiver, using ''imfile'' (file queue) on the sender's side and ''imtcp'' with an ''omfile'' template on the receiver's side. This is exactly the result of a real end-to-end execution on Rocky Linux 9 (Rsyslog ''8.2506.0'' on the sender and ''8.2510.0'' on the receiver). For this //log//, the first thing to do is **enable Pandora FMS audit log writing** in the [[:en:documentation:pandorafms:management_and_operation:12_console_setup#ks1_1_2|Web Console]]. //It is disabled by default//, and to enable it, you must follow these steps: - Go to **Management → Settings → System Settings → General Setup → Security** and then enable the **Enable audit log** option. - Save the changes with the **Update** button. ===== Topology ===== In some //log// collection tools, there is already a dedicated collector "listening" via Syslog, making it unnecessary to configure an additional receiver on the opposite side. For this example, the configuration is done from scratch without assuming any pre-configured //log// collection tool. ==== Servers and configuration ==== Both servers are configured with Rocky Linux version 9.7 and a minimal installation. The Web Console server has the Pandora FMS environment installed using the [[:en:documentation:pandorafms:installation:01_installing#ks1_7|installation script]]. ^ Host ^ IP Address ^ Role ^ | ''rsyslog-receiver'' | ''10.0.0.1'' | Rsyslog receiver | | ''pandora-console'' | ''10.0.0.2'' | Rsyslog sender + Pandora FMS Web Console | Transport: ''TCP 10514''. ''514'' is the canonical Syslog port; in this example, ''10514'' is used to show how to change the destination when the default port is not viable. **This choice keeps the procedure reproducible in a clean installation**; changing it to ''514'' for production takes only a single configuration line. ===== Process description ===== The audit //log// is a //plain text// file to which the PHP Console adds lines on every administrative action. The goal is to send each new line to a separate //host// without modifying the Console code. The //pipeline// has three stages: Pandora FMS Console --append--> /var/www/html/pandora_console/log/audit.log | | imfile (polling, 10s) v rsyslog, pandora-console (ruleset RemoteAuditFwd) | | omfwd / TCP 10514 v rsyslog, rsyslog-receiver (ruleset RemoteAudit) | v /var/log/received/pandora-audit.log **Key design decisions**: * ''imfile'' is the right tool to //tail// an application file without relying on the application to write to Syslog. It saves the read position in a //state file//, so Rsyslog restarts do not forward historical data. * **A dedicated ''ruleset'' ''RemoteAuditFwd'' on the sender is mandatory**. If the ''omfwd'' action is declared at the root level of the Rsyslog configuration, it applies to all messages in the main //ruleset// — that is, to **the entire** //journal// (''CROND'', internal ''rsyslogd'' messages, etc.) and "pollutes" the receiver. Linking the ''imfile'' input to its own //ruleset// is the cleanest way to send **only** the audit lines. * **A ''ruleset'', ''RemoteAudit'', on the receiver** with a //string// type //template// used as the output file name (''dynaFile'') produces a single predictable file—for this example, under ''/var/log/received/''—and leaves the receiver's local Syslog intact. * **TCP over UDP**: Audit lines are small but should not be silently discarded; a brief receiver restart will cause Rsyslog to //buffer// and forward them using the ''action.resumeRetryCount=-1'' and ''queue.saveonshutdown=on'' instructions. ===== Receiver: `rsyslog-receiver` ===== ==== Installing Rsyslog ==== In most Rocky Linux installations, Rsyslog is already installed by default. If it is a minimal installation that does not have it, the command to install it is: # --- On rsyslog-receiver (10.0.0.1) --- dnf install -y rsyslog ==== Rsyslog configuration ==== Create ''/etc/rsyslog.d/10-remote-audit.conf'' with the following content: # Receiver: accept audit logs forwarded on TCP port 10514 and # store them in a single file under /var/log/received/. module(load="imtcp") template(name="PandoraAudit" type="string" string="/var/log/received/pandora-audit.log" ) ruleset(name="RemoteAudit") { action(type="omfile" dynaFile="PandoraAudit") } input(type="imtcp" port="10514" ruleset="RemoteAudit") **What each block does**: * ''module(load="imtcp")'' enables the Syslog receiver over TCP. Use ''imudp'' if UDP is preferred; TCP is recommended for audit data. * The //string// type ''template'' ''PandoraAudit'' defines the output file path. * ''ruleset("RemoteAudit")'' links the single writer to that file via ''dynaFile='' (see "Known issues" below to understand why ''template='' does not work here in Rsyslog 8.2510). * ''input(type="imtcp" port="10514" ruleset="RemoteAudit")'' opens the listener and routes incoming messages to the custom //ruleset// instead of the default //ruleset//. ==== Enable and validate ==== # --- On rsyslog-receiver (10.0.0.1) --- mkdir -p /var/log/received systemctl enable --now rsyslog ss -ltn | grep 10514 **Expected**: a ''LISTEN'' line on ''0.0.0.0:10514'' and ''[::]:10514''. In production, the receiving //host// must allow incoming ''TCP 10514'' traffic from the sender in its //firewall// (or in the network //firewall// carrying the audit traffic). ===== Sender: `pandora-console` ===== The Pandora FMS Server already includes Rsyslog (it is installed by default and active in the standard Console image). You only need to add the audit forwarding configuration. ==== Create the forwarding configuration ==== Create ''/etc/rsyslog.d/10-pandora-audit-fwd.conf'': # Sender: tail the Pandora FMS Console audit log and # forward it to the receiver via TCP port 10514. The dedicated ruleset is # required to ensure that ONLY the audit log is sent, not the entire # system journal. module(load="imfile") ruleset(name="RemoteAuditFwd") { action(type="omfwd" target="10.0.0.1" port="10514" protocol="tcp" action.resumeRetryCount="-1" queue.type="linkedList" queue.filename="pandora_audit_fwd" queue.saveonshutdown="on" ) } input(type="imfile" File="/var/www/html/pandora_console/log/audit.log" Tag="pandora-audit" Severity="info" Facility="local0" ruleset="RemoteAuditFwd" ) **Notes on the parameters**: * ''action.resumeRetryCount="-1"'' makes the sender retry indefinitely when the receiver is down; this gives the sender the "//buffer// if the network goes down" behavior. * ''queue.type="linkedList"'' keeps the queue in memory simply. If the audit volume justifies a disk queue, change it to ''queue.type="disk"'' (Warning: ''queue.maxdisksize'' is only valid for //disk// queues). * ''Tag="pandora-audit"'' allows the receiver and //downstream filters// to recognize the //stream//. ''Facility="local0"'' keeps it out of the //standard facilities// (''auth'', ''syslog''). * ''ruleset="RemoteAuditFwd"'' in the ''imfile'' input is the critical part: It makes the //file-tail// output bypass the main //ruleset// and reach only the ''omfwd'' action. ==== Validate the configuration and start the service ==== # --- On pandora-console (10.0.0.2) --- rsyslogd -N1 systemctl enable --now rsyslog ''rsyslogd -N1'' performs a validation pass in a single read. The expected last line is ''End of config validation run. Bye.'' //Anything else indicates the configuration does not load, and the service will run **without** the forwarding rules//. ===== Testing and debugging ===== ==== Smoke test ==== # --- On pandora-console (10.0.0.2) --- # 1. Generate an audit-style line in the source file. # 192.0.2.10 is the IP address of the administrator # performing the action (fictitious value). TS=$(date '+%F %T') echo "$TS - admin - Test - 192.0.2.10 - rsyslog forwarding smoke test" \ | sudo tee -a /var/www/html/pandora_console/log/audit.log # 2. Wait for the imfile polling interval (10 seconds by default) sleep 15 # 3. Check the output file on the receiver cat /var/log/received/pandora-audit.log Expected output (the //timestamp// and the program name are added by Rsyslog on the sender; the final part is the original line): Jul 2 12:44:52 pandora-console pandora-audit 2026-07-02 12:44:52 - admin - Test - 192.0.2.10 - rsyslog forwarding smoke test In production, the audit lines are written by the Console itself, which does not need to "know" anything about Rsyslog. ==== Connectivity check ==== If nothing reaches the receiver, first validate the network path: # --- On pandora-console (10.0.0.2) --- bash -c 'echo > /dev/tcp/10.0.0.1/10514' && echo "TCP 10514 alcanzable" This works without ''nc'' or ''ncat'' and is the fastest way to rule out //firewall///network issues. ==== Review Rsyslog journals ==== Each of the endpoints has detailed error reports in its Systemd unit: # --- On pandora-console (10.0.0.2) --- journalctl -u rsyslog --no-pager -n 50 # --- On rsyslog-receiver (10.0.0.1) --- journalctl -u rsyslog --no-pager -n 50 **Patterns worth recognizing**: * ''action 'action-0-builtin:omfwd' suspended (…)'' followed by ''resumed'' — the receiver has gone down (or has been restarted), and the sender has reconnected. Messages are not lost thanks to ''action.resumeRetryCount=-1'' and ''queue.saveonshutdown=on''. \\ * ''omfwd: remote server closed connection'' — the receiver is rejecting connections. Check that the //listener// is running and that the //ruleset// is free of //parsing// errors. \\ * ''error during parsing file /etc/rsyslog.d/*.conf, on or before line N'' — correct the configuration and run ''rsyslogd -N1'' again before restarting the service. \\ ==== Common issues and solutions ==== ^Symptom ^Root cause ^Solution ^ |The receiver remains empty; the sender logs ''remote server closed connection''.|The receiver's configuration has a //parsing// error; the //listener// runs but messages are discarded by the default //ruleset//.|Run ''rsyslogd -N1'' on the receiver and correct the config. In Rsyslog 8.2510, use ''dynaFile='' and not ''template='' in ''omfile''.| |The receiver's file exists but contains ''CROND'', ''rsyslogd'', etc., not just auditing.|The ''omfwd'' action is declared at the root level of the sender's //config//; it forwards all messages from the //main ruleset//.|Wrap the ''omfwd'' action in a dedicated ''ruleset'' and link the ''imfile'' input to it with ''ruleset="..."''.| |''parameter 'queue.maxdisksize' not known'' on the sender.|That parameter is only valid for ''queue.type="disk"'', not for ''linkedList''.|Remove ''queue.maxdisksize'' or change the queue to ''disk''.| |After deleting ''/var/lib/rsyslog/imfile-state*'', historical data is not forwarded.|Expected: without a //state file//, ''imfile'' anchors to the current end of the file and only sends new lines.|Leave the //state file// as is. **To forward historical data**, use ''readMode="2"'' in the ''imfile'' input.| |New audit lines arrive with a delay.|''imfile'' does //polling// every 10 seconds by default.| Lower that value with ''PollingInterval="2"'' in the ''imfile'' input if near-//real-time// is needed.| |After a sender restart, the last seconds of auditing are lost| The memory queue is discarded upon shutdown.|''queue.saveonshutdown="on"'' (specified in the [[#ks6_3|Rsyslog journals review]]) persists the queue to disk; upon startup, Rsyslog empties it.| ==== Re-anchoring the sender ==== To rebuild the audit //stream// from scratch (for example, after a long offline period for the receiver where the local audit //log// has fallen behind), reset the ''imfile'' //state// and confirm that the file still exists in the expected path: # --- On pandora-console (10.0.0.2) --- # Locate the state file (its name contains a colon; enclose it in quotation marks) ls -la /var/lib/rsyslog/ | grep imfile-state # Erase it rm -f /var/lib/rsyslog/imfile-state:* # Restar service systemctl restart rsyslog After the restart, the sender only sends the lines written **after** the restart. To forward everything from the beginning of the current ''audit.log'', add ''readMode="2"'' to the ''imfile'' input and restart Rsyslog again. ===== Operational review list ===== * □ The receiver is online from the sender via ''TCP 10514''. * □ Clean ''rsyslogd -N1'' on both ends. * □ ''ss -ltn | grep 10514'' shows a ''LISTEN'' on the receiver. * □ A test line added to ''audit.log'' appears in ''/var/log/received/pandora-audit.log'' in less than a //polling// interval. * □ The receiver's //log// file contains **only** lines with the ''pandora-audit'' //tag// (without ''CROND'' / ''rsyslogd''). * □ ''systemctl enable rsyslog'' applied on both //hosts// so that forwarding survives a restart. [[:en:documentation:pandorafms:start|←Back to Pandora FMS documentation index]]