《MySQL技术》学习笔记——安全性与访问控制

安全性与访问控制

保护对MySQL文件系统的访问

如何窃取数据

  • (1)在服务器主机上安装一个自己的"流氓"MySQL服务器,使用与官方服务器不同的端口,套接字文件和数据目录。
  • (2)运行mysql_install_db,初始化数据目录。
    此动作可让你以MySQL的root用户身份访问你的服务器,建立一个test数据库,用于存储窃取到的表。
  • (3)访问你想攻击的服务器的数据目录,将想窃取的表对应的文件复制到你自己那个服务器数据目录下的test目录。
  • (4)启动流氓服务器。
    可通过SQL访问复制表的信息。
  • (5)对"流氓"数据库不设权限。
    外部用户通过"流氓"数据库来访问本无权限访问的内容

保护MySQL安装

  • (1)停止MySQL服务器
% mysqladmin -p -u root shutdown
  • (2)用以下命令,把整个MySQL安装的所有者和组名设为MySQL管理账户。
# chown -R mysql /usr/local/mysql
# chgrp -R mysql /usr/local/mysql
  • (3)对客户端应能访问的基本目录及其子目录,需更改它们的模式,以便mysql拥有其全部权限.而其他人只有其读取和执行权限。
  • (4)更改数据目录及其下面所有文件和子目录的访问模式,只允许mysql用户访问它们。
% chmod -R go-rwx /usr/local/mysql/data
[mysqld]
user=mysql

可以让以root身份执行服务器程序时,自动切换为mysql身份来执行。

保护Unix套接字文件

对客户端至 localhost 的连接,服务器使用的是Unix域套接字文件。
此套接字文件常允许被公开访问,以便客户端程序可使用它。

对此文件需要客户端需要的是执行权限。

[mysqld]
socket=/usr/local/mysql/mysql.sock
[client]
socket=/usr/local/mysql/mysql.sock

保护选项文件

使用选项文件有潜在风险。

  • 如某个选项文件含有诸如MySQL账户名或密码类的敏感信息,则不要让其可公共读取。
  • /etc/my.cnf 该文件常允许公共可读,因为它是一个用于指定全局客户端选项的地方。
    不要把服务器的选项放入其中。
  • 每个用户特有的 (user-specific) .my.cnf选项文件,应该隶属于它所在主目录对应的那个用户,且只可被此用户访问。
% chmod u=rw,go-rwx .my.cnf
  • 其他选项文件则需根据它们的具体用途来设置其访问模式。

管理MySQL用户账户

数据库权限表。

  • CREATE USER、DROP USER、RENAME USER
    分别用于创建,删除和重命名MySQL账户。
  • GRANT
    用于指定账户权限(如账户不存在,则创建它们)。
  • REVOKE
    用于移除MySQL账户的权限。
  • SET PASSWORD
    用于分配账户的密码。
  • SHOW GRANTS
    用于显示账户所拥有的权限。
权限表内容
user可连接到服务器的用户,及它们的全局性权限
db数据库权限
tables_priv表权限
columns_priv列权限
procs_priv存储例程权限
proxies_priv代理用户权限

执行CREATE USER语句时,需指定一个账户名和可选的授权信息(密码或授权方法),服务器会在 user 表里为这个新账户创建一个行。

在GRANT语句时,指定账户不存在,会先将其创建。
在使用GRANT语句时,如果指定了全局权限,也会被记录到user表里。
如果在GRANT里指定的权限只适用于给定的数据库,表,列,存储例程,则它们会被分别记录到db,tables_priv,columns_priv或procs_priv表里。

PROXY权限的分配会被记录在proxies_priv表里。

REVOKE可删除权限表里的权限,DROP USER可从各个表中删除与给定账户相关的所有行。

MySQL账户的高级管理

指定账户名

在账户管理语句里,account值由用户名和主机名构成
具体格式为 ‘user_name’@‘host_name’ 。 (主机名为客户端所在的主机)

将账户名里的主机值与DNS相匹配

DNS解析返回的应该与账户指定的完全一致才匹配(匹配按字符串逐字符匹配进行的)。

指定账户认证方式

CREATE USER 语句可借助于可选的auth_info来指定账户认证方式:

CREATE USER account [auth_info]

auth_info子句可采用两种形式如下所示:

  • 账户采用密码认证
  • 指定一种不同的认证方法。

权限分配

为某个账户分配访问权限时,可用GRANT语句:

GRANT privileges [(columns)]
	ON what
	TO account [auth_info]
	[REQUIRE encryption requirements]
	[WITH grant or resource management options]

如果指定的账户存在,则GRANT会修改其权限。
如果指定的账户不存在,则GRANT会在创建它时带上分配的权限。

其中有几个子句是可选的,如无必要,完全可以不用指定它们。通常情况下,最为常用的是下面几个部分。

  • privileges
    表示分配给账户的权限
  • columns
    指定受权限影响的列。(xx,xxx, xx) 多个列必须以逗号隔开,并且需要列在括号里。
  • what
    表示权限应用的级别。
    最高级别是全局级,其中的权限会应用到所有数据库和所有表。
    也可指定应用到数据库、表、列、存储例程。
  • account
    表示被授予权限的账户。
    格式为 ‘user_name’@‘host_name’ 。
  • auth_info
    表示账户密码或认证方法。
  • REQUIRE
    会设置账户,要求其在进行连接时需使用安全的安全套接字层连接。
  • WITH
    可用于授予GRANT OPTION权限,进而让账户能把自己的权限转授给其他用户。

定义账户的权限

一个账户可被授予多种权限。
主要分为两类:管理权限,对象权限。

两个特殊的权限说明符:ALL 和 USAGE。
ALL表示所有权限;
USAGE表示无权限。

  • CREATE USER
    此权限允许使用的语句含:CREATE USER 、DROP USER、RENAME USER、REVOKE ALL PRIVILEGES 。
  • FILE
    可让你告诉服务器读取或写入服务器主机的文件。
  • GRANT OPTION
    可让你将自己拥有的权限授予其他用户。
  • PROCESS
    MySQL服务器是多线程的,能够同时为多个客户连接提供服务。
  • PROXY
    使你能获得另一用户的权限。
  • RELOAD
    让你能执行某些服务器管理操作。
    让你可执行FLUSH/RESET等;
    还可执行reload、refresh、flush-hosts、flush-logs 等 mysqladmin命令。
  • REPLICATION CLIENT
    使你可使用SHOW MASTER STATUS、SHOW SLAVE STATUS来查询主、从服务器的位置和状态。
  • SHOW DATABASES
    查看所有数据库名称。
  • SHUTDOWN
    可让你关闭服务器。
  • SUPER
    此权限使你能够使用 KILL 语句或 mysqladmin kill 命令来终止服务器进程。
  • ALTER
    使你可执行ALTER TABLE xxx 。
  • ALTER ROUTINE
    使你能更改或删除存储函数和存储过程。
  • CREATE
    使你能创建数据库和表。
  • CREATE ROUTINE
    使你能创建存储函数和存储过程。
  • CREATE TABLESPACE
    使你能创建,删除,或更改表空间。
  • CREATE TEMPORARY TABLES
    创建临时表。
  • CREATE VIEW
    创建视图。
  • DELETE
    删除表里的行。
  • DROP
    删除数据库和表。
  • EVENT
    使你能对事件调度器的各个事件进行操作。
  • EXECUTE
    使你能执行存储函数和存储过程。
  • INDEX
    使你能创建或删除表的索引,为键缓存分配索引,将索引预加载到键缓存。
  • INSERT
    使你能将行插入到表。
  • LOCK TABLES
    锁定表。
  • REFERENCES
    此权限未使用。
  • SELECT
    检索表里的数据。
  • SHOW VIEW
    查看视图。
  • TRIGGER
    添加和删除触发器。
  • UPDATE
    修改表里的行。

权限级别:

权限说明符权限作用级别
ON .全局权限,所有数据库+所有表
ON *默认数据库
ON db_name.*指定数据库
ON db_name.tbl_name指定数据库的指定表
ON tbl_name指定表
ON db_name.routine_name指定数据库的指定例程
ON account代理权限

想显式地指定权限要应用的对象类型,可以含TABLE, FUNCTION, PROCEDURE(如ON TABLE xx.xx 或 ON FUNCTION xx.xx)。

USAGE权限只能全局级指定(ON .)。

ALL会把给定级别上所有权限授予账户。
ALL下的所有权限不会包含GRANT和REVOKE所需的GRANT OPTION。

  • 使用无权限的USAGE权限
    让你更改某个账户的特性,同时保证原有权限不受影响。
  • 要求账户使用安全连接
  • 让账户拥有管理权限
  • 限制账户的资源占用
  • 显示账户权限
SHOW GRANTS FOR 'sampadm'@'localhost';
SHOW GRANTS;
  • 撤销权限
    REVOKE。
    REVOKE没有auth_info, REQUIRE, WITH子句。
REVOKE privileges [(columns)] ON what FROM account;
GRANT ALL ON sampdb.* TO 'boris'@'localhost';
REVOKE DELETE, UPDATE ON sampdb.* FROM 'boris'@'localhost';

要撤销某个权限,你需先自己拥有该权限,还需拥有GRANT OPTION权限。

  • 更改密码或重置丢失的密码
  • 插入式身份认证和代理用户

权限表结构和内容

各类权限管理SQL语句最终都变为对MySQL权限表的修改。
权限表控制着客户端对MySQL数据库的访问,位于mysql数据库里,会在将MySQL第一次安装至机器的过程中被初始化。
这些表的名字分别是:user、db、tables_priv、columns_priv、procs_priv、proxies_priv 。

服务器对它们的使用情况如下:

  • user表列出的是可连接至服务器的各个用户账户,及每个用户所拥有的全局权限。
    在user表里启用的所有权限都是全局权限,适用于所有数据库。
    user表还包含用于身份认证的列,用于使用SSL建立安全连接的SSL选项列,用于防止给定账户独占该服务器的资源管理列。
  • db表列出的是哪些账户对哪些数据库有权限。
    此处授予的权限可应用于数据库内的所有对象(包括表,存储例程等)。
  • tables_priv表列出的是各种表级别的权限。
    此处指定的权限适用于表里的所有列。
  • columns_priv表列出的是列级别的权限。
    此处指定的权限适用于表中的特定列。
  • procs_priv表包含的是适用于各种存储例程(存储函数,存储过程)的权限。
    此处指定的权限适用于数据库里的特定例程。
  • proxies_priv表表明哪些账户可称为其他账户的代理,并获得它们的权限。

每个权限表含两种基本类型的列:
一个是访问访问列,用于确定何时应用于行;另一个是权限列,用于确定某个行授予了哪些权限。

user表还有几个用于身份认证,SSL连接和资源管理的列。

权限系统包含的表有 tables_priv、columns_priv、procs_priv,分别用于定义以下各项的权限:特定表、列、存储函数和存储过程。

权限表访问范围列

当某个账户试图执行某个给定操作时,访问范围列的操作决定了服务器会使用哪些行来确定最终的权限。
权限表的每个行都包括Host列,User列,用于表明该行适用于由特定用户从给定主机发起的连接。

db表含一个Db列,用于表明该行适用于那个数据库。
tables_priv和columns_priv表的行里包含的访问范围列,使其访问范围进一步变窄,分别限定在数据库里的特定表和表里的特定列中。
procs_priv表的访问范围列则指定了一个行适用于那个存储函数或存储过程。

权限表权限列

对每一行,这些权限列表明的是,由访问范围列标识出的那个用户拥有哪些权限。
在user表和db表里,指定的每种权限都是一个单独列。这些列被定义为ENUM(‘N’, ‘Y’)类型,其默认值为’N’。
如,Select_priv列定义如下:

Select_priv ENUM('N', 'Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N'

表tables_priv, columns_priv, procs_priv里的权限都是用SET表示的,从而可将存储在同一列的各种权限任意组合。

SET('Select','Insert',...,'Trigger')
CHARACTER SET utf8 NOT NULL DEFAULT ''

columns_priv表的Column_priv列的定义如下:

SET
('Select',...)
CHARACTER SET utf8 NOT NULL DEFAULT ''

权限表身份认证列

user表有3个用于指明账户认证方式的列:Password、plugin、authentication_string 。

对某个给定账户在user表里对应的行,如果 plugin 列为空,则客户端进行账户认证时会使用Password列里的密码。

权限表SSL相关列

在user表里,有几个列适用于基于SSL的安全认证。

最主要的列是ssl_type,它表明账户是否需要安全连接。

服务器如何控制客户端访问

MySQL服务器对客户端的访问控制分为两个阶段。

  • 第一阶段在你试图连接服务器的时候。

  • 第二阶段,服务器会对执行的每一条语句作两项检查。
    首先,它检查每小时执行语句数目和每小时更新数目的限制。
    其次,服务器会检查权限表,以验证你是否有足够的执行该语句的访问权限。

访问范围列的内容

每个访问范围列都有一些约束规则,来定义哪些类型值是合法的,及服务器会如何解释它们。

  • Host
    主机名、IP地址。值 localhost 代表本地主机。
  • User
    用户名必须为文字值或空白(空)。空白值可以匹配任何名字,即为“匿名”。否则,它必须与指定的名字精确匹配。
  • Db
    在 db 表里,指定 Db 值时,可以使用普通字符,也可以使用 SQL 模式字符 “%”或“_” 指定的通配符。
  • Table_name,Column_name和Routine_name
    这些列值必须分别为普通的表名、列名或存储例程名。
    列值需要与指定的名字精确匹配。不允许使用模式和空白值。
  • Routine_type
    此列的值只能是 ‘FUNCTION’ 或者 ‘PROCEDURE’ ,用来表示行中 Routine_name 列里的名字是适用于存储函数,还是适用于存储过程。
  • Proxied_host,Proxied_user
    这两列存在于 proxies_priv 表中,该表还拥有可以表示代理用户账户的 Host 列和 User 列。

学习参考资料:

《MySQL技术内幕》第5版
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值