Outils pour utilisateurs

Outils du site


sysadmin:linux:rsyslog:export_elasticsearch

rsyslog: exporter les logs vers elasticsearch

rsyslog propose un module natif écrit en C permettant de journaliser les logs produits localement vers une serveur Elasticsearch. L'avantage est sa simplicité de mise en œuvre. On évite l'utilisation du composant Logtash, la solution est plus économe en ressources.

rsyslog s'adresse directement à Elasticsearch via son module omelasticsearch. Contrairement a syslong-ng aucune bibliothèque Java n'est nécessaire, rsyslog utilise l'API Rest HTTP pour pousser les données.

Installer le module

sudo apt install rsyslog-elasticsearch

Ajouter un fichier de configuration dans le dossier /etc/rsyslog.d/*.conf

00-elasticsearch.conf
module(load="omelasticsearch")
 
template(name="plain-syslog" type="list" option.json="on") {
    constant(value="{")
    constant(value="\"@timestamp\":\"")     property(name="timereported" dateFormat="rfc3339")
    constant(value="\",\"host\":\"")        property(name="hostname")
    constant(value="\",\"severity-num\":")  property(name="syslogseverity")
    constant(value=",\"facility-num\":")    property(name="syslogfacility")
    constant(value=",\"severity\":\"")      property(name="syslogseverity-text")
    constant(value="\",\"facility\":\"")    property(name="syslogfacility-text")
    constant(value="\",\"syslogtag\":\"")   property(name="syslogtag")
    constant(value="\",\"message\":\"")     property(name="msg")
    constant(value="\"}")
}
 
template(name="logstash-index" type="string" string="logstash-%$YEAR%.%$MONTH%.%$DAY%")
 
action(type="omelasticsearch"
  template="plain-syslog"
  searchIndex="logstash-index"
  dynSearchIndex="on"
  bulkmode="on"
  errorfile="/var/log/omelasticsearch.log")

Le template reformate les données produites par rsyslog en JSON. Avec cette configuration tous les logs générés par l’hôte sont communiqués au serveur elasticsearch. Chaque jour un nouvel index est créé de la forme rsyslog-AAAA.MM.DD. Ces données peuvent être présentées simplement sans modification par Kibana.

Mise en forme et export des logs UFW

On définit un nouveau template de type list qui reformate les données générées par UFW. Ici le champ message est analysé via des regex afin de définir de nouveau attributs sur lesquels des filtres pourront être utilisés lors de requêtes ou dans Kibana confère wiki templates_et_regex et

template(name="json-ufw" type="list" option.jsonf="on") {
    property(name="timereported" outname="@timestamp" dateFormat="rfc3339" format="jsonf")
    property(name="hostname" outname="host" format="jsonf")
    constant(value="UFW" outname="app-name" format="jsonf")
    property(name="syslogfacility" outname="facility-num" datatype="number" format="jsonf")
    property(name="syslogfacility-text" outname="facility" format="jsonf")
    # Remplace le niveau de criticité par défaut des logs générés par UFW warning -> notice
    #property(name="syslogseverity" outname="severity-num" datatype="number" format="jsonf")
    #property(name="syslogseverity-text" outname="severity" format="jsonf")
    constant(value="\"severity-num\": 5")
    constant(value="notice" outname="severity" format="jsonf")
    property(name="syslogtag" outname="syslogtag" format="jsonf")
    property(name="msg" outname="action" onEmpty="null" regex.submatch="2" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="(\\[UFW\\s)(\\w*)" format="jsonf")
    property(name="msg" outname="in_interface" onEmpty="null" regex.submatch="2" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="(\\sIN=)(\\w*)" format="jsonf")
    property(name="msg" outname="out_interface" onEmpty="null" regex.submatch="2" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="(\\sOUT=)(\\w*)" format="jsonf")
    property(name="msg" outname="protocol" onEmpty="null" regex.submatch="2" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="(\\sPROTO=)(\\w*|\\d*)" format="jsonf")
    property(name="msg" outname="src_ip" onEmpty="null" regex.submatch="1" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="SRC=([0-9]+(\\.[0-9]+){3})" format="jsonf")
    property(name="msg" outname="dst_ip" onEmpty="null" regex.submatch="1" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="DST=([0-9]+(\\.[0-9]+){3})" format="jsonf")
    property(name="msg" outname="src_port" onEmpty="null" regex.submatch="1" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="SPT=(\\w+)" datatype="number" format="jsonf")
    property(name="msg" outname="dst_port" onEmpty="null" regex.submatch="1" regex.type="ERE" regex.nomatchmode="BLANK" regex.expression="DPT=(\\w+)" datatype="number" format="jsonf")
    property(name="msg" outname="message" format="jsonf")
}

On associe le template à une ou plusieurs actions, ici les données sont enregistrées localement puis communiquées a la base elasticsearch via le module omelasticsearch:

# action
:msg,contains,"[UFW " action(type="omfile" file="/var/log/ufw-json.log" template="json-ufw")
&action(type="omelasticsearch"
  server="localhost"
  serverport="9200"
  template="json-ufw"
  searchIndex="logstash-index"
  dynSearchIndex="on"
  bulkmode="on"
  maxbytes="100m"
  queue.type="linkedlist"
  queue.size="5000"
  queue.dequeuebatchsize="300"
  action.resumeretrycount="-1"
  errorfile="/var/log/rsyslog-elasticsearch.log")

Références

sysadmin/linux/rsyslog/export_elasticsearch.txt · Dernière modification : 2021/06/12 14:26 de 77.192.232.26