Dans le post précédent sur la sécurité MySQL, nous avons couvert une gamme d'options qui peuvent être utilisées pour rendre votre ou vos instances MySQL plus sécurisées. Ils comprenaient :
- Mesures de sécurité générales MySQL ;
- Contrôler l'accès dans MySQL ;
- Création, modification et suppression d'utilisateurs dans MySQL ;
- Accorder et révoquer des privilèges aux utilisateurs de MySQL ;
- Vérification des privilèges attribués aux utilisateurs dans MySQL.
Dans cet article, nous allons plonger dans le reste des options, y compris :
- Catégories de compte dans MySQL ;
- Rôles dans MySQL ;
- Comptes réservés dans MySQL ;
- Gestion des mots de passe dans MySQL ;
- Verrouillage de compte dans MySQL ;
- Plugins de sécurité proposés par MySQL ;
- Sécurisation des sauvegardes MySQL.
Gardez à l'esprit qu'une fois de plus, nous ne couvrirons pas absolument tout ce que vous devez savoir, mais nous essaierons de fournir de bons points de départ pour faire vos propres recherches.
Catégories de compte dans MySQL
Les catégories de comptes ont été introduites dans MySQL 8, plus précisément dans MySQL 8.0.16. Voici l'essentiel :
- Il existe deux catégories de comptes distinctes :les utilisateurs réguliers et les utilisateurs système ;
- Un utilisateur régulier est un utilisateur sans le privilège SYSTEM_USER - un utilisateur système est un utilisateur avec le privilège SYSTEM_USER ;
- Un utilisateur normal peut modifier les comptes normaux - un tel utilisateur ne peut pas modifier les comptes système ;
- Un utilisateur système peut modifier à la fois le compte système et le compte normal ;
- Les comptes réguliers peuvent être modifiés à la fois par les utilisateurs réguliers et les utilisateurs du système ;
- Les comptes système ne peuvent être modifiés que par les utilisateurs du système.
Pour utiliser les catégories de compte dans MySQL du point de vue de la sécurité, gardez à l'esprit que le privilège SYSTEM_USER affecte des choses comme la manipulation de compte et la suppression de sessions et d'instructions en leur sein - ce concept dans MySQL permet de restreindre certaines modifications à certains comptes rendant ainsi MySQL plus sûr. Les catégories de comptes peuvent également être utilisées pour protéger les comptes système contre la manipulation par des comptes réguliers :pour ce faire, n'accordez pas les privilèges de modification de schéma mysql aux comptes réguliers.
Pour accorder à un compte les privilèges SYSTEM_USER, utilisez la requête suivante sur un compte créé :
GRANT SYSTEM_USER ON *.* TO system_user;
Rôles dans MySQL
Dans MySQL, les rôles sont des ensembles de privilèges. Lorsque vous accordez un rôle à un compte utilisateur dans MySQL, vous accordez tous les privilèges associés à ce rôle. Les rôles peuvent être créés à l'aide de l'instruction CREATE ROLE :
CREATE ROLE ‘role_1’, ‘role_2’;
Les noms de rôle se composent d'une partie utilisateur et d'une partie hôte - la partie utilisateur ne peut pas être vide et la partie hôte par défaut est " %" si elle n'est pas spécifiée.
Lorsque des rôles sont créés, vous devez leur attribuer des privilèges. Les privilèges peuvent être attribués à l'aide de l'instruction GRANT :
- GRANT ALL ON demo_database.* TO 'demo_user' ; accorderait tous les privilèges à un utilisateur appelé demo_user sur une base de données appelée demo_database ;
- GRANT INSERT, SELECT, UPDATE, DELETE ON database.* TO 'demo_user' ; accorderait les privilèges INSERT, SELECT, UPDATE et DELETE à un utilisateur appelé demo_user sur une base de données appelée demo_database ;
- GRANT SELECT ON demo_database.* TO 'demo_user' ; accorderait des privilèges SELECT à un utilisateur appelé demo_user sur une base de données appelée demo_database.
Pour attribuer un rôle à un utilisateur individuel, utilisez cette syntaxe :
GRANT ‘role_name’ TO ‘user_name’@’localhost’;
Pour attribuer plusieurs rôles à un utilisateur individuel, utilisez cette syntaxe :
GRANT ‘role_1’, ‘role_2’ TO ‘user_name’@’localhost’;
Pour attribuer des rôles à plusieurs utilisateurs en même temps, utilisez cette syntaxe :
GRANT ‘role_name’ TO ‘user1’@’localhost’, ‘user2’@’localhost’;
Les rôles peuvent être utiles pour prévenir les incidents de sécurité car si un attaquant connaît le mot de passe d'un utilisateur peu privilégié en supposant à tort que l'utilisateur est très "puissant" en termes de rôle, votre application (et votre base de données) pourrait soyez très bien sauvé.
Comptes réservés dans MySQL
En ce qui concerne les comptes réservés, gardez à l'esprit que MySQL crée des comptes lors de l'initialisation du répertoire de données. Certains comptes doivent être considérés comme réservés dans MySQL :
- ‘root’@’localhost’ - ce compte est un compte superutilisateur et il a des privilèges divins sur toutes les bases de données MySQL (il peut effectuer n'importe quelle opération sur n'importe quelle base de données MySQL). Il convient de noter que l'utilisateur root peut également être renommé pour éviter d'exposer un compte hautement privilégié. Pour renommer le compte, exécutez la requête suivante :
RENAME USER ‘root’@’localhost’ TO ‘username’@’localhost’;
- Assurez-vous d'émettre un FLUSH PRIVILEGES ; déclaration après avoir renommé le compte pour que les modifications prennent effet.
- ‘mysql.sys’@’localhost’ - ce compte est un utilisateur système qui est utilisé comme définisseur pour la vue, les procédures et les fonctions dans le schéma sys. Ajouté à MySQL 5.7.9 pour éviter les problèmes pouvant survenir si le compte racine est renommé.
- ‘mysql.session’@’localhost’ - ce compte est utilisé en interne par les plugins pour accéder au serveur.
Dans ce cas, vous ne pouvez pas faire grand-chose en termes de sécurité, mais gardez à l'esprit que le compte root a des privilèges divins, ce qui signifie qu'il peut effectuer n'importe quelle opération sur n'importe quelle base de données MySQL et faire preuve de prudence au moment de décider à qui accorder les privilèges d'accès au compte. Gardez également à l'esprit à quoi servent les autres comptes MySQL.
Gestion des mots de passe dans MySQL
MySQL prend également en charge les fonctionnalités de gestion des mots de passe. Certains d'entre eux incluent :
- La possibilité d'expirer périodiquement les mots de passe ;
- La possibilité d'éviter la réutilisation du mot de passe ;
- La possibilité de générer des mots de passe ;
- La possibilité de vérifier si le mot de passe utilisé est fort ;
- La possibilité de verrouiller temporairement les utilisateurs après trop de tentatives de connexion infructueuses.
Maintenant, nous allons examiner ces options plus en détail.
Pour faire expirer un mot de passe manuellement, utilisez l'instruction ALTER USER comme suit :
ALTER USER ‘user’@’localhost’ PASSWORD EXPIRE;
Pour définir une stratégie globale, modifiez le fichier my.cnf de sorte qu'il inclue le paramètre default_password_lifetime. Le paramètre peut être défini sous la section [mysqld] (l'exemple suivant définit la durée de vie du mot de passe à 3 mois (90 jours)) :
default_password_lifetime=90
Si vous souhaitez que les mots de passe n'expirent jamais, définissez le paramètre default_password_litetime sur 0.
Vous pouvez également définir l'expiration du mot de passe pour des utilisateurs spécifiques. Si vous souhaitez définir l'intervalle d'expiration du mot de passe pour un utilisateur appelé demo_user, vous pouvez utiliser l'exemple suivant :
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE INTERVAL 90 DAY;
Pour désactiver l'expiration du mot de passe :
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE NEVER;
Pour réinitialiser la politique globale d'expiration du mot de passe :
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE DEFAULT;
Les restrictions de réutilisation des mots de passe n'autorisent pas la réutilisation des mots de passe - pour utiliser cette fonctionnalité, utilisez les variables password_history et password_reuse_interval. Vous pouvez soit mettre ces variables dans my.cnf en regardant l'exemple ci-dessous, soit les définir au moment de l'exécution en ajoutant SET PERSIST devant les instructions ci-dessous.
Pour interdire la réutilisation de l'un des 5 mots de passe précédemment utilisés datant de moins de 365 jours, utilisez :
password_history=5
password_reuse_interval=365
Pour exiger un minimum de 5 changements de mot de passe avant d'autoriser la réutilisation :
ALTER USER ‘demo_user’@’localhost’ PASSWORD HISTORY 5;
La même chose peut être faite lors de la création d'un utilisateur - remplacez ALTER USER par CREATE USER.
Pour générer un mot de passe aléatoire lors de la création d'un utilisateur, exécutez :
CREATE USER [email protected] IDENTIFIED BY RANDOM PASSWORD;
Pour remplacer le mot de passe d'un utilisateur par un mot de passe généré aléatoirement :
SET PASSWORD FOR [email protected] TO RANDOM;
Votre mot de passe aléatoire sera affiché en dessous.
Gardez à l'esprit que les mots de passe aléatoires par défaut ont une longueur de 20 caractères. La longueur peut être contrôlée par la variable generator_random_password_length qui a une plage de 5 à 255.
Pour vérifier si un mot de passe utilisé est fort, vous pouvez utiliser la variable VALIDATE_PASSWORD_STRENGTH - la fonction affiche un nombre de 0 à 100, 0 étant le plus faible et 100 le plus fort :
SELECT VALIDATE_PASSWORD_STRENGTH('password');
Verrouillage de compte dans MySQL
MySQL 8.0.19 a également introduit la possibilité de verrouiller temporairement les comptes d'utilisateurs. Cela peut être accompli en utilisant les variables FAILED_LOGIN_ATTEMPTS et PASSWORD_LOCK_TIME.
Pour activer le verrouillage de compte lors de la création d'un utilisateur, exécutez :
CREATE USER ‘demo_user’@’localhost’ IDENTIFIED BY ‘password’ FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 5;
La valeur après FAILED_LOGIN_ATTEMPTS spécifie après combien de tentatives infructueuses le compte est verrouillé, la valeur après PASSWORD_LOCK_TIME spécifie la durée de verrouillage du compte en jours. Il est également possible de spécifier une valeur qui ne se termine pas tant que le compte n'est pas déverrouillé en spécifiant PASSWORD_LOCK_TIME comme UNBOUNDED.
Plugins de sécurité proposés par MySQL
MySQL propose également quelques plugins qui peuvent encore améliorer les capacités de sécurité. MySQL propose :
- Plug-ins d'authentification ;
- Plugins de contrôle de connexion ;
- Plug-ins de validation de mot de passe ;
- Plug-ins d'audit ;
- Plug-ins de pare-feu ;
Ces plugins peuvent être utilisés pour un certain nombre de choses en termes de sécurité :
Plug-ins d'authentification
Les plugins d'authentification peuvent permettre aux utilisateurs de choisir entre plusieurs méthodes d'authentification enfichables disponibles dans MySQL. Ils peuvent être utilisés avec les instructions CREATE USER ou ALTER USER. Voici un exemple :
CREATE USER ‘user_1’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;
Cette requête implémenterait l'authentification à l'aide de la méthode native de hachage de mot de passe.
Plug-ins de contrôle de connexion
Les plugins de contrôle de connexion peuvent introduire un retard croissant dans les réponses du serveur aux tentatives de connexion si les tentatives de connexion dépassent un certain nombre - ils sont capables d'arrêter les attaques potentielles par force brute. Cette bibliothèque de plugins a été introduite dans MySQL dans la version 5.7.17 et peut être ajoutée à MySQL via my.cnf ou en chargeant les plugins sur le serveur lors de l'exécution.
Afin d'ajouter les plugins à my.cnf , ajoutez la ligne suivante sous [mysqld] :
plugin-load-add=connection_control.so
Après avoir modifié le fichier, enregistrez vos modifications et redémarrez MySQL.
Afin de charger les plugins sur le serveur lors de l'exécution, exécutez :
INSTALL PLUGIN CONNECTION_CONTROL SONAME ‘connection_control.so’;
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME ‘connection_control.so’;
Ajustez le suffixe .so si nécessaire. Si vous avez tout fait correctement, la table CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS devrait contenir toutes les tentatives de connexion infructueuses.
Plug-ins de validation de mot de passe
Les plugins de validation de mot de passe peuvent permettre aux utilisateurs d'utiliser des mots de passe plus forts s'ils sont utilisés correctement. Le plugin de validation de mot de passe peut être installé via my.cnf ou en chargeant le plugin sur le serveur lors de l'exécution. Pour installer le plugin via my.cnf, ajoutez la ligne suivante sous [mysqld], puis redémarrez le serveur :
plugin-load-add=validate_password.so
Pour charger le plug-in lors de l'exécution, exécutez l'instruction suivante :
INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Pour charger le plugin lors de l'exécution et empêcher sa suppression, ajoutez validate-password=FORCE_PLUS_PERMANENT à my.cnf.
Pour empêcher le serveur de s'exécuter si le plugin n'est pas initialisé, utilisez l'option --validate-password avec une valeur de FORCE ou FORCE_PLUS_PERMANENT.
La politique de force du mot de passe peut également être modifiée :pour ce faire, modifiez la valeur validate_password_policy sur LOW, MEDIUM ou STRONG. La valeur LOW vérifie uniquement la longueur du mot de passe, la politique MEDIUM ajoute certaines conditions et la politique STRONG ajoute la condition selon laquelle les sous-chaînes de mot de passe composées de 4 caractères ou plus ne doivent pas correspondre aux mots d'un fichier de dictionnaire qui peut être spécifié en modifiant la variable validate_password_dictionary_file.
Plug-ins porte-clés
Les plug-ins de porte-clés peuvent permettre aux composants et plug-ins du serveur de stocker en toute sécurité des informations sensibles pour les récupérer. Pour charger le plugin dans MySQL, ajoutez ce qui suit sous [mysqld] :
early-plugin-load=keyring_file.so
Pour spécifier le fichier du coffre-fort du trousseau de clés, ajoutez ce qui suit (la variable keyring_vault_config doit pointer vers le fichier de configuration) :
loose-keyring_vault_config=”/var/lib/mysql_keyring/keyring_vault.conf”
Le fichier de trousseau de clés doit contenir la variable Vault_url qui définit l'adresse du serveur du coffre, la variable secret_mount_point qui définit le nom du point de montage où le coffre du trousseau de clés stocke les clés, et un jeton qui doit être défini par le serveur de coffre-fort. En option, la variable voûte_ca peut également être définie (elle doit pointer vers le certificat CA utilisé pour signer les certificats du coffre).
Redémarrez le serveur pour que les modifications prennent effet ;
Plug-ins d'audit
Les plug-ins d'audit peuvent activer la surveillance, la journalisation et le blocage de l'activité effectuée sur les serveurs MySQL. Pour installer MySQL Enterprise Audit, exécutez un script situé dans le répertoire de partage de votre instance MySQL (évitez de mettre le mot de passe de votre instance MySQL dans le terminal - utilisez my.cnf) :
mysql < /path/to/audit_log_filter_linux_install.sql
Vous pouvez également empêcher la suppression du plug-in lors de l'exécution - ajoutez ce qui suit dans la section [mysqld] :
audit_log=FORCE_PLUS_PERMANENT
Redémarrez le serveur pour appliquer les modifications. Notez que la journalisation basée sur des règles n'enregistre aucun événement auditable par défaut, donc pour qu'elle enregistre tout, créez un filtre :
SELECT audit_log_filter_set_filter(‘log_filter’, ‘{ “filter”: { “log”: true } }’);
Puis attribuez-le à un compte :
SELECT audit_log_filter_set_user(‘%’, ‘log_filter’);
Notez que les plugins d'audit ne sont disponibles que dans MySQL Enterprise Edition ;
Plug-ins de pare-feu
Les plug-ins de pare-feu peuvent permettre aux utilisateurs d'autoriser ou de refuser l'exécution d'instructions SQL spécifiques en fonction de modèles spécifiques. MySQL Enterprise Firewall a été introduit dans MySQL 5.6.24 - il est capable de protéger les données en surveillant, en alertant et en bloquant les activités non autorisées :il est capable de bloquer les attaques par injection SQL, de surveiller les menaces et de bloquer le trafic suspect ainsi que de détecter les intrusions dans la base de données. Le pare-feu est également capable de consigner les déclarations bloquées - elles peuvent être inspectées et un décompte en temps réel des déclarations approuvées et rejetées peut également être observé.
Pour installer MySQL Enterprise Firewall, activez-le simplement lors de l'installation de MySQL Server sous Windows, il peut également être installé, désactivé ou désinstallé à l'aide de MySQL Workbench 6.3.4. Le pare-feu peut également être installé manuellement en exécutant un script dans le répertoire de partage de votre installation MySQL. Pour activer le pare-feu, ajoutez la ligne suivante sous [mysqld] et redémarrez le serveur :
mysql_firewall_mode=ON
Le pare-feu peut également être activé lors de l'exécution :
SET GLOBAL mysql_firewall_mode = ON;
Alternativement, pour conserver le pare-feu (ce qui signifie que le pare-feu n'aura pas à être réactivé à chaque redémarrage ultérieur du serveur) :
SET PERSIST mysql_firewall_mode = ON;
Ensuite, accordez un privilège FIREWALL_ADMIN à tout compte qui administre le pare-feu et le privilège FIREWALL_USER à tout compte qui ne doit avoir accès qu'à ses propres règles de pare-feu. Accordez également le privilège EXECUTE pour les procédures stockées du pare-feu dans la base de données mysql. Pour que le pare-feu fonctionne, enregistrez des profils avec celui-ci, puis entraînez le pare-feu à connaître les déclarations autorisées que la base de données peut exécuter et dites ensuite au pare-feu de faire correspondre les déclarations entrantes à la liste blanche définie. Chaque profil a un mode opérationnel - ARRÊT, ENREGISTREMENT, PROTECTION ou DETECTION. OFF désactive le profil, RECORDING forme le pare-feu, PROTECTING autorise ou refuse l'exécution de l'instruction et DETECTING détecte (mais ne bloque pas) les tentatives d'intrusion. Les règles d'un profil spécifié peuvent être réinitialisées en définissant sa valeur sur RESET. OFF désactivera le profil. Pour définir le mode, utilisez la requête suivante, où name est le nom du profil et OFF est le mode opérationnel :
CALL mysql.sp_set_firewall_mode(name, ‘OFF’);
Le plug-in de pare-feu est également disponible uniquement dans MySQL Enterprise Edition.
Sécuriser les sauvegardes MySQL
En ce qui concerne les sauvegardes MySQL, vous avez plusieurs options.
- Si vous utilisez mysqldump, vous pouvez stocker votre nom d'utilisateur et votre mot de passe dans my.cnf et invoquer mysqldump comme ceci (la commande suivante videra toutes les bases de données dans un fichier /home/backup.sql) :
$ mysqldump --defaults-extra-file=/var/lib/my.cnf --single-transaction --all-databases > /home/backup.sql
- En stockant votre nom d'utilisateur et votre mot de passe à l'intérieur de my.cnf, vous n'écrivez pas votre mot de passe à l'intérieur du terminal - une telle méthode pour effectuer des sauvegardes est plus sûre car pendant que le vidage est en cours d'exécution, la commande peut être vue via le ps ax commande.
-
Vous pouvez également envisager d'utiliser mysqldump-secure qui est un script wrapper compatible POSIX qui est capable de compresser et de chiffrer les sauvegardes avec une sécurité renforcée à l'esprit .
-
Les sauvegardes peuvent être chiffrées à l'aide d'OpenSSL - prenez simplement votre sauvegarde, puis chiffrez-la avec la commande suivante :
$ openssl enc -aes-256-cbc -salt -in backup.tar.gz -out backup.tar.gz.enc -k password
La commande ci-dessus créera un nouveau fichier crypté backup.tar.gz.enc dans le répertoire courant. Le fichier sera crypté avec le mot de passe que vous avez choisi (remplacez le mot de passe par le mot de passe souhaité). Le fichier peut être déchiffré ultérieurement en exécutant la commande suivante :
$ openssl aes-256-cbc -d -in backup.tar.gz.enc -out backup.tar.gz -k password
Remplacez le mot de passe par votre mot de passe.
-
mysqldump a une autre option pour chiffrer vos sauvegardes (l'exemple suivant les compresse également avec gzip) :
$ mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl enc -aes-256-cbc -k password > backup.xb.enc
Remplacez le mot de passe par le mot de passe souhaité.
-
Vous pouvez également chiffrer vos sauvegardes à l'aide de mariabackup ou xtrabackup. Voici un exemple tiré de la documentation de MariaDB :
$ mariabackup --user=root --backup --stream=xbstream | openssl enc -aes-256-cbc -k password > backup.xb.enc
Remplacez le mot de passe par le mot de passe souhaité.
-
Les sauvegardes peuvent également être chiffrées à l'aide de ClusterControl - si l'option de chiffrement est activée pour une sauvegarde particulière, ClusterControl chiffrera la sauvegarde à l'aide d'AES-256 CBC (le chiffrement se produit sur le nœud de sauvegarde). Si la sauvegarde est stockée sur un nœud de contrôleur, les fichiers de sauvegarde sont diffusés dans un format chiffré à l'aide de socat ou netcat. Si la compression est activée, ClusterControl va d'abord compresser la sauvegarde, puis la chiffrer. La clé de chiffrement sera générée automatiquement si elle n'existe pas, puis stockée dans la configuration CMON dans l'option backup_encryption_key. Gardez à l'esprit que cette clé est codée et doit d'abord être décodée. Pour ce faire, exécutez la commande suivante :
$ cat /etc/cmon.d/cmon_ClusterID.cnf | grep ^backup_encryption_key | cut -d"'" -f2 | base64 -d > keyfile.key
La commande lira la backup_encryption_key et décodera sa valeur en une sortie binaire. Le fichier clé peut être utilisé pour déchiffrer la sauvegarde comme suit :
$ cat backup.aes256 | openssl enc -d -aes-256-cbc -pass file:/path/to/keyfile.key > backup_file.xbstream.gz
Pour plus d'exemples, consultez la documentation de ClusterControl.
Conclusion
Dans ces articles sur la sécurité de MySQL, nous avons couvert certaines mesures de sécurité qui peuvent être utiles si vous ressentez le besoin de renforcer la sécurité de votre ou vos instances MySQL. Bien que nous n'ayons pas couvert absolument tout, nous pensons que ces points peuvent être un bon point de départ pour renforcer la sécurité de votre installation MySQL. Tirez de ces messages ce que vous voulez, faites vos propres recherches et appliquez les mesures de sécurité les plus applicables à votre situation.