MySQL访问权限系统和访问控制

6.1一般安全问题
6.1.1安全指南 
     运行MySQL时,请遵循以下准则:
     (1)不要给任何人(MySQL root帐户除外 )访问 数据库中的 user表mysql!这是至关重要的。
    (2)了解MySQL访问权限系统的工作原理(参见 第6.2节“MySQL访问权限系统”)。使用 GRANTand REVOKE语句来控制对MySQL的访问。不 要授予比必要更多的权限。不要授予所有主机的权限。使用该SHOW GRANTS 语句来检查哪些帐户可以访问什么。然后使用该REVOKE 语句删除不必要的那些权限。
     (3)尝试mysql -u root。如果您能够成功连接到服务器而不需要输入密码,任何人都可以作为MySQL root用户以完全权限连接到MySQL服务 器!
     (4)不要在您的数据库中存储明文密码。如果您的计算机遭到入侵,入侵者可以获取完整的密码列表并使用它们.
     (5)MySQL默认使用端口3306。不能从不受信任的主机访问此端口。作为检查您的MySQL端口是否打开的简单方法,请尝试从一些远程计算机        执行以下命令,server_host运行MySQL服务器的主机名或IP地址在哪里:
        shell> telnet server_host 3306
        如果telnet挂起或连接被拒绝,端口被阻止,这是你想要的。如果您获得连接和一些垃圾字符,端口是打开的,并且应该在防火墙或路由器上关闭,除非您确实有很好的理由
保持打开状态.
     (6)不要通过互联网传输普通(未加密)的数据。每个有时间和能力拦截它并将其用于自己目的的人都可以访问这些信息。而是使用SSL或        SSH等加密协议。MySQL支持内部SSL连接。另一种技术是使用SSH端口转发为通信创建一个加密(和压缩的)隧道。但是加密传输数据会        加大开销,请综合考虑。

6.1.2保密密码
      6.1.2.1最终用户密码安全指南
             当您运行客户端程序以连接到MySQL服务器时,以不公开的方式指定您的密码是不合适的,以供其他用户发现。在运行客户端程序 时可以使用用于指定密码的方法,以及对每种方法的风险进行评估。简而言之,最安全的方法是使客户端程序提示输入密码,或 者在正确保护的选项文件中指定密码。
             不安全的方式1:给出明文密码,如下命令:
             
             shell> mysql -u francis -pfrank db_name
             很方便但不安全。在某些系统上,您的密码对系统状态程序(例如可能由其他用户调用以显示命令行的ps)可见。MySQL客户端通常在初始化序列期间用零覆盖命令行密码参数。然而,仍然有一段短暂的时间间隔,值是可见的。此外,在某些系统上,这种覆 盖策略是无效的,密码对于ps是可见的。
             
             不安全的方式2:  
             将您的密码存储在MYSQL_PWD 环境变量中             
             这种指定您的MySQL密码的方法必须被认为是非常不安全的,不应该被使用。ps的某些版本 包括显示运行进程环境的选项。在某些系统上,如果设置 MYSQL_PWD,
您的密码将暴露给运行ps的任何其他用户。

             安全方式1:如下:
             在命令行上 使用-p或--password选项不指定密码值。在这种情况下,客户端程序以交互方式请求密码:
             shell> mysql -u francis -p db_name
             Enter password: ********
             该*字符显示在您输入密码。输入密码时不显示密码。以这种方式输入密码比在其他用户看不到命令​​行更安全。
             
             安全方式2:如下:
             将您的密码存储在选项文件中。例如,在Unix上,您可以在主目录[client]中的.my.cnf文件部分 列出您的密码 :
             [client]
              password=your_pass
             为了保证密码的安全,除了你以外,任何人都不应该访问该文件。为了确保这一点,将文件访问模式设置为400或600。例如:
             shell> chmod 600 .my.cnf
             
             如果您的命令解释器配置为维护历史记录,则保存命令的任何文件将包含在命令行中输入的MySQL密码。例如, bash使用  ~/.bash_history。任何此类文
件应具有限制性访问模式。

      6.1.2.2密码安全管理员指南
              数据库管理员应使用以下准则来保护密码安全。
              (1)MySQL存储mysql.user表中用户帐户的密码 。不得将访问此表的权限授予任何非管理性帐户。
              (2)帐户密码可以过期,以便用户必须重置它们.
              (3)该validate_password插件可用于对可接受的密码执行策略.
              (4)应该保护可能写入密码的日志文件等文件.
              
      6.1.2.3密码和记录
             (1)口令可以写在SQL语句,如纯文本 CREATE USER, GRANT,SET PASSWORD,和语句调用该 PASSWORD()函数。如果MySQL服务器
                以这样的方式记录这些语句,则其中的密码对于访问日志的任何人都可以看到。
               在MySQL 5.7中,语句记录避免了以下语句以明文形式写入密码:
               CREATE USER ... IDENTIFIED BY ...
               ALTER USER ... IDENTIFIED BY ...
               GRANT ... IDENTIFIED BY ...
               SET PASSWORD ...
               SLAVE START ... PASSWORD = ...
               CREATE SERVER ... OPTIONS(... PASSWORD ...)
               ALTER SERVER ... OPTIONS(... PASSWORD ...)
               这些语句中的密码将重写为不会直接写入写入常规查询日志,慢查询日志和二进制日志的语句文本中。重写不适用于其他声明              
               (2)INSERT或者 表中引用文字密码的UPDATE语句 mysql.user是按原样记录的,所以你应该避免这样的语句。(无论如何不​​鼓
                   励直接操纵授权表),容易造成错误,忘记加 where条件。导致把user表的用户全部密码一次更改。
      
               (3)对于常规查询日志,可以通过启动具有该--log-raw选项的服务器来抑制密码重写 。出于安全考虑,此选项不建议用于生产
               使用。
               (4)密码重写仅在预期使用纯文本密码时进行。对于具有期望密码哈希值的语法的语句,不会发生重写。如果这种语法错误地提
                 供纯文本密码,则密码将按照给定的方式进行记录,无需重写。例如,如下所示,记录以下语句,因为可能需要输入密码哈希值:
                 CREATE USER 'user1'@'localhost' IDENTIFIED BY PASSWORD 'not-so-secret';
                 要防范日志文件遭到无理曝光,请将它们放在限制对服务器和数据库管理员的访问的目录中。如果服务器记录到 mysql数据库中
                 的表,则只将这些表的访问权限授予数据库管理员
6.1.2.4 MySQL中的密码哈希


6.1.3使MySQL安全对抗攻击者
当您连接到MySQL服务器时,您应该使用密码。通过连接不会以明文形式发送密码。客户端连接顺序中的密码处理在MySQL 4.1.1中升级到非常安全。
如果您仍然使用4.1.1之前的密码,则加密算法不如新算法那么强。通过一些努力,可以嗅探客户端和服务器之间的流量的聪明的攻击者可以破解密码
.如果客户端和服务器之间的连接通过不受信任的网络,并且您担心这一点,您可以使用压缩协议使流量更难以解密。您还可以使用MySQL的内部SSL支
持来使连接更加安全.
要使MySQL系统安全,您应该强烈地考虑以下建议:
(1)要求所有MySQL帐户都有密
(2)确保在数据库目录中具有读取或写入权限的唯一的Unix用户帐户是用于运行mysqld的帐户
(3)不要以Unix root 用户身份运行MySQL服务器。这是非常危险的,因为具有该FILE权限的任何用户 都能够使服务器创建文件root(例如~root/.bashrc)
   。为了防止这种情况, mysqld拒绝运行, root除非使用该--user=root选项明确指定.要将 mysqld作为不同的Unix用户启动,请添加一个user选
   项,[mysqld]该my.cnf选项指定在您指定服务器选项的选项文件组中的 用户名。例如:
   [mysqld]
   user=mysql
(4)不授予FILE非管理用户的权限。具有此权限的任何用户都可以使用mysqld守护程序的权限在文件系统中的任何位置写入文件.
(5)不给予非管理用户PROCESS或 SUPER特权。
(6)不允许使用符号链接到表格。(此功能可通过禁用 --skip-symbolic-links 选项。)
(7)如果您不信任您的DNS,则应在授权表中使用IP地址而不是主机名。无论如何,您应该非常小心使用包含通配符的主机名值创建授权表条目。
(8)如果要限制单个帐户允许的连接数量,可以通过设置mysqld中的 max_user_connections变量来实现。该 声明还支持资源控制选项,用于限制允
许用于帐户的服务器使用范围


6.1.4安全性相关的mysqld选项和变量
Table 6.1 Security Option/Variable Summary

Name Cmd-Line Option File System Var Status Var Var Scope Dynamic
allow-suspicious-udfs Yes Yes  
automatic_sp_privileges Yes Global Yes
chroot Yes Yes  
des-key-file Yes Yes  
local_infile Yes Global Yes
old_passwords Yes Both Yes
safe-user-create Yes Yes  
secure-auth Yes Yes Global Yes
- Variable: secure_auth Yes Global Yes
secure-file-priv Yes Yes Global No
- Variable: secure_file_priv Yes Global No
skip-grant-tables Yes Yes  
skip-name-resolve Yes Yes Global No
- Variable: skip_name_resolve Yes Global No
skip-networking Yes Yes Global No
- Variable: skip_networking Yes Global No
skip-show-database Yes Yes Global No
- Variable: skip_show_database Yes Global No


6.1.5如何以正常用户身份运行MySQL
在Unix(或使用taror tar.gzpackages的Linux安装 )中,MySQL服务器mysqld可以由任何用户启动和运行。但是,root出于安全考虑,您应该避免以Unix 用户身份运行服务器。要将mysqld更改为正常的非特权Unix用户运行user_name,您必须执行以下操作:
停止服务器,如果它正在运行(使用mysqladmin shutdown)
更改数据库目录和文件,以便 user_name具有读取和写入文件的权限(您可能需要以Unix root用户身份执行此 操作):
shell> chown -R user_name /path/to/mysql/datadir
如果不这样做,服务器在运行时将无法访问数据库或表 user_name。
如果MySQL数据目录中的目录或文件是符号链接,则chown -R可能不会遵循符号链接。如果没有,您还需要遵循这些链接并更改他们指向的目录和文件。
以用户身份启动服务器user_name。另一个选择是启动mysqld作为Unix root用户并使用该 选项。mysqld启动,然后 在接受任何连接之前切换到作为Unix用户运行。 --
user=user_nameuser_name
要在系统启动时自动将服务器作为给定用户启动,请通过向选项文件组或服务器数据目录中的 选项文件 添加user选项来 指定用户名 。例如: [mysqld]/etc/my.cnfmy.cnf
[mysqld]
user=user_name
如果您的Unix机器本身没有安全,您应该root在授权表中为MySQL 帐户分配密码。否则,在该机器上具有登录帐户的任何用户都可以使用选项运行mysql客户端 --user=root
并执行任何操作。(在任何情况下,将密码分配给MySQL帐户是个好主意,尤其是在服务器主机上存在其他登录帐户时)。请参见 第2.10.4节“保护初始MySQL帐户”。



6.1.6 LOAD DATA LOCAL的安全问题
为避免LOAD DATA问题,客户应避免使用LOCAL。为了避免连接到不受信任的服务器,客户端可以建立安全连接,并使用--ssl-mode=VERIFY_IDENTIFY选项和相应的CA证书进行连接来验证服务器身份 。
为了使管理员和应用程序能够管理本地数据加载功能,LOCAL配置如下:
在服务器端:
所述local_infile系统变量控制服务器端LOCAL 的能力。根据 local_infile设置,服务器拒绝或允许LOCAL在客户端启用的客户端的本地数据加载。默认情况下, local_infile启用。
要明确导致服务器拒绝或允许 LOAD DATA LOCAL语句(不论如何客户程序和库在构建时或运行时配置),启动mysqld的与 local_infile分别禁用或启用。 local_infile也可以在运行时设置。
在客户端:
对于mysql客户端,默认情况下禁用本地数据加载。要明确禁用或启用它,请使用 --local-infile=0或 --local-infile[=1]选项。
对于mysqlimport客户端,默认情况下禁用本地数据加载。要明确禁用或启用它,请使用 --local=0或 --local[=1]选项。
如果您LOAD DATA LOCAL在Perl脚本或[client]从选项文件读取组的其他程序中使用,则可以向该组添加 local-infile选项设置。为了防止不了解此选项的程序出现问题,请使用loose- 前缀
指定 :
[client]
loose-local-infile=0
要么:
[client]
loose-local-infile=1
在所有情况下,LOCAL 客户端成功使用加载操作也要求服务器允许。
如果LOCAL能力被禁用,在服务器或客户端上,尝试发出LOAD DATA LOCAL语句的客户端将 收到以下错误消息:
ERROR 1148: The used command is not allowed with this MySQL version



6.2 MySQL访问特权系统
当您运行连接到服务器的客户端程序时,MySQL访问控制涉及两个阶段:
阶段1:服务器根据您的身份接受或拒绝连接,以及是否可以通过提供正确的密码来验证您的身份。
阶段2:假设您可以连接,服务器将检查您发出的每个语句,以确定您是否具有足够的权限来执行它。例如,如果您尝试从数据库中的表中选择行或从数据库中删除表,则服务器将验证您是否具有 SELECT表的DROP特权或数据库的 权限
MySQL权限系统的主要功能是验证谁从给定主机连接用户,并与特权用户数据库如联想 SELECT, INSERT, UPDATE,和 DELETE。附加功能包括具有匿名用户和授予特定于MySQL的功能(如LOAD DATA INFILE管理操作)的权限 


6.2.1 MySQL提供的特权
6.2.2授权表
授予MySQL帐户的特权决定了该帐户可以执行的操作。MySQL权限在其应用的上下文和不同操作级别上有所不同:
管理权限使用户能够管理MySQL服务器的操作。这些权限是全局的,因为它们不是特定于特定数据库的。
数据库权限适用于数据库及其中的所有对象。可以为特定数据库或全局授予这些权限,以便它们适用于所有数据库。
可以为数据库中的特定对象(数据库中的给定类型的所有对象(例如数据库中的所有表))或全局的所有对象为数据库对象(例如表,索引,视图和存储例程)授予特​​权所有数据库中给定类型的对象)。
有关帐户权限的信息存储在 user,db, tables_priv,columns_priv,和procs_priv在表 mysql系统数据库.
Table 6.2 Permissible Privileges for GRANT and REVOKE


Privilege        Column                   Context
ALL [PRIVILEGES] Synonym for “all privileges” Server administration
ALTER             Alter_priv Tables
ALTER ROUTINE        Alter_routine_priv Stored routines
CREATE   Create_priv Databases, tables, or indexes
CREATE ROUTINE Create_routine_priv Stored routines
CREATE TABLESPACE Create_tablespace_priv Server administration
CREATE TEMPORARY TABLES Create_tmp_table_priv Tables
CREATE USER Create_user_priv Server administration
CREATE VIEW Create_view_priv Views
DELETE Delete_priv Tables
DROP Drop_priv Databases, tables, or views
EVENT Event_priv Databases
EXECUTE Execute_priv Stored routines
FILE File_priv File access on server host
GRANT OPTION Grant_priv Databases, tables, or stored routines
INDEX Index_priv Tables
INSERT Insert_priv Tables or columns
LOCK TABLES Lock_tables_priv Databases
PROCESS Process_priv Server administration
PROXY See proxies_priv table Server administration
REFERENCES References_priv Databases or tables
RELOAD Reload_priv Server administration
REPLICATION CLIENT Repl_client_priv Server administration
REPLICATION SLAVE Repl_slave_priv Server administration
SELECT Select_priv Tables or columns
SHOW DATABASES Show_db_priv Server administration
SHOW VIEW Show_view_priv Views
SHUTDOWN Shutdown_priv Server administration
SUPER Super_priv Server administration
TRIGGER Trigger_priv Tables
UPDATE Update_priv Tables or columns
USAGE Synonym for “no privileges” Server administration
以下列表提供了MySQL中可用权限的一般说明。特定的SQL语句可能具有比此处指示的更特定的权限要求。如果是这样,有关陈述的描述提供了细节。
该ALL或 ALL PRIVILEGES 权限说明符的简写。它代表“ 给定权限级别可用的所有权限 ” (除外GRANT OPTION)。例如,ALL在全局或表级授予授予所有全局权限或所有表级权限。
该ALTER权限允许使用该ALTER TABLE语句来更改表的结构。ALTER TABLE还要求 CREATE和 INSERT特权。重命名表需要ALTER和 DROP对旧表, CREATE以及 INSERT对新表。
ALTER ROUTINE需要 该权限来更改或删除存储的例程(过程和函数)。
该CREATE权限允许创建新的数据库和表。
将CREATE ROUTINE需要的权限来创建存储例程(过程和函数)。
CREATE TABLESPACE创建,更改或删除表空间和日志文件组需要 该权限。
该CREATE TEMPORARY TABLES 权限允许使用该CREATE TEMPORARY TABLE 语句创建临时表 。
会话创建了一个临时表后,服务器不会对该表进行进一步的特权检查。所述创建会话可以在桌子上进行任何操作,例如DROP TABLE, INSERT, UPDATE,或 SELECT。有关详细信息,请参见

第13.1.18.3节“CREATE TEMPORARY TABLE语法”。
该CREATE USER权限允许使用的ALTER USER, CREATE USER, DROP USER, RENAME USER,和 REVOKE ALL PRIVILEGES语句。
该CREATE VIEW权限允许使用该CREATE VIEW 语句。
该DELETE特权使行从数据库中的表被删除。
该DROP特权使您能够删除(删除)现有的数据库,表和视图。DROP为了ALTER TABLE ... DROP PARTITION在分区表上使用该语句,需要该 权限。该 DROP也需要特权TRUNCATE TABLE。 如果授予DROP 的特权mysql数据库用户,该用户可以删除其中的MySQL访问权限被存储在数据库中。
EVENT需要 该权限来创建,更改,删除或查看事件计划程序的事件。
EXECUTE需要执行存储例程(过程和函数) 的权限。
该FILE权限允许您使用LOAD DATA INFILE和 SELECT ... INTO OUTFILE语句和 LOAD_FILE()函数在服务器主机上读取和写入文件。具有该FILE权限的用户可以读取服务器主机上任何可由MySQL
服务器读取或读取的文件。(这意味着用户可以读取任何数据库目录中的任何文件,因为服务器可以访问任何这些文件。)该 FILE权限还使用户能够在MySQL服务器具有写入权限的任何目录中

创建新文件。这包括服务器的数据目录,其中包含实现权限表的文件。作为安全措施, 服务器将不会覆盖现有文件。FILE从MySQL 5.7.17开始,该权限需要使用DATA DIRECTORY或者INDEX DIRECTORY表选项来使用该 CREATE TABLE语句。
要限制可以读取和写入文件的位置,请将secure_file_priv 系统设置为特定的目录。请参见 第5.1.5节“服务器系统变量”。
该GRANT OPTION权限使您能够给予其他用户或从其他用户删除您拥有的这些权限。
该INDEX权限使您可以创建或删除(删除)索引。 INDEX适用于现有表。如果您具有CREATE 表的特权,则可以在CREATE TABLE语句中包含索引定义。
该INSERT权限允许将行插入到数据库中的表中。 INSERT还需要对 ANALYZE TABLE, OPTIMIZE TABLE和 REPAIR TABLE表维护语句。
该LOCK TABLES权限允许使用显式LOCK TABLES语句来锁定具有该SELECT权限的表。这包括使用写锁,这阻止其他会话读取锁定表。
该PROCESS权限属于显示有关在服务器中执行的线程的信息(即有关会话执行的语句的信息)。该权限允许使用 SHOW PROCESSLIST或 mysqladmin进程列表来查看属于其他帐户的线程; 你可以随时看到你自己的线程。该PROCESS权限还允许使用的SHOW ENGINE。
该PROXY权限使用户能够模拟或被称为另一用户。请参阅 第6.3.10节“代理用户”。
该REFERENCES权限在MySQL 5.7.6之前未使用。从5.7.6开始,创建外键约束需要REFERENCES父表的 权限。
该RELOAD权限允许使用该FLUSH语句。这也使中mysqladmin等效于命令FLUSH操作: flush-hosts,flush-logs, flush-privileges, flush-status, flush-tables, flush-threads,refresh,和reload。该reload命令告诉服务器将授权表重新加载到内存中。 flush-privileges是同义词 reload。该refresh 命令关闭并重新打开日志文件并刷新所有表。其他 命令执行类似于但更具体的功能 ,并且在某些情况下可能是优选的。例如,如果要仅仅刷新日志文件,是一个更好的选择。 flush-xxxrefreshflush-logsrefresh
该REPLICATION CLIENT 权限允许使用的SHOW MASTER STATUS,SHOW SLAVE STATUS和SHOW BINARY LOGS语句。
REPLICATION SLAVE应授予从属服务器用于连接到当前服务器作为主服务器的帐户 的权限。没有此权限,从站不能请求对主服务器上的数据库进行的更新。
该SELECT特权使您能够从数据库中的表中选择行。 SELECT语句SELECT只有在实际从表中检索行时才需要该 权限。一些 SELECT语句不访问表,可以在没有任何数据库的权限的情况下执行。例

如,您可以使用 SELECT简单的计算器来评估不引用表的表达式:
SELECT 1+1;
SELECT PI()*2;
SELECT读取列值的其他语句也需要 该权限。例如,对于 在statement中SELECT的col_name= exprassignment UPDATE或者在or 语句的WHERE子句中 指定的列,右侧所引用的列是需要的 。 
DELETEUPDATE
在SELECT还需要用于被与用于表或视图特权 EXPLAIN,包括视图任何基础表。
该SHOW DATABASES权限使帐户能够通过发出SHOW DATABASE语句来查看数据库名称 。没有此权限的帐户只能看到具有某些权限的数据库,如果服务器已启动该--skip-show-database选项,则无
法使用该语句 。请注意,任何全局权限都是数据库的特权。
该SHOW VIEW权限允许使用该SHOW CREATE VIEW 语句。与使用的视图也需要此权限EXPLAIN。
该SHUTDOWN权限允许使用该SHUTDOWN语句,mysqladmin shutdown命令和 mysql_shutdown()C API函数。
该SUPER权限使这些业务和服务器行为:
通过修改全局系统变量启用配置更改。对于某些系统变量,设置会话值也需要 SUPER特权; 如果是,则在变量描述中指示。实例包括 binlog_format, sql_log_bin,和 sql_log_off。
启用和停止从服务器上的复制,包括组复制。
使用CHANGE MASTER TO和CHANGE REPLICATION FILTER语句。
通过PURGE BINARY LOGS和 BINLOG语句启用二进制日志控制 。
启用执行视图或存储的程序时设置有效的授权ID。具有此权限的用户可以在DEFINER视图或存储的程序的属性中指定任何帐户 。
允许使用的CREATE SERVER,ALTER SERVER和DROP SERVER语句。
启用mysqladmin调试 命令。
启用InnoDB按键旋转。
启用该DES_ENCRYPT()功能读取DES密钥文件 。
启用版本令牌用户定义的功能。
可以控制不允许非SUPER帐户的客户端连接:
允许使用该KILL 语句或mysqladmin kill 命令来终止属于其他帐户的线程。(你可以随时杀死自己的线程。)
SUPER即使max_connections 达到由系统变量控制的连接限制 ,服务器也接受客户端的 一个连接 。
即使read_only启用了系统变量,也可以进行更新 。这适用于表更新和帐户管理语句的使用,例如 GRANT和 REVOKE。
客户端连接init_connect时 ,服务器不会执行 系统变量内容 SUPER。
离线模式(offline_mode 启用)的服务器不会SUPER在下一个客户端请求时终止 客户端连接,并接受来自SUPER客户端的新连接 。
SUPER 如第23.7节“存储程序的二进制日志记录”所述, 您可能还需要创建或更改存储函数的权限,如果启用 二进制日志记录。
该TRIGGER特权启用触发操作。您必须具有此表的权限才能创建,删除,执行或显示该表的触发器。
当触发器被激活(由谁拥有特权执行用户INSERT, UPDATE或 DELETE与触发器关联的表的语句),触发器执行要求谁定义触发器的用户仍然有 TRIGGER特权。

该UPDATE特权使排在数据库中的表进行更新。
该USAGE权限说明符表示“ 没有权限。“它在全球一级GRANT用于修改帐户属性,如资源限制或SSL特性,而无需命名特定帐户权限。 SHOW GRANTS显示 USAGE以指示帐户在特权级别没有权限。
这是一个好主意,只授予一个帐户所需的特权。在给予FILE和管理特权方面应特别小心:
该FILE权限可以被滥用来读取MySQL服务器可以在服务器主机上读取的任何文件的数据库表。这包括服务器数据目录中的所有世界可读的文件和文件。然后可以使用该表 SELECT将其内容传输到
客户端主机。

该GRANT OPTION权限使用户能够将权限授予其他用户。具有不同特权和特权的两个用户 GRANT OPTION可以组合权限。

的ALTER特权可以使用通过重命名表颠覆权限系统。

SHUTDOWN可以通过终止服务器 将特权滥用于完全拒绝其他用户的服务。

该PROCESS特权可用于查看当前正在执行的语句的纯文本,包括设置或更改密码的语句。

该SUPER权限可用于终止其他会话或更改服务器的运行方式。

授予mysql数据库本身的特权可用于更改密码和其他访问权限信息。密码存储加密,所以恶意用户不能简单地读取它们来了解纯文本密码。但是,具有对user表 authentication_string列的写

访问权限的用户 可以更改帐户的密码,然后使用该帐户连接到MySQL服务器。



6.2.2授权表
注意
using语句,如授权表的直接修改 INSERT, UPDATE或 DELETE不鼓励,并在您自行承担风险。服务器可以自由地忽略由于这种修改而导致格式错误的行
这些mysql数据库表包含授权信息:

user:用户帐户,全局权限和其他非特权列
db:数据库级特权
tables_priv:表级权限
columns_priv:列级权限
procs_priv:存储过程和功能特权
proxies_priv:代理用户权限
服务器以下列方式使用授权表:
的user表范围列确定是否拒绝或允许传入连接。对于允许的连接,user表中授予的任何权限 表示用户的全局权限。此表中授予的任何权限适用于 服务器上的所有数据库。

警告
因为任何全局特权都被视为所有数据库的特权,任何全局权限都可以让用户SHOW DATABASES通过检查 SCHEMATA表 来查看所有数据库名称INFORMATION_SCHEMA。

该db表范围列决定哪些用户可以访问哪些数据库从哪个主机。特权列决定允许的操作。在数据库级授予的权限适用于数据库和数据库中的所有对象,例如表和存储的程序。

在tables_priv与 columns_priv表类似于 db表,但是更精致:他们在申请表和列级应用而非在数据库级。在表级授予的权限适用于表及其所有列。在列级别授予的权限仅适用于特定列。
该procs_priv表适用于存储的例程(过程和函数)。在例程级别授予的权限仅适用于单个过程或函数。

该proxies_priv表指示哪些用户可以作为其他用户的代理,以及用户是否可以PROXY向其他用户授予权限。

服务器使用user与 db表中的mysql 在两个访问控制的第一和第二阶段的数据库(参见6.2节,“MySQL访问权限系统”)。中列 user和db表如下所示。
该user表plugin, Password和 authentication_string列存储身份验证插件和证书信息。在MySQL 5.7.6中,Password列已被删除,所有凭据都存储在 authentication_string列中。
password_last_changed通过更新 CREATE USER, ALTER USER和 SET PASSWORD报表,并通过 GRANT创造一个帐户或更改帐户密码的语句。
password_lifetime(添加在MySQL 5.7.4中)表示账户密码的生命周期,以天为单位。如果密码超过其使用寿命(使用password_last_changed列进行评估 ),则当客户端使用该帐户进行连接
时,服务器会认为密码已过期。的值N大于零意味着该密码必须在每次更改 N天。值为0会禁用自动密码到期。如果该值为NULL(默认值),则全局过期策略将按default_password_lifetime系
统变量定义 。
account_locked(添加在MySQL 5.7.6中)指示帐户是否被锁定(请参见 第6.3.11节“用户帐户锁定”)。
只有user表指定了管理权限,例如RELOAD和 SHUTDOWN。管理操作是服务器本身的操作,而不是数据库特定的,因此没有理由在其他授权表中列出这些权限。因此,服务器只需要查询 user表来
确定用户是否可以执行管理操作。
该FILE权限也仅在指定的user表。它不是这样的管理权限,但是用户在服务器主机上读取或写入文件的能力与被访问的数据库无关。
服务器启动时将授权表的内容读入内存。您可以通过发出FLUSH PRIVILEGES 语句或执行mysqladmin flush-privileges或mysqladmin reload 命令来告诉它重新加载表 。授权表的更改如第


6.2.6节“权限更改生效 时”所示。
当您修改帐户时,最好验证您的更改是否具有预期的效果。要检查给定帐户的权限,请使用该SHOW GRANTS 语句。例如,要确定与用户名和主机名值授予一个帐户的权限 bob和pc84.example.com使用下面的语句:
SHOW GRANTS FOR 'bob'@'pc84.example.com';
要显示帐户的非特权属性,请使用 SHOW CREATE USER:
SHOW CREATE USER 'bob'@'pc84.example.com'
6.2.3指定账号
MySQL帐号由用户名和主机名组成。这样可以为具有相同名称的用户创建可以从不同主机进行连接的帐户。本节介绍如何编写帐户名称,包括特殊值和通配符规则。
在SQL语句中,如和CREATE USER,GRANT和 SET PASSWORD帐号名称遵循以下规则:
帐号名称是 。 'user_name'@'host_name'
仅由用户名组成的帐户名称相当于 。例如,相当于 。 'user_name'@'%''me''me'@'%'
如果用户名和主机名合法,则不需要引用它们作为未引用的标识符。引用需要指定一个user_name包含特殊字符(如空格或-)的host_name字符串或包含特殊字符或通配符(如.或%)的字符串 
; 例如, 'test-user'@'%.com'。

使用反引号(`),单引号(')或双引号(")引用用户名和主机名作为标识符或字符串。有关字符串引用和标识符引用的指导原则,请参见 第9.1.1节“字符串文字”和 第9.2节“模式对象名称”。
用户名和主机名部分(如果引用)必须单独引用。那就是写 'me'@'localhost',而不是 'me@localhost'; 后者实际上相当于'me@localhost'@'%'。
对CURRENT_USER or或CURRENT_USER()函数的引用等效于从字面上指定当前客户端的用户名和主机名。
用户名和主机名具有一些特殊值或通配符约定,如下所述。
帐户名称的用户名部分是与入口连接尝试的用户名字面匹配的非空白值,或与任何用户名匹配的空白值(空字符串)。具有空白用户名的帐户是匿名用户。要在SQL语句中指定匿名用户,请使用引用的空用户名部分,例如''@'localhost'。
帐户名称的主机名称部分可以采用多种形式,允许使用通配符:
主机值可以是主机名或IP地址(IPv4或IPv6)。该名称'localhost'指示本地主机。IP地址'127.0.0.1' 表示IPv4环回接口。IP地址 '::1'表示IPv6环回接口。
在%和_通配符允许在主机名或IP地址的值。这些具有与LIKE运算符执行的模式匹配操作相同的含义。例如,主机值'%'匹配任何主机名,而一个值 '%.mysql.com'匹配mysql.com域中的任何主机 
。 '192.168.1.%'匹配192.168.1 C类网络中的任何主机。


6.2.4访问控制,阶段1:连接验证
当您尝试连接到MySQL服务器时,服务器会根据以下条件接受或拒绝连接:
您的身份,以及您是否可以通过提供正确的密码来验证您的身份
您的帐户是否被锁定或解锁
服务器首先检查凭据,然后检查帐户锁定状态。任一步骤的故障都会导致服务器完全拒绝对您的访问。否则,服务器接受连接,然后进入第二阶段并等待请求。
使用三个执行凭证检查 user表范围列(Host,User,和 authentication_string)。锁定状态记录在user表格 account_locked列中。服务器接受仅在连接Host和 User一些列的user 表行匹配
客户端主机名和用户名,客户端提供该行中指定的密码,和 account_locked值'N'。第6.2.3节“指定帐户名称”中给出了允许Host和 User值 的规则。帐号锁定可以用语句更改。 ALTER USER
如果User列值为非空,则传入连接中的用户名必须完全匹配。如果该 User值为空,它将匹配任何用户名
该authentication_string列可以为空。这不是通配符,并不意味着任何密码匹配
如果服务器使用插件验证客户端,则插件实现的身份验证方法可能会使用或不使用该authentication_string 列中的密码
特别是,不要让非管理用户读取mysql数据库中的表的访问权限 .
下表显示了表中各种组合User和Host值 如何 user适用于传入连接。


User 值 Host 值                允许连接
'fred' 'thomas.loc.gov' fred,连接 thomas.loc.gov
'' 'thomas.loc.gov' 任何用户,连接 thomas.loc.gov
'fred' '%'                fred,从任何主机连接
'' '%'                任何用户,从任何主机连接
'fred' '%.loc.gov'        fred,从loc.gov域中的任何主机连接
'fred' 'x.y.%'                fred,从连接x.y.net, x.y.com,x.y.edu,等; 这可能没有用
'fred' '192.168.10.177' fred,从主机与IP地址进行连接 192.168.10.177
'fred' '192.168.10.%'   fred,从192.168.10C类子网中的任何主机连接
'fred' '192.168.10.0/255.255.255.0' 与上一个例子相同

如果您能够连接到服务器,但是您的权限不是您期望的,那么您可能会被认证为其他帐户。要了解服务器用于验证您的帐户,请使用该 CURRENT_USER()功能。(请参见 第12.14节“信息函数
”。)它返回一个 格式的值 ,表示匹配表行中的值和 值 。假设 连接并发出以下查询: user_name@host_nameUserHostuserjeffrey

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+
此处显示的结果表示匹配的 user表行具有空白 User列值。换句话说,服务器被jeffrey视为匿名用户




6.2.5访问控制,阶段2:请求验证
建立连接后,服务器进入访问控制阶段2。对于通过该连接发出的每个请求,服务器确定要执行的操作,然后检查您是否具有足够的权限。这是授权表中的特权列发挥作用的地方。这些权限可
以来自任何的 user,db, tables_priv,columns_priv,或procs_priv表。(您可能会发现参考6.2.2节“授予表”,其中列出了每个授权表中存在的列。)
该user表授予全局分配给您的权限,无论默认数据库是什么,它都适用。例如,如果 user表授予您 DELETE权限,则可以从服务器主机上的任何数据库中的任何表中删除行!将user表中的权限
授予只需要用户的权限(如数据库管理员)是明智之举。对于其他用户,您应该将user表中的所有权限 设置为'N'并仅在更特定级别授予权限。您可以授予特定数据库,表,列或例程的权限。
服务器将db表读入内存并在读取user表的同时进行排序 。服务器排序 db基于表Host, Db和User范围列。与user表一样,排序最先列出最具体的值,最小值最小,当服务器查找匹配的行时,

它将使用它找到的第一个匹配项。
服务器使用排序表来验证其接收的每个请求。对于需要管理权限,如请求SHUTDOWN或者 RELOAD,服务器仅检查 user表行,因为这是指定管理权限的唯一表。如果该行允许请求的操作并拒绝其
他访问,服务器将授予访问权限。例如,如果要执行mysqladmin shutdown,但是您的user表行不会SHUTDOWN向您授予权限,则服务器即使检查该db表也会拒绝访问 。(它不包含 
Shutdown_priv列,所以没有必要这样做。)
对于数据库相关请求(INSERT, UPDATE等等),服务器首先通过查看user表行来检查用户的全局权限 。如果行允许请求的操作,则允许访问。如果user表中的全局权限不足,则服务器通过检


查db表来确定用户的特定于数据库的权限 :


该服务器会在db表上的匹配Host,Db以及 User列。在Host与 User列对应连接用户的主机名和MySQL用户名。该Db 列与用户想要访问的数据库相匹配。如果没有排为Host和 User,访问被拒绝。
在确定db表行授予的数据库特定权限后 ,服务器将其添加到user表授予的全局权限。如果结果允许请求的操作,则允许访问。否则,服务器依次检查tables_priv和 columns_priv表中的用户

的表和列权限,将其添加到用户的权限,并根据结果允许或拒绝访问。对于存储例程操作,服务器使用 procs_priv表而不是 tables_priv和 columns_priv。
以布尔值表示,上述用户权限计算方式的描述可以总结如下:
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
OR routine privileges


6.2.6特权更改生效时
当mysqld启动时,它会将所有授权表内容读入内存。内存中的表在此时对访问控制有效。
如果你修改授权表间接使用账户管理语句,如GRANT, REVOKE,SET PASSWORD,或RENAME USER,服务器注意到这些变化,并立即再次加载授权表到内存中。
如果你修改授权表直接使用的语句,例如 INSERT, UPDATE或者 DELETE,你的变化对特权的效果检查,直到你重新启动服务器或告诉它重新加载表。如果您直接更改授权表,但忘记重新加载它们,则在重新启动服务器之前,更改将不起作用。这可能会让你想知道为什么你的改变似乎没有什么区别!
要告诉服务器重新载入授权表,请执行flush-privileges操作。这可以通过发出 FLUSH PRIVILEGES 语句或执行mysqladmin flush-privileges或mysqladmin reload 命令来完成。授权表重新加载会影响每个现有客户端连接的权限,如下所示:
表和列权限更改将随客户端的下一个请求生效。
数据库特权更改在客户端下次执行语句时生效。 USE db_name

注意
客户端应用程序可能会缓存数据库名称; 因此,在没有实际改变到不同的数据库的情况下,这种效果可能不可见。
全局权限和密码不受连接客户端的影响。这些更改仅对后续连接生效。
如果服务器使用该--skip-grant-tables选项启动 ,则它不会读取授权表或实现任何访问​​控制。任何人都可以连接和做任何事情,这是不安全的。为了使服务器开始读取表并启用访问检查,请
刷新权限。
检查以确保没有防火墙阻止访问MySQL
授权表必须正确设置,以便服务器可以使用它们进行访问控制
如果您使用SET PASSWORD,INSERT或 更改密码UPDATE,则必须使用该PASSWORD() 功能对密码进行加密。如果您不使用 PASSWORD()这些语句,密码将无法正常工作。例如,以下语句分配密码
,但无法对其进行加密,因此用户以后无法连接:
SET PASSWORD FOR 'abe'@'host_name' = 'eagle';
而是像这样设置密码:
SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');
PASSWORD()当使用CREATE USERor GRANT语句或 mysqladmin password命令指定密码时, 该函数是不必要的 。每个都会自动使用PASSWORD() 密码加密
localhost 是您的本地主机名的同义词,如果您没有明确指定主机,那么也是客户端尝试连接的默认主机。

6.2.7连接MySQL时出现问题的疑难解答

你可能感兴趣的:(MYSQL安全服务器引擎)