Par defaut, MySQL 5 sous Ubuntu est configuré avec 2 utilisateurs :
root
et
debian-sys-maint
. Le premier sert à
l'administration du SGBD : création des bases, création
des utilisateurs, etc... Le deuxième en revanche sert au démarrage, à l'arrêt
et à la mise à jour des packages de la base.
root
n'a pas de mot de passe par défaut.
La première des choses à faire après l'installation de la base est donc de lui
en affecter un. mysqladmin
permet de changer
des mots de passe, mais aussi de créér/supprimer des bases de données, de
démarrer/stopper un serveur, ...
Pour modifier le mot de passe d'un utilisateur MySQL il y a plusieurs possibilités, mais nous n'en verrons que deux. Nous pouvons le faire directement en ligne de commande soit en ligne de commande bash (voir les remarques à ce sujet dans Section 6.3.4, « Outils ») :
root@ubuntu:~#mysqladmin password "nouveaumotdepasse"
❶ root@ubuntu:~#mysqladmin password "nouveaumotdepasse"
❷ mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user 'root'@'localhost' (using password: NO)' ❸ root@ubuntu:~#history -r
root@ubuntu:~#
❶ | modification du mot de passe |
❷ | une fois le mot de passe modifié, il faut utiliser
|
❸ | relecture de l'historique |
Une autre solution est de le faire en ligne de commande MySQL :
root@ubuntu:~#mysql
❶ Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 36 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>SET PASSWORD FOR root@localhost=PASSWORD('nouveaumotdepasse');
❷ Query OK, 0 rows affected (0.12 sec) mysql>FLUSH PRIVILEGES;
❸ Query OK, 0 rows affected (0.02 sec) mysql>QUIT
❹ Bye root@ubuntu:~# cat /dev/null > ~/.mysql_history ❺ root@ubuntu:~#
❶ | démarrage du shell MySQL. |
❷ | modification du mot de passe pour l'utilisateur root se connectant depuis localhost. |
❸ |
|
❹ | fermeture du shell MySQL |
❺ | le shell |
Pour plus de sécurité, on peut aussi modifier le nom du
« super-utilisateur » MySQL. Par défaut c'est
root, mais une fois de plus, rien ne nous oblige à utiliser
ce compte. Pour changer le nom de l'utilisateur, il faudra faire les modifications
directement en SQL dans la table système
(table mysql
).
root@ubuntu:~#mysql -p
❶ Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 37 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>USE mysql;
❷ Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql>UPDATE user SET user='dbadmin' WHERE user='root';
❸ Query OK, 3 rows affected (0.11 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql>FLUSH PRIVILEGES;
❹ Query OK, 0 rows affected (0.01 sec) mysql>QUIT
Bye root@ubuntu:~#mysql -p
Enter password: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ❺ root@ubuntu:~#mysql -u dbadmin -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. ❻ Your MySQL connection id is 39 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>QUIT
Bye root@ubuntu:~#cat /dev/null > ~/.mysql_history
❶ | démarrage du shell MySQL. |
❷ | use permet de changer la base de données en cours.
|
❸ |
|
❹ |
|
❺ | même avec le bon mot de passe, mysql nous refuse : l'utilisateur
root n'existe plus. Nous devons donc spécifier
l'utilisateur avec l'option |
❻ | avec le bon utilisateur, pas de problème |
Selon les version de MySQL et les OS qui les packagent, on trouve parfois
un utilisateur anonyme configuré par défaut[18]. Même
si cet utilisateur n'a en général pas de droits, il est préférable de le
supprimer afin d'éliminer un vecteur potentiel d'intrusion dans la base de
données. Il faudra donc se connecter à la base
mysql
et supprimer l'utilisateur '' (dont le
nom est vide) dans la table user.
Attention : les utilisateurs peuvent apparaître plusieurs fois dans la table user, puisque la clef de cette table est le couple (utilisateur, hôte de connexion).
root@ubuntu:~#mysql -u dbadmin -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 40 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>SHOW DATABASES;
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test | +--------------------+ 3 rows in set (0.03 sec) mysql>USE mysql
Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql>DELETE FROM user WHERE user='';
Query OK, 1 row affected (0.00 sec) mysql>DELETE FROM db WHERE user='';
Query OK, 2 rows affected (0.01 sec) mysql>
Enfin, on pourra faire une dernière passe sur la base de données système mysql afin de s'assurer que seuls les droits nécessaires sont activés.
mysql>DELETE FROM db;
❶ Query OK, 0 rows affected (0.00 sec) mysql>DELETE FROM user WHERE NOT (host="localhost" AND (user="dbadmin" OR user="debian-sys-maint"));
❷ Query OK, 3 rows affected (0.00 sec) mysql>FLUSH PRIVILEGES;
❸ Query OK, 0 rows affected (0.00 sec) mysql>
❶ | suppression de toutes les règles de la table db. |
❷ | suppression de tous les utilisateurs qui ne sont pas root ou debian-sys-maint. |
❸ | actualisation des droits. |
Les opérations de création et suppression peuvent aussi s'effectuer de
deux façons : en ligne de commande bash, ou en ligne de commande mysql. La
première méthode utilise encore mysqladmin avec les arguments
create
ou
drop
:
root@ubuntu:~#mysqladmin create mabase -u dbadmin -p
❶ Enter password: root@ubuntu:~#mysqlshow -u dbadmin mabase -p
❷ Enter password: Database: mabase +--------+ | Tables | +--------+ +--------+ root@ubuntu:~#
❶ | creation de la base en ligne de commande. |
❷ | mysqlshow permet d'obtenir des informations sur des bases, des tables et des champs. |
En cas de regrets mysqladmin drop
permet de
supprimer la base :
root@ubuntu:~#mysqladmin drop mabase -u dbadmin -p
Enter password: Dropping the database is potentially a very bad thing to do. Any data stored in the database will be destroyed. Do you really want to drop the 'mabase' database [y/N]y
Database "mabase" dropped root@ubuntu:~#mysqlshow -u dbadmin mabase -p
Enter password: mysqlshow: Unknown database 'mabase' root@ubuntu:~#
Si l'on préfère la version ligne de commande mysql, on fera :
root@ubuntu:~#mysql -u dbadmin -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 17 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>CREATE DATABASE mabase;
Query OK, 1 row affected (0.01 sec) mysql>SHOW DATABASES;
+--------------------+ | Database | +--------------------+ | information_schema | | mabase | | mysql | | test | +--------------------+ 4 rows in set (0.00 sec) mysql>DROP DATABASE mabase;
Query OK, 0 rows affected (0.01 sec) mysql>SHOW DATABASES;
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test | +--------------------+ 3 rows in set (0.00 sec) mysql>
On pourra pratiquer en réèl sur la base test. Cette base est livrée avec toutes les versions de MySQL et apparemment sous tous les OS supportés. Comme pour l'utilsateur anonyme, il est préférable de s'en débarasser : elle n'apporte rien sinon un vecteur potentiel pour un attaquant. Cela pourra éventuellement ennuyer quelques modules Perl liés à MySQL qui testent parfois leur bon fonctionnement en utilisant la base test comme cobaye. Dans ce cas, il faudra forcer leur installation ou recréer la base test.
mysql>DROP DATABASE test;
Query OK, 0 rows affected (0.01 sec) mysql>SHOW DATABASES;
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ 2 rows in set (0.00 sec) mysql>
Une commande particulièrement dangereuse sous MySQL est LOAD DATA INFILE. Elle permet d'insérer le contenu d'un fichier dans une base de données. Si, via une application PHP, une attaquante arrive à injecter du code SQL, elle pourra éventuellement remplir des tables avec des informations sensibles :
root@ubuntu:~#mysql -u dbadmin -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>LOAD DATA LOCAL INFILE "/etc/passwd" INTO TABLE mydb.res;
Query OK, 29 rows affected (0.07 sec) Records: 29 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT * FROM res WHERE texte LIKE 'root%'; +---------------------------------+ | texte | +---------------------------------+ | root:x:0:0:root:/root:/bin/bash | +---------------------------------+ 1 row in set (0.00 sec) mysql>
On voit les problèmes que ce genre de commande peut amener : une exposition
de la totalité des fichiers de configuration système : réupération des
identifiants utilisateur sur le système afin de préparer une attaque par force
brute, escalade de privilèges en récupérant les informations
d'authentification dans /etc/mysql/debian.cnf
, etc...
On veillera donc à supprimer l'accès à LOCAL INFILE dans le
fichier de configuration en ajoutant :
set-variable = local-infile=0
dans la section [mysqld]
. Après avoir
redémarré la base de données, il faudra vérifier que la configuration est
correctement appliquée :
root@ubuntu:~#mysql -u dbadmin -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>LOAD DATA LOCAL INFILE "/etc/passwd" INTO TABLE mydb.res;
ERROR 1148 (42000): The used command is not allowed with this MySQL version mysql>
Par defaut sous Ubuntu la directive
bind-address = 127.0.0.1
est dans le fichier
de configuration par défaut. Elle permet de restreindre l'accès au port 3306
à la machine locale (127.0.0.1). On devra commenter cette directive uniquement
si l'accès au serveur MySQL est requis depuis une autre machine. Si le serveur
possède plusieurs interfaces, on ne « bindera » le serveur que sur
l'interface nécessaire. Il est aussi possible de supprimer complètement l'accès
au serveur MySQL via le réseau avec la directive
skip-networking
. Dans ce cas les clients
devront utiliser la socket unix /var/run/mysqld/mysqld.sock
pour se connecter à la base.
Comme on a pû le remarquer plus haut, le shell MySQL conserve
un historique, à l'image de bash, dans le fichier
~/.mysql_history
. On peut demander à
mysql d'utiliser un autre fichier grâce à la variable
d'environnement MYSQL_HISTFILE
(tout comme
HISTFILE dans le cas de bash).
Pour supprimer l'historique, il y a deux possibilités :
mettre « /dev/null » dans la variable
MYSQL_HISTFILE
(export MYSQL_HISTFILE="/dev/null" dans le fichier
~/.bashrc
par exemple),
lier ~/.mysql_history
à
/dev/null
(ln -sf /dev/null ~/.mysql_history).
La structure du filtrage étant déja en place, l'ouverture de l'accès à la base MySQL est très simple. On n'ouvrira l'accès au port que si cela est réèllement nécessaire, et, si possible, uniquement aux adresses IP qui le nécessitent. Il n'y a pas de raison d'ouvrir l'accès IP au serveur de bases de données à tout le monde.
Exemple 6.1. MySQL : configuration du filtrage TCP en entrée
# # ###################################### # TCP entrant # Il faudra ouvrir des ports au fil de l'eau # lors de la mise en place de # services TCP (ssh, apache, ...). # ###################################### # -A TCP_IN -j TCP_INLIMITS -A TCP_IN -j STATEFUL -A TCP_IN -j TCP_SYNLIMITS -A TCP_IN -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m limit --limit 10/min -j LOG --log-prefix "TCP_IN:" --log-level 6 -A TCP_IN -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -j DROP # Ajouter les rêgles ici lors de l'installation de services TCP si ces services # doivent être ouverts # -A TCP_IN -s adresse_ip_autorisée -p tcp -m tcp --dport 3306 -j ACCEPT ❶ # on peut aussi débloquer le port 3306 pour tout le monde -A TCP_IN -p tcp -m tcp --dport 3306 -j ACCEPT ❷ #