| |

LFCS 131 ๐Ÿง rsyslog โ€” Configuration

โฑ๏ธ Estimated read: 10 min | |

The systemd journal is the default log store on modern Linux distributions, but it is not the only one. The rsyslog daemon runs alongside the journal and writes traditional text files to /var/log/. It is the mechanism that produces /var/log/syslog, /var/log/auth.log, /var/log/messages, and /var/log/kern.log. The LFCS exam tests the configuration syntax of /etc/rsyslog.conf, the rule format (selector, action), the facility and priority levels, and the distinction between the local log files and the remote log forwarding. The critical point is that a rule is a filter and an action. The filter selects the messages by facility and severity. The action writes them to a file, forwards them to a remote host, or discards them.

Key point: The rsyslog.conf file uses the format facility.priority action. The facility identifies the source (auth, kern, mail, cron, daemon, user, local0-7). The priority identifies the severity (debug, info, notice, warning, err, crit, alert, emerg). The action is a file path (prefixed with - for async write), a remote host (prefixed with @ for UDP or @@ for TCP), or a stop/discard directive. The configuration is loaded with systemctl restart rsyslog, and the syntax is validated with rsyslogd -N1.


Why rsyslog configuration requires explicit rules

The facility problem. A message is categorized by the subsystem that generated it. The kernel messages use kern. The authentication messages use auth or authpriv. The mail server uses mail. The cron daemon uses cron. The custom applications use local0 through local7. The facility is the first part of the filter. A rule for kern.* matches every kernel message, regardless of severity.

The priority problem. A message has a severity. The priority is the second part of the filter. The *.err matches every message with severity err or higher, regardless of facility. The kern.crit matches kernel messages with severity crit or higher. The . is the separator. The * is the wildcard. The = is the exact match (kern.=crit matches only crit, not alert or emerg). The ! is the negation (kern.!err matches everything except err).

The action problem. The action determines what happens to the matched message. A file path writes the message to the file. A - prefix before the path writes asynchronously, which is faster but may lose messages on a crash. A @host forwards to a remote host over UDP. A @@host forwards over TCP. The :omusrmsg: action sends to logged-in users. The ~ or stop discards the message. The action is the destination.

The ordering problem. The rules are evaluated in order. A message that matches the first rule is written to the first action. If the first rule has a stop directive, the message is not evaluated against the subsequent rules. The stop is the mechanism for preventing a message from being written to multiple files. Without it, a *.info rule and a *.err rule both match an error message, and the message is written to both files.

The trade-off. The rsyslog configuration is more complex than the systemd journal’s automatic indexing. The journal is queryable by field. The rsyslog files are text, and the searching is done with grep. But the rsyslog files are the traditional format that many tools expect, and the remote forwarding is a built-in feature that the journal also supports but with a different configuration syntax.


a. The rule format: facility, priority, and action

A rule is a line with two parts: the selector and the action. The selector is facility.priority. The action is the destination.

# /etc/rsyslog.conf

# Kernel messages to kern.log
kern.*                          /var/log/kern.log

# Authentication messages to auth.log
auth,authpriv.*                 /var/log/auth.log

# All messages with info or higher to syslog
*.info;mail.none;authpriv.none;cron.none    /var/log/syslog

# Cron messages to cron.log
cron.*                          /var/log/cron.log

# Mail messages to mail.log
mail.*                          -/var/log/mail.log

The *.info;mail.none;authpriv.none;cron.none rule matches all messages with severity info or higher, excluding mail, authpriv, and cron. The exclusion is the none priority. The semicolon is the separator between selectors. The rule is a single line with multiple selectors and one action.

The -/var/log/mail.log action uses the - prefix, which writes asynchronously. The async write is faster but may lose the last few messages on a crash. The sync write (no -) is safer but slower.

The stop directive prevents a message from being processed by subsequent rules.

# Stop processing cron messages after writing to cron.log
cron.*                          /var/log/cron.log
& stop

The & is the continuation character. The stop directive discards the message after the action. Without it, the message continues to the next rule, which may write it to another file.


b. Remote logging: forwarding and receiving

The rsyslog can forward messages to a remote host. The @ prefix is UDP. The @@ prefix is TCP.

# Forward all messages to a remote syslog server over UDP
*.*                             @logserver.example.com:514

# Forward over TCP
*.*                             @@logserver.example.com:514

The remote host must have rsyslog configured to receive. The receiving configuration requires the imudp or imtcp module and a rule to write the received messages to a file.

# /etc/rsyslog.conf on the receiving server

# Load the UDP module
module(load="imudp")
input(type="imudp" port="514")

# Load the TCP module
module(load="imtcp")
input(type="imtcp" port="514")

# Write received messages to a file
*.*                             /var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log

The %HOSTNAME% and %PROGRAMNAME% are message properties. They are replaced with the sender’s hostname and the program name. The % is the property delimiter. The properties are the mechanism for creating per-host and per-program log files.

The input directive must be inside a module block, or the module must be loaded with module(load=...) before the input. The port is the listening port. The 514 is the standard syslog port, but it requires root or CAP_NET_BIND_SERVICE to bind on ports below 1024. A port above 1024 is the alternative for a non-root process.


c. Validation and the included configuration files

The rsyslog configuration is validated with rsyslogd -N1. The -N1 flag checks the syntax without starting the daemon. The -f flag specifies an alternative configuration file.

# Validate the configuration
sudo rsyslogd -N1

# Validate a specific file
sudo rsyslogd -N1 -f /etc/rsyslog.conf

The configuration can be split across multiple files with the $IncludeConfig directive or the include() function. The modern syntax uses include().

# Include additional configuration files
include(file="/etc/rsyslog.d/*.conf")

The /etc/rsyslog.d/ directory is the standard location for additional rules. The distribution packages and the administrator rules are split across separate files. The 50-default.conf file contains the default rules on Debian/Ubuntu. The 99-custom.conf file is the conventional place for the administrator’s additions.

The systemctl restart rsyslog command applies the configuration. The systemctl status rsyslog command shows the daemon status and the recent errors. The journalctl -u rsyslog command shows the rsyslog logs.


Complete Example Session

# ============================================
# PART 1: VIEW THE DEFAULT CONFIG
# ============================================

cat /etc/rsyslog.conf
# Shows the default rules.
# ============================================
# PART 2: ADD A CUSTOM RULE
# ============================================

sudo tee /etc/rsyslog.d/99-custom.conf <<'EOF'
# Log all auth messages to a separate file
auth,authpriv.*    /var/log/my-auth.log
EOF
# ============================================
# PART 3: VALIDATE THE CONFIG
# ============================================

sudo rsyslogd -N1
# Output: rsyslogd: version ..., config validation run (level 1), master config /etc/rsyslog.conf
# rsyslogd: End of config validation run. Bye.
# ============================================
# PART 4: RESTART THE SERVICE
# ============================================

sudo systemctl restart rsyslog
sudo systemctl status rsyslog
# active (running)
# ============================================
# PART 5: TRIGGER A TEST MESSAGE
# ============================================

logger -p auth.info "Test auth message"
# The message appears in /var/log/my-auth.log.
# ============================================
# PART 6: VIEW THE LOG
# ============================================

sudo tail /var/log/my-auth.log
# Shows the test message.
# ============================================
# PART 7: FORWARD TO A REMOTE HOST
# ============================================

sudo tee -a /etc/rsyslog.d/99-custom.conf <<'EOF'
*.*    @@logserver.example.com:514
EOF
sudo rsyslogd -N1
sudo systemctl restart rsyslog
# ============================================
# PART 8: CONFIGURE THE RECEIVER
# ============================================

sudo tee /etc/rsyslog.d/99-receive.conf <<'EOF'
module(load="imtcp")
input(type="imtcp" port="514")

*.*    /var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log
EOF
sudo rsyslogd -N1
sudo systemctl restart rsyslog
# ============================================
# PART 9: VERIFY REMOTE LOGGING
# ============================================

# On the sender:
logger "Remote test"
# On the receiver:
ls /var/log/remote/<sender-hostname>/
# Shows the received log.

The nine parts trace the rsyslog configuration: default config, custom rule, validation, restart, test message, log view, remote forwarding, receiver configuration, and verification.


Quick Reference

Facilities

FacilitySource
kernKernel
authAuthentication
authprivPrivate auth (passwords)
mailMail server
cronCron
daemonSystem daemons
userUser processes
local0โ€“local7Custom applications

Priorities

PriorityNumberMeaning
emerg0Emergency
alert1Alert
crit2Critical
err3Error
warning4Warning
notice5Notice
info6Informational
debug7Debug

Selectors

SyntaxMeaning
*.*All facilities, all priorities
kern.*All kernel messages
*.errAll errors and above
kern.=critKernel messages with crit only
kern.!errKernel messages except err
*.info;mail.noneInfo and above, except mail

Actions

ActionMeaning
/var/log/file.logWrite to file
-/var/log/file.logAsync write
@host:514UDP forward
@@host:514TCP forward
~ or stopDiscard

Validation

CommandPurpose
rsyslogd -N1Validate syntax
systemctl restart rsyslogApply config
journalctl -u rsyslogView rsyslog logs

Best Practices

โœ… Do This:

sudo rsyslogd -N1
<!-- Validate config before restart -->              # โœ…
auth,authpriv.*    /var/log/auth.log
<!-- Separate auth logs from syslog -->              # โœ…
module(load="imtcp")
input(type="imtcp" port="514")
<!-- Load the module before input -->                # โœ…

โŒ Don’t Do This:

# Forget the stop directive
<!-- Messages go to multiple files -->               # โŒ
# Bind to port 514 without root
<!-- Permission denied -->                           # โŒ
# Restart without validation
<!-- A syntax error stops the daemon -->             # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Daemon fails to startSyntax errorrsyslogd -N1
Messages missingRule order wrongAdd stop directive
Remote logs not receivedModule not loadedAdd module(load=...)
File not createdPermissionsCheck logrotate and ownership
Async write loses messages- prefixRemove - for sync

Real-World Examples

1. Kernel Log

kern.*    /var/log/kern.log

2. Auth Log

auth,authpriv.*    /var/log/auth.log

3. Syslog

*.info;mail.none;authpriv.none;cron.none    /var/log/syslog

4. Stop Directive

cron.*    /var/log/cron.log
& stop

5. UDP Forward

*.*    @logserver.example.com:514

6. TCP Forward

*.*    @@logserver.example.com:514

7. Load UDP

module(load="imudp")
input(type="imudp" port="514")

8. Load TCP

module(load="imtcp")
input(type="imtcp" port="514")

9. Remote Log File

*.*    /var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log

10. Validate

sudo rsyslogd -N1

Visual

Rule Format

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  facility.priority    action                 โ”‚
โ”‚                                              โ”‚
โ”‚  auth,authpriv.*    /var/log/auth.log        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Filter: all auth messages                   โ”‚
โ”‚  Action: write to /var/log/auth.log          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Remote Logging

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Sender                                      โ”‚
โ”‚  *.*    @@logserver.example.com:514          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚ TCP
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Receiver                                    โ”‚
โ”‚  module(load="imtcp")                        โ”‚
โ”‚  input(type="imtcp" port="514")              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  /var/log/remote/<hostname>/<program>.log    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Config file/etc/rsyslog.conf
Drop-in directory/etc/rsyslog.d/
Rule formatfacility.priority action
Validationrsyslogd -N1
Restartsystemctl restart rsyslog
UDP forward@host:port
TCP forward@@host:port
Remote modulemodule(load="imudp") / imtcp
Stop directive& stop
Async write- prefix

Key takeaways:

  • A rule is a filter and an action. The filter is the facility and priority. The action is the file, the remote host, or the discard. The rules are evaluated in order.
  • The stop directive prevents duplicate writes. Without it, a message that matches multiple rules is written to multiple files. The & stop after a rule discards the message for the subsequent rules.
  • The async write (-) is faster but riskier. It may lose the last few messages on a crash. The sync write is safer for critical logs.
  • Remote forwarding uses @ for UDP and @@ for TCP. The receiving server must load the imudp or imtcp module and configure the input.
  • The configuration is validated with rsyslogd -N1. The daemon fails to start if the configuration has a syntax error. The validation is the mandatory step before the restart.

Remember: The rsyslog is the traditional text log daemon. The journal is the binary log store. The two run together, and the rsyslog files are the ones that are grep-able. The rule is the filter. The action is the destination. The stop is the boundary. The validation is the gate. The exam tests the syntax and the remote configuration.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!