MariaDB
 sql >> Base de données >  >> RDS >> MariaDB

Trucs et astuces à l'aide de la journalisation d'audit pour MariaDB

Le plug-in d'audit de MariaDB fournit des fonctionnalités d'audit non seulement pour MariaDB, mais également pour MySQL (à partir des versions 5.5.34 et 10.0.7) et pour Percona Server. MariaDB a commencé à inclure par défaut le plugin d'audit à partir des versions 10.0.10 et 5.5.37, et il peut être installé dans n'importe quelle version à partir de MariaDB 5.5.20.

L'objectif du plug-in d'audit MariaDB est de consigner l'activité du serveur. Pour chaque session client, il enregistre qui s'est connecté au serveur (c'est-à-dire le nom d'utilisateur et l'hôte), quelles requêtes ont été exécutées, quelles tables ont été consultées et quelles variables de serveur ont été modifiées. Ces informations sont stockées dans un fichier journal rotatif ou peuvent être envoyées au syslogd local.

Dans cet article de blog, nous allons vous montrer quelques réglages et astuces sur la façon de configurer la journalisation d'audit pour un serveur MariaDB. L'écriture est basée sur MariaDB 10.5.9, avec la dernière version de MariaDB Audit Plugin 1.4.4.

Réglage de l'installation

La méthode recommandée pour activer la journalisation d'audit consiste à définir les lignes suivantes dans le fichier de configuration MariaDB :

[mariadb]
plugin_load_add = server_audit # load plugin
server_audit=FORCE_PLUS_PERMANENT  # do not allow users to uninstall plugin
server_audit_file_path=/var/log/mysql/mariadb-audit.log # path to the audit log
server_audit_logging=ON  # enable audit logging

N'oubliez pas de définir "server_audit=FORCE_PLUS_PERMANENT" pour appliquer le journal d'audit et interdire sa désinstallation par d'autres utilisateurs à l'aide de l'instruction UNINSTALL SONAME. Par défaut, la destination de journalisation est un fichier journal dans le répertoire de données MariaDB. Nous devrions placer le journal d'audit en dehors de ce répertoire car il est possible que le datadir soit effacé (SST pour Galera Cluster), ou remplacé pour une restauration physique comme l'échange de datadir lors de la restauration d'une sauvegarde prise à partir de MariaDB Backup.

Un réglage supplémentaire est nécessaire, comme indiqué dans les sections suivantes.

Filtrage des événements d'audit

Le plug-in MariaDB Audit utilise plusieurs paramètres de journal qui dépendent de la version du plug-in. Les événements d'audit suivants sont disponibles sur la dernière version 1.4.4 du plug-in :

Type

Description

CONNECTER

Se connecte, se déconnecte et se connecte en échec, y compris le code d'erreur

QUERY

Requêtes exécutées et leurs résultats en texte brut, y compris les requêtes ayant échoué en raison d'erreurs de syntaxe ou d'autorisation

TABLEAU

Tables affectées par l'exécution de la requête

QUERY_DDL

Semblable à QUERY, mais filtre uniquement les requêtes de type DDL (instructions CREATE, ALTER, DROP, RENAME et TRUNCATE - sauf CREATE/DROP [PROCEDURE / FUNCTION / USER] et RENAME USER (elles ne sont pas DDL)

QUERY_DML

Similaire à QUERY, mais filtre uniquement les requêtes de type DML (instructions DO, CALL, LOAD DATA/XML, DELETE, INSERT, SELECT, UPDATE, HANDLER et REPLACE)

QUERY_DML_NO_SELECT

Similaire à QUERY_DML, mais n'enregistre pas les requêtes SELECT. (depuis la version 1.4.4) (instructions DO, CALL, LOAD DATA/XML, DELETE, INSERT, UPDATE, HANDLER et REPLACE)

QUERY_DCL

Similaire à QUERY, mais filtre uniquement les requêtes de type DCL (CREATE USER, DROP USER, RENAME USER, GRANT, REVOKE et SET PASSWORD)

Par défaut, il suivra tout puisque la variable server_audit_events sera définie sur vide par défaut. Notez que les anciennes versions prennent moins en charge le type d'opération ci-dessus, comme illustré ici. Assurez-vous donc que vous utilisez la dernière version si vous souhaitez effectuer un filtrage spécifique.

Si le cache de requêtes est activé et qu'une requête est renvoyée à partir du cache de requêtes, aucun enregistrement TABLE n'apparaîtra dans le journal car le serveur n'a ouvert ou accédé à aucune table et s'est plutôt appuyé sur le cache résultats. Vous pouvez donc désactiver la mise en cache des requêtes.

Pour filtrer des événements spécifiques, définissez la ligne suivante dans le fichier de configuration MariaDB (nécessite un redémarrage) :

server_audit_events = 'CONNECT,QUERY,TABLE'

Ou définissez-le dynamiquement dans le runtime à l'aide de SET GLOBAL (ne nécessite aucun redémarrage, mais pas persistant) :

MariaDB> SET GLOBAL server_audit_events = 'CONNECT,QUERY,TABLE';

Voici l'exemple d'un événement d'audit :

20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,226,QUERY,information_schema,'SHOW GLOBAL VARIABLES',0

Une entrée de ce journal consiste en un ensemble d'informations séparées par une virgule contenant les informations suivantes :

  • Horodatage

  • L'hôte MySQL (identique à la valeur de SELECT @@hostname)

  • L'utilisateur de la base de données

  • Hôte auquel l'utilisateur se connectait

  • Identifiant de connexion

  • Identifiant du fil

  • Fonctionnement

  • Base de données

  • Instruction/commande SQL

  • Code de retour. 0 signifie que l'opération renvoie une réponse de réussite (même vide), tandis qu'une valeur différente de zéro signifie une erreur lors de l'exécution de l'opération comme une requête ayant échoué en raison d'erreurs de syntaxe ou d'autorisation.

Lors du filtrage des entrées, on ferait un simple grep et on chercherait un modèle spécifique :

$ grep -i global /var/lib/mysql/server_audit.log
20210325 04:19:17,ip-172-31-0-44,root,localhost,14,37080,QUERY,,'set global server_audit_file_rotate_now = 1',0
20210326 00:46:48,ip-172-31-0-44,root,localhost,35,329003,QUERY,,'set global server_audit_output_type = \'syslog\'',0

Par défaut, toutes les valeurs de mots de passe seront masquées par des astérisques :

20210326 05:39:41,ip-172-31-0-44,root,localhost,52,398793,QUERY,mysql,'GRANT ALL PRIVILEGES ON sbtest.* TO [email protected] IDENTIFIED BY *****',0

Auditer le filtrage des utilisateurs

Si vous suivez tout, vous serez probablement submergé par l'utilisateur de surveillance pour sa responsabilité d'échantillonnage, comme indiqué dans l'exemple ci-dessous :

20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,226,QUERY,information_schema,'SHOW GLOBAL VARIABLES',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,227,QUERY,information_schema,'select @@global.wsrep_provider_options',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,228,QUERY,information_schema,'SHOW SLAVE STATUS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,229,QUERY,information_schema,'SHOW MASTER STATUS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,230,QUERY,information_schema,'SHOW SLAVE HOSTS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,231,QUERY,information_schema,'SHOW GLOBAL VARIABLES',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,232,QUERY,information_schema,'select @@global.wsrep_provider_options',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,233,QUERY,information_schema,'SHOW SLAVE STATUS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,234,QUERY,information_schema,'SHOW MASTER STATUS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,7,235,QUERY,information_schema,'SHOW SLAVE HOSTS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,5,236,QUERY,information_schema,'SET GLOBAL SLOW_QUERY_LOG=0',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,5,237,QUERY,information_schema,'FLUSH /*!50500 SLOW */ LOGS',0
20210325 02:02:08,ip-172-31-0-44,cmon,172.31.1.119,6,238,QUERY,information_schema,'SHOW GLOBAL STATUS',0

En l'espace d'une seconde, nous pouvons voir 14 événements QUERY enregistrés par le plugin d'audit pour notre utilisateur de surveillance appelé "cmon". Dans notre charge de travail de test, le taux de journalisation est d'environ 32 Ko par minute, ce qui accumulera jusqu'à 46 Mo par jour. Selon la taille de stockage et la capacité d'E/S, cela peut être excessif dans certaines charges de travail. Il serait donc préférable de filtrer l'utilisateur de surveillance de la journalisation d'audit, afin que nous puissions avoir une sortie plus propre et beaucoup plus facile à auditer et à analyser.

Selon les politiques de sécurité et d'audit, nous pourrions filtrer l'utilisateur indésirable comme l'utilisateur de surveillance en utilisant la variable suivante dans le fichier de configuration MariaDB (nécessite un redémarrage) :

server_audit_excl_users='cmon'

Ou définissez-le dynamiquement dans le runtime à l'aide de SET GLOBAL (ne nécessite aucun redémarrage, mais pas persistant) :

MariaDB> SET GLOBAL server_audit_excl_users = 'cmon'

Vous pouvez ajouter plusieurs utilisateurs de base de données, séparés par une virgule. Après avoir ajouté ce qui précède, nous avons obtenu des journaux d'audit plus propres, comme ci-dessous (plus rien de l'utilisateur 'cmon'):

$ tail -f /var/log/mysql/mysql-audit.log
20210325 04:16:06,ip-172-31-0-44,cmon,172.31.1.119,6,36218,QUERY,information_schema,'SHOW GLOBAL STATUS',0
20210325 04:16:06,ip-172-31-0-44,root,localhost,13,36219,QUERY,,'set global server_audit_excl_users = \'cmon\'',0
20210325 04:16:09,ip-172-31-0-44,root,localhost,13,36237,QUERY,,'show global variables like \'%server_audit%\'',0
20210325 04:16:12,ip-172-31-0-44,root,localhost,13,0,DISCONNECT,,,0

Gestion de la rotation des journaux

Étant donné que le journal d'audit va capturer un grand nombre d'événements, il est recommandé de configurer une rotation de journal appropriée pour celui-ci. Sinon, nous nous retrouverions avec une taille énorme de fichier journal qui rend son analyse très difficile. Pendant que le serveur est en cours d'exécution et que server_audit_output_type=file, nous pouvons forcer la rotation du fichier journal en utilisant l'instruction suivante :

MariaDB> SET GLOBAL server_audit_file_rotate_now = 1;

Pour la rotation automatique des journaux, nous devons définir les variables suivantes dans le fichier de configuration MariaDB :

server_audit_file_rotate_size=1000000 # in bytes
server_audit_file_rotations=30

Ou définissez-le dynamiquement dans le runtime à l'aide de SET GLOBAL (ne nécessite aucun redémarrage) :

MariaDB> SET GLOBAL server_audit_file_rotate_size=1000000;
MariaDB> SET GLOBAL server_audit_file_rotations=30;

Pour désactiver la rotation des journaux d'audit, définissez simplement server_audit_file_rotations sur 0. La valeur par défaut est 9. La rotation des journaux se produira automatiquement après avoir atteint le seuil spécifié et conservera les 30 derniers journaux, ce qui signifie que le 30 derniers jours de journalisation d'audit.

Audit à l'aide de Syslog ou Rsyslog Facility

L'utilisation de la fonction syslog ou rsyslog facilitera la gestion des journaux car elle permet la journalisation à partir de différents types de systèmes dans un référentiel central. Au lieu de maintenir un autre composant de journalisation, nous pouvons demander à l'audit MariaDB de se connecter à syslog. Ceci est pratique si vous disposez d'un collecteur/diffuseur de journaux pour les services d'analyse de journaux tels que Splunk, LogStash, Loggly ou Amazon CloudWatch.

Pour ce faire, définissez les lignes suivantes dans le fichier de configuration MariaDB (nécessite un redémarrage) :

server_audit_logging = 'syslog'
server_audit_syslog_ident = 'mariadb-audit'

Ou si vous souhaitez modifier le runtime (ne nécessite aucun redémarrage, mais pas persistant) :

MariaDB> SET GLOBAL server_audit_logging = 'syslog';
MariaDB> SET GLOBAL server_audit_syslog_ident = 'mariadb-audit';

Les entrées seront similaires au format Syslog :

$ grep mariadb-audit /var/log/syslog
Mar 26 00:48:49 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,36,329540,QUERY,,'SET GLOBAL server_audit_syslog_ident = \'mariadb-audit\'',0
Mar 26 00:48:54 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,36,0,DISCONNECT,,,0

Si vous souhaitez configurer un service de journalisation à distance pour un référentiel de journalisation centralisé, nous pouvons utiliser rsyslog. L'astuce consiste à utiliser la variable server_audit_syslog_facility où nous pouvons créer un filtre pour faciliter la journalisation, comme ci-dessous :

MariaDB> SET GLOBAL server_audit_logging = 'syslog';
MariaDB> SET GLOBAL server_audit_syslog_ident = 'mariadb-audit';
MariaDB> SET GLOBAL server_audit_syslog_facility = 'LOG_LOCAL6';

Cependant, il y a quelques étapes préalables préalables. Considérez l'architecture de réplication maître-esclave MariaDB suivante avec un serveur rsyslog centralisé :

Dans cet exemple, tous les serveurs fonctionnent sur Ubuntu 20.04. Sur le serveur de destination rsyslog, nous devons définir ce qui suit dans /etc/rsyslog.conf :

module(load="imtcp")
input(type="imtcp" port="514")
$ModLoad imtcp
$InputTCPServerRun 514
if $fromhost-ip=='172.31.0.44' then /var/log/mariadb-centralized-audit.log
& ~
if $fromhost-ip=='172.31.0.82' then /var/log/mariadb-centralized-audit.log
& ~

Notez que la partie "&~" est importante et ne la manquez pas. Il indique essentiellement à la fonction de journalisation de se connecter à /var/log/mariadb-centralized-audit.log et d'arrêter tout traitement ultérieur juste après.

Ensuite, créez le fichier journal de destination avec le propriétaire et l'autorisation corrects :

$ touch /var/log/mariadb-centralized-audit.log
$ chown syslog:adm /var/log/mariadb-centralized-audit.log
$ chmod 640 /var/log/mariadb-centralized-audit.log

Redémarrez rsyslog :

$ systemctl restart rsyslog

Assurez-vous qu'il écoute toutes les adresses IP accessibles sur le port TCP 514 :

$ netstat -tulpn | grep rsyslog
tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN      3143247/rsyslogd
tcp6       0      0 :::514                  :::*                    LISTEN      3143247/rsyslogd

Nous avons terminé la configuration du serveur rsyslog de destination. Nous sommes maintenant prêts à configurer la partie source. Sur le serveur MariaDB, créez un nouveau fichier de configuration rsyslog séparé dans /etc/rsyslog.d/50-mariadb-audit.conf et ajoutez les lignes suivantes :

$WorkDirectory /var/lib/rsyslog # where to place spool files
$ActionQueueFileName queue1     # unique name prefix for spool files
$ActionQueueMaxDiskSpace 1g     # 1GB space limit (use as much as possible)
$ActionQueueSaveOnShutdown on   # save messages to disk on shutdown
$ActionQueueType LinkedList     # run asynchronously
$ActionResumeRetryCount -1      # infinite retries if rsyslog host is down
local6.* action(type="omfwd" target="172.31.6.200" port="514" protocol="tcp")

Les paramètres de la première section concernent la création d'une file d'attente sur disque, ce qui est recommandé pour ne perdre aucune entrée de journal. La dernière ligne est importante. Nous avons changé la variable server_audit_syslog_facility en LOG_LOCAL6 pour le plugin d'audit. Ici, nous avons spécifié "local6.*" comme filtre pour transférer uniquement les entrées Syslog à l'aide de l'installation local6 vers rsyslog exécuté sur le serveur rsyslog 172.31.6.200, sur le port 514 via le protocole TCP.

Pour activer les modifications pour rsyslog, la dernière étape consiste à redémarrer le rsyslog sur le serveur MariaDB pour activer les modifications :

$ systemctl restart rsyslog

Maintenant, rsyslog est correctement configuré sur le nœud source. Nous pouvons tester en accédant au serveur MariaDB et effectuer certaines activités pour générer des événements d'audit. Vous devriez voir que les entrées du journal d'audit sont transférées ici :

$ tail -f /var/log/mariadb-centralized-audit.log
Mar 26 12:56:18 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,69,0,CONNECT,,,0
Mar 26 12:56:18 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,69,489413,QUERY,,'select @@version_comment limit 1',0
Mar 26 12:56:19 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,69,489414,QUERY,,'show databases',0
Mar 26 12:56:37 ip-172-31-0-44 mariadb-audit:  ip-172-31-0-44,root,localhost,69,0,DISCONNECT,,,0

Réflexions finales

MariaDB Audit Plugin peut être configuré de plusieurs façons pour s'adapter à vos politiques de sécurité et d'audit. Les informations d'audit peuvent vous aider à résoudre les problèmes de performances ou d'application, et vous permettent de voir exactement quelles requêtes SQL sont en cours de traitement.