Rsyslog

Siehe auch

RHEL setzt seit Version 6 auf Rsyslog als Syslog-Client und -Server, welches das ursprüngliche syslogd-Modell erweitert. Seit Rsyslog Version 7 können Logdaten auch von journald, einer Komponente von systemd, verwaltet werden. journald erlaubt mit seiner Komponente journalctl eine sehr detaillierte Untersuchung aller Logausgaben eines Systems, die komfortabler ist und deren Ergebnisse durch zusätzliche Metadaten genauer sind als die „alte“ Methode mittels tail/cat/grep. Unter RHEL existieren beide Logging-Tools nebeneinander.

  • Facility: Typ der Nachricht

  • Severity: Schweregrad

    • emerg: System is unusable

    • alert: Immediate action required

    • crit: Critical condition

    • err: Error condition

    • warning: Warning condition

    • notice: Normal but significant condition

    • info: Informational messages

    • debug: Debugging messages

Die Rsyslog-Konfigurationssyntax ab Version 7 unterscheidet sich teilweise deutlich von der Version 5 (in den Bereichen Module, Template-Syntax, Debugging etc.).

Rsyslog v8+ unterstützt GELF (Graylog Extended Log Format).

Rsyslog-Versionen:

  • Rsyslog liegt Stand 2023-01 in Version 8.2212.0 vor.

  • RHEL 8.7: Rsyslog v8.2102.0

  • RHEL 7.4: Rsyslog v8.24

  • RHEL 7.3: Rsyslog v7.4.7

  • RHEL 6.x: Rsyslog v5.8.10

Module:

  • im: Input Modules

  • mm: Message Modification Modules

  • om: Output Modules

Die Doku zu Rsyslog findet sich in

dnf -y install rsyslog-doc
# /usr/share/doc/rsyslog

Bemerkung

Man prüft die Rsyslog-Konfiguration, indem man den Daemon interaktiv laufen lässt:

rsyslogd -N1 -f /etc/rsyslog.d/my.conf

Exkurs: logger

Beispiele:

logger 'my message'
logger --priority local3.info --tag 'my tag name' 'my message'
logger --server 192.0.2.74 --udp --port 1514 'my message on '$(date)

Eine Priorität besteht aus facility.level. Default-Priorität ist user.notice.

Nutzbare Facilities sind:

  • auth

  • authpriv (for security information of a sensitive nature)

  • cron

  • daemon

  • ftp

  • lpr

  • mail

  • news

  • syslog

  • user

  • uucp

  • local0 .. local7

Gültige Level-Namen sind:

  • emerg

  • alert

  • crit

  • err

  • warning

  • notice

  • info

  • debug

Syslog-Client

Soll ein Rsyslog-Client seine Logdaten an einen zentralen Syslog-Server 192.0.2.74 senden, so muss dies auf dem Client wie folgt konfiguriert werden:

/etc/rsyslog.d/myforward.conf
# using UDP (recommended)
*.* @192.0.2.74:514

# using TCP
*.* @@192.0.2.74:514

Fehlt noch die ausgehende Firewall-Regel, der Restart des Rsyslog und ein anschliessender Test:

firewall-cmd --add-port=514/udp
firewall-cmd --reload
systemctl restart rsyslog.service
logger --server 192.0.2.74 --udp --port 1514 'Test Syslog 1514/udp on '$(date)

Testnachricht von ... muss danach mindestens in /var/log/messages des Syslog-Servers (hier 192.0.2.74) auftauchen.

Syslog-Server

Möchte man selbst einen zentralen Syslog-Server auf Basis von Rsyslog betreiben, der Nachrichten per UDP auf Port 514 entgegennehmen kann, muss man die folgenden Zeilen aktivieren:

/etc/rsyslog.conf
module(load="imudp")
input(type="imudp" port="514")

Überprüfen, ob rsyslog auch auf Port 514 lauscht:

ss --udp --listening --numeric | grep 514

Pro sendendem Host eine Log-Datei pro Facility ablegen:

/etc/rsyslog.conf
template(
    name="OneFilePerServer"
    type="string"
    string="/var/log/hosts/%HOSTNAME%/%syslogfacility-text%.log"
)
*.* action(
    type="omfile"
    dynafile="OneFilePerServer"
)

Forwarding und Filtering

Siehe auch http://www.rsyslog.com/doc/v8-stable/configuration/filters.html.

So nimmt man Nachrichten von der Übermittlung aus, die beispielsweise mit der Zeichenkette „RULE“ beginnen:

/etc/rsyslog.d/myforward.conf
# Rsyslog v7+
:msg, startswith, "RULE " stop
*.* @192.0.2.74:514

# Rsyslog v5
  :msg, startswith, "RULE "  ~
  *.* @192.0.2.74:514

Etwas komplexere Forwarding-Rule per Syslog und Filter:

/etc/rsyslog.d/myforward.conf
# rsyslog v7 filter conditions:
# contains isequal startswith regex ereregex
if (
    $msg startswith "GSSAPI client step "
    or $msg startswith "GSSAPI server step "
    or ($programname == "kernel" and $msg startswith "RULE ")
    or ($programname == "systemd" and ($msg startswith "Created slice " or $msg startswith "Removed slice "))
    or ($programname == "systemd" and ($msg startswith "Starting user-" or $msg startswith "Stopping user-"))
    or ($programname == "systemd" and ($msg startswith "Starting Session " or $msg startswith "Started Session "))
    or ($programname == "systemd-logind" and ($msg startswith "New Session " or $msg startswith "Removed Session "))
)
then {
    # ignore, do not foward
    continue
} else {
    *.* @192.0.2.74:514;RSYSLOG_SyslogProtocol23Format
}

Templates

Templates ermöglichen die Definition eines beliebigen Log-Formats. Sie werden auch für die dynamische Generierung von Dateinamen verwendet. Jede Ausgabe in rsyslog verwendet Templates - das gilt für Dateien, Benutzernachrichten und so weiter. Templates, die mit den Standardformaten von syslogd kompatibel sind, sind in rsyslogd fest codiert.

Wer mit Regexes hantiert: Unbedingt den Regex-Tester von rsyslog.com verwenden: http://www.rsyslog.com/regex/ - Log-Line einpasten, Regex ausprobieren und rsyslog.conf Template-Syntax erhalten.

Beispiel für ein Template auf einem zentralen Syslog-Server, welches cron-Meldungen verschiedener Absender in einzelne Verzeichnisse einsortiert:

/etc/rsyslog.d/store-cron.conf
template (name="HostTemplate" type="string" string="/var/log/loghost/%HOSTNAME%/cron.log")

# usage:
cron.* action(type="omfile" DynaFile="HostTemplate")

Mit einem Template lässt sich auch GELF-Forwarding umsetzen:

/etc/rsyslog.d/myforward.conf
template(
    name="gelf"
    type="list"
) {
    constant(value="{\"version\":\"1.1\",")
    constant(value="\"host\":\"")
    property(name="hostname")
    constant(value="\",\"short_message\":\"")
    property(name="msg" format="json")
    constant(value="\",\"timestamp\":")
    property(name="timegenerated" dateformat="unixtimestamp")
    constant(value=",\"level\":\"")
    property(name="syslogseverity")
    constant(value="\"}")
}

# syslog forwarder via UDP
action(type="omfwd" target="192.0.2.74" port="12201" protocol="udp" template="gelf")

Um zu ermitteln, was wirklich in den einzelnen Variablen steckt und an Inhalten geliefert wird, kann folgendes Template statt dem eingebauten RSYSLOG_TraditionalFileFormat verwendet werden:

template(
    name="full_debug"
    type="list"
) {
    constant(value="app-name: ")
    property(name="app-name")
    constant(value="\n")
    constant(value="bom: ")
    property(name="$bom")
    constant(value="\n")
    constant(value="day: ")
    property(name="$day")
    constant(value="\n")
    constant(value="fromhost: ")
    property(name="fromhost")
    constant(value="\n")
    constant(value="fromhost-ip: ")
    property(name="fromhost-ip")
    constant(value="\n")
    constant(value="hostname: ")
    property(name="hostname")
    constant(value="\n")
    constant(value="hhour: ")
    property(name="$hhour")
    constant(value="\n")
    constant(value="hour: ")
    property(name="$hour")
    constant(value="\n")
    constant(value="inputname: ")
    property(name="inputname")
    constant(value="\n")
    constant(value="iut: ")
    property(name="iut")
    constant(value="\n")
    constant(value="jsonmesg: ")
    property(name="jsonmesg")
    constant(value="\n")
    constant(value="minute: ")
    property(name="$minute")
    constant(value="\n")
    constant(value="month: ")
    property(name="$month")
    constant(value="\n")
    constant(value="msg: ")
    property(name="msg")
    constant(value="\n")
    constant(value="msgid: ")
    property(name="msgid")
    constant(value="\n")
    constant(value="myhostname: ")
    property(name="$myhostname")
    constant(value="\n")
    constant(value="now: ")
    property(name="$now")
    constant(value="\n")
    constant(value="now-unixtimestamp: ")
    property(name="$now-unixtimestamp")
    constant(value="\n")
    constant(value="pri: ")
    property(name="pri")
    constant(value="\n")
    constant(value="pri-text: ")
    property(name="pri-text")
    constant(value="\n")
    constant(value="procid: ")
    property(name="procid")
    constant(value="\n")
    constant(value="programname: ")
    property(name="programname")
    constant(value="\n")
    constant(value="protocol-version: ")
    property(name="protocol-version")
    constant(value="\n")
    constant(value="qhour: ")
    property(name="$qhour")
    constant(value="\n")
    constant(value="rawmsg: ")
    property(name="rawmsg")
    constant(value="\n")
    constant(value="rawmsg-after-pri: ")
    property(name="rawmsg-after-pri")
    constant(value="\n")
    constant(value="source: ")
    property(name="source")
    constant(value="\n")
    constant(value="structured-data: ")
    property(name="structured-data")
    constant(value="\n")
    constant(value="syslogfacility: ")
    property(name="syslogfacility")
    constant(value="\n")
    constant(value="syslogfacility-text: ")
    property(name="syslogfacility-text")
    constant(value="\n")
    constant(value="syslogpriority: ")
    property(name="syslogpriority")
    constant(value="\n")
    constant(value="syslogpriority-text: ")
    property(name="syslogpriority-text")
    constant(value="\n")
    constant(value="syslogseverity: ")
    property(name="syslogseverity")
    constant(value="\n")
    constant(value="syslogseverity-text: ")
    property(name="syslogseverity-text")
    constant(value="\n")
    constant(value="syslogtag: ")
    property(name="syslogtag")
    constant(value="\n")
    constant(value="timegenerated: ")
    property(name="timegenerated")
    constant(value="\n")
    constant(value="timereported: ")
    property(name="timereported")
    constant(value="\n")
    constant(value="timestamp: ")
    property(name="timestamp")
    constant(value="\n")
    constant(value="wday: ")
    property(name="$wday")
    constant(value="\n")
    constant(value="year: ")
    property(name="$year")
    constant(value="\n")
}

module(load="builtin:omfile" template="full_debug")

Rsyslog-Properties

Verwendbare Variablen:

  • app-name

  • bom

  • day

  • fromhost

  • fromhost-ip

  • hhour

  • hostname

  • hour

  • inputname

  • iut

  • jsonmesg

  • minute

  • month

  • msg

  • msgid

  • myhostname

  • now

  • now-unixtimestamp

  • pri

  • pri-text

  • procid

  • programname

  • protocol-version

  • qhour

  • rawmsg

  • rawmsg-after-pri

  • source

  • structured-data

  • syslogfacility

  • syslogfacility-text

  • syslogpriority

  • syslogpriority-text

  • syslogseverity

  • syslogseverity-text

  • syslogtag

  • timegenerated

  • timereported

  • timestamp

  • wday

  • year

Kommandozeilen-Eingaben speichern

Kommdozeilen-Eingaben auf verschiedenen Linux-Servern sollen alle im zentralen Syslog landen? Dann richtet man das hier auf den einzelnen Maschinen ein:

/etc/profile.d/log-commands.sh
PROMPT_COMMAND=$(history -a > (tee -a ~/.bash_history | & logger -t "$USER[$$] $SSH_CONNECTION"))
typeset -r PROMPT_COMMAND
source /etc/profile.d/log-commands.sh

Rsyslog mit MariaDB-Backend

Rsyslog kann Log-Nachrichten in einer MariaDB-Datenbank ablegen.

dnf -y install rsyslog-mysql
/etc/rsyslog.conf
# old syntax

# the MariaDB connection
$ModLoad ommysql

# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# ignore those messages
:msg, startswith, "RULE " stop

# the DB connection
# all-messages  :modname:dbserv,dbname,dbuser,dbpass[;template]
*.* >192.0.2.74,Syslog,dbuser,linuxfabrik

Auf dem MariaDB-Server das folgende (optimierte) SQL-Statement zur Erzeugung der Syslog-Datenbank mit der zentralen Log-Tabelle ausführen:

CREATE DATABASE Syslog;

USE Syslog;

CREATE TABLE SystemEvents
(
    ID int unsigned not null auto_increment primary key,

    FromHost varchar(255) NULL,
    SysLogTag varchar(255),
    Facility smallint NULL,
    Priority smallint NULL,
    DeviceReportedTime datetime NULL,
    ReceivedAt datetime NULL,
    Message text,
    InfoUnitID int NULL ,

    CurrUsage int NULL,
    CustomerID bigint,
    EventBinaryData text NULL,
    EventCategory int NULL,
    EventID int NULL,
    EventLogType varchar(255),
    EventSource varchar(255),
    EventUser varchar(255) NULL,
    GenericFileName VarChar(255),
    Importance int NULL,
    MaxAvailable int NULL,
    MaxUsage int NULL,
    MinUsage int NULL,
    NTSeverity int NULL,
    SystemID int NULL
);

Ein Benutzer für diese Datenbank muss lediglich SELECT- und INSERT-Rechte besitzen.

Nicht wundern: in den Standard-Einstellungen werden nur die optisch abgesetzten Spalten DeviceReportedTime, Facility, FromHost, InfoUnitID, Message, Priority, ReceivedAt und SysLogTag gefüllt. Die restlichen Spalten stehen für Windows-Eventlogs und eigene Template-Kreationen zur Verfügung - wer möchte, kann auf diese verzichten, eigene anlegen und mit Hilfe von Rsyslog-Templates befüllen.

Das originale SQL-Statement findet sich unter /usr/share/doc/rsyslog-mysql-*/createDB.sql.

Aufpassen: Man muss selbst für eine angemessene Retention der Daten in der MariaDB sorgen.

Troubleshooting

Rsyslog debuggen:

/etc/rsyslog.conf
# first lines:
$DebugFile /var/log/rsyslog.log
$DebugLevel 2

Built on 2024-02-28