====== 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]]