mysql安全和权限
时间:2007-04-08 来源:wangbinde
一、mysql授权表
mysql数据库安装成功后,数据库已经建好了test数据库和包含5个授权表的mysql数据库。
mysql> show tables from mysql;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| func |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| proc |
| procs_priv |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
17 rows in set (0.00 sec)
除了func表外(该表用于用户定义的功能),每个表都可以根据用户名,连接主机或申请的数据库来建立访问规则。
user表:
mysql> desc user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | | |
| x509_issuer | blob | NO | | | |
| x509_subject | blob | NO | | | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.01 sec) mysql> select host,user,password from user;
+-----------------------+------+----------+
| host | user | password |
+-----------------------+------+----------+
| localhost | root | |
| localhost.localdomain | root | |
| localhost.localdomain | | |
| localhost | | |
+-----------------------+------+----------+
4 rows in set (0.01 sec)
上表表示root用户可以从可以从localhost和localhost.localomain无需口令登陆mysql服务器。当然host可以是一个固定的ip。在windows和unix中,mysql用户与系统用户并不相同。mysql用户只在mysql RDMMS中存在,并且在系统中不需要帐户或主目录;在unix环境中的mysql命令行客户机,默认采用当前灯笼的用户名连接服务器,不过可以通过--user参数来定义登陆的用户身份。
mysql> select host,password,user,delete_priv from user;
+-----------------------+----------+------+-------------+
| host | password | user | delete_priv |
+-----------------------+----------+------+-------------+
| localhost | | root | Y |
| localhost.localdomain | | root | Y |
| localhost.localdomain | | | N |
| localhost | | | N |
+-----------------------+----------+------+-------------+
4 rows in set (0.01 sec)
上表的表示root用户有删除所有mysql数据库中表的权利,在user表中定义的用户权限适用于mysql中的所有数据库。
二、db表和host表:
db表和host表组合使用可以控制用户可以访问的数据库和进行的操作。
mysql> desc db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
20 rows in set (0.01 sec) mysql> desc host;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
19 rows in set (0.01 sec)
mysql> select host,user,db from db where db='test';
+------+------+------+
| host | user | db |
+------+------+------+
| % | | test |
+------+------+------+
1 row in set (0.01 sec) mysql> select host,user,db from db where db='library';
Empty set (0.01 sec)
上例表明任意用户可以从任意主机访问test数据库。
如果db表中host字段为空,说明得到许可的主机列表将通过第三个表(host表)获得,在缺少host表时,如果希望相同的用户根据来自不同主机的连接有不同的权限,就需要在db表中为每个主机创建一个单独的记录,并且赋予相应的权限。当存在host表时,就可以在host表中设置不同的主机名,使之连接db表中个单独的表项(host字段为空),然后以每个主机为基础设置权限。当一个命名主机试图连接时,mysq将基于host表中对该主机设置的规则赋予这些权限。
三、tables_priv表和columns_priv表
在更新版本中的mysql中增加了两个额外的表:tables_priv和columns_priv。这些表允许数据库管理员分别限制在数据库中访问具体的表和一个表中的具体的列。
mysql> desc columns_priv;
+-------------+----------------------------------------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+-------------------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Column_name | char(64) | NO | PRI | | |
| Timestamp | timestamp | YES | | CURRENT_TIMESTAMP | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+----------------------------------------------+------+-----+-------------------+-------+
7 rows in set (0.01 sec) mysql> desc tables_priv;
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Grantor | char(77) | NO | MUL | | |
| Timestamp | timestamp | YES | | CURRENT_TIMESTAMP | |
| Table_priv | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') | NO | | | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
8 rows in set (0.00 sec)
四、授权表之间的关系
mysql对具体用户和动作申请的控制可以作用在两个阶段:连接阶段和申请阶段。
* 连接阶段。
当用户通过具体主机申请于数据库服务器的一次连接时,mysql首先坚持此用户在user表中是否存在这个表项,用户口令是否正确,并且此用户是否得到许可可以通过该主机连接。如上诉条件符合则允许建立连接。
* 申请阶段。
一旦用户的连接建立成功,用户对数据的操作(select,delete,update等)还要有对应的权限才能得到执行。
当mysql服务器接收到一个连接请求时,首先匹配user授权表,若没有匹配的规则,则匹配db表和host表。若还没有匹配的规则则拒绝访问,若匹配到了正确的规则,则允许进行连接。当用户要执行管理活动方面的申请时,用户只需要匹配user表就可以了,因为管理活动是是针对于整个数据库而不是某个确定的数据库或表。
五、授权、废除和浏览用户权限
在mysql中修改授权表,需要是能够访问到数据库服务器的超级用户。修改授权表时可以使用insert,update,delete语句,也可以用grant和revoke语句,相比来说第二种方法要优于第一种。
1 使用grant和revoke命令
语法格式:
grant privilege (field_name,field_name,…),privilege (field_name,field_name,…)…on database_name.table_name to user@domain identified by password,user@domain identified by password,…
revoke privilege (field_name,field_name,…),privilege (field_name,field_name,…)…on database_name.table_name from user@domain identified by password,user@domain identified by password,…
mysql> use mysql
Database changed
mysql> grant select,update on library.data to wangbinde@localhostidentified by 'wangbinde';
Query OK, 0 rows affected (0.02 sec) 在数据库和表中,mysql允许使用通配符,接下来的查询赋予主机名为为localdomain上的用户wang在所有数据库上的所有权限。
mysql> grant all privileges on *.* to 'wang'@'localhost' identified by 'wang' with grant option;
mysql> revoke grant option on *.* from wang@localdomain;
Query OK, 0 rows affected (0.00 sec)
限制资源的使用:
通过user表中的max_quetions,max_updates,max_connections三个字段,可以用来分别现在具体用户每个小时内的查询、表或记录更新和新连接的数量。这三个字段可以在grant命令中形成三个选项语句。
第一个语句是max_queries_per_hour语句,用来限制用户每小时运行的查询数量,参考下面的示例:
mysql> grant select on *.* to wangbinde with max_queries_per_hour 5;
Query OK, 0 rows affected (0.00 sec)
上面示例中的max_queries_per_hour参数定义了每小时内不能超过5次,包括select,insert,update,delete等所有类型的查询
mysql> grant select on *.* to wangbinde with max_updates_per_hour 5;
Query OK, 0 rows affected (0.00 sec)
上面示例定义了对数据库修改次数的限制
mysql> grant select on *.* to wangbinde with max_connections_per_hour 3;
Query OK, 0 rows affected (0.01 sec)
上面这条语句定义了每小时打开新连接的数量。当然也可以把上面的语句组合成一条语句,如下所示:
mysql> grant select,insert,update,delete on *.*
-> to wang with max_queries_per_hour 50 max_updates_per_hour 10 max_connections_per_hour 4;
Query OK, 0 rows affected (0.00 sec)
用户以用户为单位有一个内部计数器,可以计算三种资源限制的每项要求。这些计数器可以使用新命令flush user_resources在任意时刻重置:
mysql> flush user_resources;
Query OK, 0 rows affected (0.01 sec)
可以使用show grants命令浏览富裕具体用户的权限,使用用户名为变量,并显示该用户已经授予的所有权限列表。如下所示:
mysql> show grants for wangbinde;
+----------------------------------------------------------------------------------------------------------------------+
| Grants for wangbinde@% |
+----------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO 'wangbinde'@'%' WITH MAX_QUERIES_PER_HOUR 5 MAX_UPDATES_PER_HOUR 5 MAX_CONNECTIONS_PER_HOUR 3 |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> show grants for root;
ERROR 1141 (42000): There is no such grant defined for user 'root' on host '%'
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql的linux发布包中包括 一个名为mysqlaccess的脚本,可以用力生产一个具体用户访问等级和权限的报告,在系统中输入命令mysqlaccess --howto可以看到这个脚本的示例。
重载授权表
使用grant和revoke命令执行的授予或取消权限的动作可以立即被激活,而通过常规的sql语句进行的授权需要重载服务器才能生效,就是运行flush privileges命令(需要reload的权限才能运行flush命令)。
mysql在启动时就需要读取授权表,但是也可要求mysql 通过mysqladmin工具来重载授权表,命令如下:
[mysql@localhost ~]$ mysqladmin -u root reload
[mysql@localhost ~]$ mysql
改变root用户口令:
[mysql@localhost ~]$ mysqladmin -u root password '123123'
[mysql@localhost ~]$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[mysql@localhost ~]$ mysql -u root -p
Enter password:
忘记root口令是的处理方法:
[root@localhost data]# mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
[root@localhost data]# su - mysql
[mysql@localhost ~]$ /usr/local/mysql/bin/mysqld_safe --skip-grant-tables --skip
-networking &
[1] 3019
[mysql@localhost ~]$ Starting mysqld daemon with databases from /usr/local/mysql/var [mysql@localhost ~]$ mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.24a-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| library |
| mysql |
| test |
+--------------------+
4 rows in set (0.01 sec) mysql>
这样就可以绕过授权表,作为mysql根用户登陆到服务器,不需要输入口令,额外的参数--skip-networking选项告诉mysql不要监听tcp/ip的连接,并且保证不回在修改权限时在网络上被破解。下面的动作是修改root的口令:
mysql> use mysql
Database changed
mysql> update user set password=password('123123') where user='root';
Query OK, 1 row affected (0.04 sec)
Rows matched: 2 Changed: 1 Warnings: 0
下面的步骤就是关闭数据库,按照正常的方式启动。
mysql数据库安装成功后,数据库已经建好了test数据库和包含5个授权表的mysql数据库。
mysql> show tables from mysql;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| func |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| proc |
| procs_priv |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
17 rows in set (0.00 sec)
除了func表外(该表用于用户定义的功能),每个表都可以根据用户名,连接主机或申请的数据库来建立访问规则。
user表:
mysql> desc user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | | |
| x509_issuer | blob | NO | | | |
| x509_subject | blob | NO | | | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.01 sec) mysql> select host,user,password from user;
+-----------------------+------+----------+
| host | user | password |
+-----------------------+------+----------+
| localhost | root | |
| localhost.localdomain | root | |
| localhost.localdomain | | |
| localhost | | |
+-----------------------+------+----------+
4 rows in set (0.01 sec)
上表表示root用户可以从可以从localhost和localhost.localomain无需口令登陆mysql服务器。当然host可以是一个固定的ip。在windows和unix中,mysql用户与系统用户并不相同。mysql用户只在mysql RDMMS中存在,并且在系统中不需要帐户或主目录;在unix环境中的mysql命令行客户机,默认采用当前灯笼的用户名连接服务器,不过可以通过--user参数来定义登陆的用户身份。
mysql> select host,password,user,delete_priv from user;
+-----------------------+----------+------+-------------+
| host | password | user | delete_priv |
+-----------------------+----------+------+-------------+
| localhost | | root | Y |
| localhost.localdomain | | root | Y |
| localhost.localdomain | | | N |
| localhost | | | N |
+-----------------------+----------+------+-------------+
4 rows in set (0.01 sec)
上表的表示root用户有删除所有mysql数据库中表的权利,在user表中定义的用户权限适用于mysql中的所有数据库。
二、db表和host表:
db表和host表组合使用可以控制用户可以访问的数据库和进行的操作。
mysql> desc db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
20 rows in set (0.01 sec) mysql> desc host;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
19 rows in set (0.01 sec)
mysql> select host,user,db from db where db='test';
+------+------+------+
| host | user | db |
+------+------+------+
| % | | test |
+------+------+------+
1 row in set (0.01 sec) mysql> select host,user,db from db where db='library';
Empty set (0.01 sec)
上例表明任意用户可以从任意主机访问test数据库。
如果db表中host字段为空,说明得到许可的主机列表将通过第三个表(host表)获得,在缺少host表时,如果希望相同的用户根据来自不同主机的连接有不同的权限,就需要在db表中为每个主机创建一个单独的记录,并且赋予相应的权限。当存在host表时,就可以在host表中设置不同的主机名,使之连接db表中个单独的表项(host字段为空),然后以每个主机为基础设置权限。当一个命名主机试图连接时,mysq将基于host表中对该主机设置的规则赋予这些权限。
三、tables_priv表和columns_priv表
在更新版本中的mysql中增加了两个额外的表:tables_priv和columns_priv。这些表允许数据库管理员分别限制在数据库中访问具体的表和一个表中的具体的列。
mysql> desc columns_priv;
+-------------+----------------------------------------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+-------------------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Column_name | char(64) | NO | PRI | | |
| Timestamp | timestamp | YES | | CURRENT_TIMESTAMP | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+----------------------------------------------+------+-----+-------------------+-------+
7 rows in set (0.01 sec) mysql> desc tables_priv;
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Grantor | char(77) | NO | MUL | | |
| Timestamp | timestamp | YES | | CURRENT_TIMESTAMP | |
| Table_priv | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') | NO | | | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+-------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-------+
8 rows in set (0.00 sec)
四、授权表之间的关系
mysql对具体用户和动作申请的控制可以作用在两个阶段:连接阶段和申请阶段。
* 连接阶段。
当用户通过具体主机申请于数据库服务器的一次连接时,mysql首先坚持此用户在user表中是否存在这个表项,用户口令是否正确,并且此用户是否得到许可可以通过该主机连接。如上诉条件符合则允许建立连接。
* 申请阶段。
一旦用户的连接建立成功,用户对数据的操作(select,delete,update等)还要有对应的权限才能得到执行。
当mysql服务器接收到一个连接请求时,首先匹配user授权表,若没有匹配的规则,则匹配db表和host表。若还没有匹配的规则则拒绝访问,若匹配到了正确的规则,则允许进行连接。当用户要执行管理活动方面的申请时,用户只需要匹配user表就可以了,因为管理活动是是针对于整个数据库而不是某个确定的数据库或表。
五、授权、废除和浏览用户权限
在mysql中修改授权表,需要是能够访问到数据库服务器的超级用户。修改授权表时可以使用insert,update,delete语句,也可以用grant和revoke语句,相比来说第二种方法要优于第一种。
1 使用grant和revoke命令
语法格式:
grant privilege (field_name,field_name,…),privilege (field_name,field_name,…)…on database_name.table_name to user@domain identified by password,user@domain identified by password,…
revoke privilege (field_name,field_name,…),privilege (field_name,field_name,…)…on database_name.table_name from user@domain identified by password,user@domain identified by password,…
mysql> use mysql
Database changed
mysql> grant select,update on library.data to wangbinde@localhostidentified by 'wangbinde';
Query OK, 0 rows affected (0.02 sec) 在数据库和表中,mysql允许使用通配符,接下来的查询赋予主机名为为localdomain上的用户wang在所有数据库上的所有权限。
mysql> grant all privileges on *.* to 'wang'@'localhost' identified by 'wang' with grant option;
mysql> revoke grant option on *.* from wang@localdomain;
Query OK, 0 rows affected (0.00 sec)
限制资源的使用:
通过user表中的max_quetions,max_updates,max_connections三个字段,可以用来分别现在具体用户每个小时内的查询、表或记录更新和新连接的数量。这三个字段可以在grant命令中形成三个选项语句。
第一个语句是max_queries_per_hour语句,用来限制用户每小时运行的查询数量,参考下面的示例:
mysql> grant select on *.* to wangbinde with max_queries_per_hour 5;
Query OK, 0 rows affected (0.00 sec)
上面示例中的max_queries_per_hour参数定义了每小时内不能超过5次,包括select,insert,update,delete等所有类型的查询
mysql> grant select on *.* to wangbinde with max_updates_per_hour 5;
Query OK, 0 rows affected (0.00 sec)
上面示例定义了对数据库修改次数的限制
mysql> grant select on *.* to wangbinde with max_connections_per_hour 3;
Query OK, 0 rows affected (0.01 sec)
上面这条语句定义了每小时打开新连接的数量。当然也可以把上面的语句组合成一条语句,如下所示:
mysql> grant select,insert,update,delete on *.*
-> to wang with max_queries_per_hour 50 max_updates_per_hour 10 max_connections_per_hour 4;
Query OK, 0 rows affected (0.00 sec)
用户以用户为单位有一个内部计数器,可以计算三种资源限制的每项要求。这些计数器可以使用新命令flush user_resources在任意时刻重置:
mysql> flush user_resources;
Query OK, 0 rows affected (0.01 sec)
可以使用show grants命令浏览富裕具体用户的权限,使用用户名为变量,并显示该用户已经授予的所有权限列表。如下所示:
mysql> show grants for wangbinde;
+----------------------------------------------------------------------------------------------------------------------+
| Grants for wangbinde@% |
+----------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO 'wangbinde'@'%' WITH MAX_QUERIES_PER_HOUR 5 MAX_UPDATES_PER_HOUR 5 MAX_CONNECTIONS_PER_HOUR 3 |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> show grants for root;
ERROR 1141 (42000): There is no such grant defined for user 'root' on host '%'
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql的linux发布包中包括 一个名为mysqlaccess的脚本,可以用力生产一个具体用户访问等级和权限的报告,在系统中输入命令mysqlaccess --howto可以看到这个脚本的示例。
重载授权表
使用grant和revoke命令执行的授予或取消权限的动作可以立即被激活,而通过常规的sql语句进行的授权需要重载服务器才能生效,就是运行flush privileges命令(需要reload的权限才能运行flush命令)。
mysql在启动时就需要读取授权表,但是也可要求mysql 通过mysqladmin工具来重载授权表,命令如下:
[mysql@localhost ~]$ mysqladmin -u root reload
[mysql@localhost ~]$ mysql
改变root用户口令:
[mysql@localhost ~]$ mysqladmin -u root password '123123'
[mysql@localhost ~]$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[mysql@localhost ~]$ mysql -u root -p
Enter password:
忘记root口令是的处理方法:
[root@localhost data]# mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
[root@localhost data]# su - mysql
[mysql@localhost ~]$ /usr/local/mysql/bin/mysqld_safe --skip-grant-tables --skip
-networking &
[1] 3019
[mysql@localhost ~]$ Starting mysqld daemon with databases from /usr/local/mysql/var [mysql@localhost ~]$ mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.24a-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| library |
| mysql |
| test |
+--------------------+
4 rows in set (0.01 sec) mysql>
这样就可以绕过授权表,作为mysql根用户登陆到服务器,不需要输入口令,额外的参数--skip-networking选项告诉mysql不要监听tcp/ip的连接,并且保证不回在修改权限时在网络上被破解。下面的动作是修改root的口令:
mysql> use mysql
Database changed
mysql> update user set password=password('123123') where user='root';
Query OK, 1 row affected (0.04 sec)
Rows matched: 2 Changed: 1 Warnings: 0
下面的步骤就是关闭数据库,按照正常的方式启动。
相关阅读 更多 +