数据库原理——第四章:数据库安全性

参考书目《数据库系统概论(第5版)》

数据库安全性概述

数据库安全标准:TCSECCC
TCSEC/TDI安全级别划分(从上到下安全级别逐渐降低)

安全级别 定义
A1 验证设计
B3 安全域
B2 结构化保护
B1 标记安全保护
C2 受控的存取保护
C1 自主安全保护
D 最小保护

C1级:只提供了非常初级的自主安全保护,能够实现对用户和数据的分离,进行自助存取控制(DAC)
B1级:对系统的数据加以标记,并对标记的主体和客体实施强制存取控制(MAC)以及审计等安全机制。B1级别的产品才被认为是真正意义上的安全产品


数据库安全性控制

用户身份鉴别

这是数据库管理系统提供的最外层安全保护机制

  1. 静态口令鉴别
  2. 动态口令鉴别
  3. 生物特征鉴别
  4. 智能卡鉴别

存取控制

存取控制机制主要包括定义用户权限合法权限检查,二者一起组成了数据库管理系统的存取控制子系统

  • 自主存取控制:用户对于不同的数据库对象拥有不同的存取权限,不同用户对同一对象也有不同权限,而且用户可以将其拥有的权限转授给其他用户。因此自主存取控制非常灵活
  • 强制存取控制:每个数据库对象被标以一定的密级,每一个用户也被授予某一个级别的许可证。对于任意一个对象,只有具有合法许可证的用户才可以存取。因此强制存取控制相对比较严格

自主存取控制方法

用户权限由两个要素组成:数据库对象操作类型
定义用户的存取权限称为授权

------后续语句实现基于MySQL------

创建用户

1
2
CREATE USER <用户名>@<用户登陆主机> [IDENTIFIED BY <密码>];
CREATE USER <用户名>; /*可以在本地无密码登录的账户*/
  • 用户登录主机若不填写则默认为localhost,若要允许远程登陆,则localhost可以替换为相应的主机ip,或者直接替换为:%(表示任何一台主机都可以远程登陆)
  • 新用户的密码可以选择不创建

修改用户密码

1
2
ALTER USER <用户名>@<用户登陆主机> IDENTIFIED BY <新密码>
SET PASSWORD FOR <用户名>@<用户登陆主机> = PASSWORD('新密码') /*创建新密码*/

删除用户

1
DROP USER [IF EXIST] <用户名>@<用户登陆主机>

给用户授权

1
GRANT <权限>(属性名),... ON <数据库名>.<数据库表名>,... TO <用户名>@<用户登陆主机>,... [WITH GRANT OPTION]
  • 如果指定了WITH GRANT OPTION子句,则获得某种权限的用户还可以把这种权限再授予其他用户(传播权限)
  • 对于<权限>(属性名),如UPDATE(Sno)表示对于Sno这个属性具有更新的权限,若不填则默认为所有属性
  • 如果想给新用户所有的权限,可以直接使用ALL PRIVILEGES

收回授权

1
REVOKE <权限>(属性名),... ON <数据库名>.<数据库表名>,... FROM <用户名>@<用户登陆主机>,...

数据库角色

MySQL 8.0 为了用户权限管理更容易,提供了一个角色管理的新功能
数据库角色是被命名的一组与数据库操作相关的权限,角色是权限的集合。如果用户被授予角色权限,则该用户拥有该角色的权限,从而简化授权过程
MySQL 8.0 提供的角色管理功能如下:

1
2
3
4
5
6
7
8
CREATE ROLE 角色创建
DROP ROLE 角色删除
GRANT 为用户和角色分配权限
REVOKE 为用户和角色撤销权限
SHOW GRANTS 显示用户和角色的权限
SET DEFAULT ROLE 指定哪些帐户角色默认处于活动状态
SET ROLE 更改当前会话中的活动角色
CURRENT_ROLE() 显示当前会话中的活动角色
  1. 创建用户、分配权限、回收权限、验证

    • 创建用户

    1
    CREATE USER wsy@'%' IDENTIFIED BY '111111';

    • 分配权限

    1
    GRANT INSERT,UPDATE,ALTER ON test.* TO wsy@'%';

    • 回收权限

    1
    REVOKE UPDATE ON test.* FROM wsy@'%';

    • 验证

    1
    2
    3
    4
    5
    6
    7
    /*使用用户wsy登录Mysql之后*/
    SELECT user();
    USE test;
    DESC P;
    INSERT INTO P VALUES ('P7', '螺母', '绿', 32);
    SELECT * FROM P WHERE PNO='P1'
    UPDATE P SET P=P+10 WHERE COLOR='红';

    结果如下



  2. 创建角色、分配权限、回收权限、验证

    • 创建角色

    1
    CREATE ROLE visitor;

    • 分配权限

    1
    GRANT SELECT ON test.* TO visitor;

    • 回收权限

    1
    REVOKE SELECT ON test.* FROM visitor;

    • 验证

    1
    2
    3
    4
    5
    /*root账户下,分配visitor角色给wsy*/
    GRANT visitor TO wsy;

    /*使用用户wsy登录Mysql之后*/
    USE test;


强制存取控制方法

自助存取控制可能不安全的根本原因在于:仅仅通过对数据的存取控制权限来进行安全控制,而数据本身并无安全性标记
在强制存取控制中,全部实体被分为主体客体两大类。主体是系统中的活动实体,客体是系统中的被动实体,受主体操控
数据库管理系统为每个实例指派一个敏感度标记,敏感度标记可被分为:TS >= S >= C >= P
主体的敏感度标记称为许可证级别,客体的敏感度标记称为密级
判定规则:

  • 仅当主体的许可证级别大于或等于客体的密级是,该主体才能读取相应的客体
  • 仅当主体的许可证级别小于或等于客体的密级是,该主体才能相应的客体

视图

通过视图机制把要保密的数据对无权存取的用户隐藏起来


审计

审计功能把用户对数据库的所有操作自动记录下来放入审计日志中。管理人员可利用审计日志监控数据库的各种行为,重现操作过程,找出非法存取数据的人、时间和内容等

------后续语句实现基于MySQL8.0------

  1. 开启审计功能

    • 设置变量

    1
    2
    3
    4
    5
    6
    7
    8
    /*打开审计开关*/
    set global general_log = on;
    set global general_log_file = '/var/lib/mysql/operation.log';
    set global log_timestamps = SYSTEM;

    /*查看审计状态*/
    show global variables like 'log_timestamps';
    show global variables like '%general%';

  2. 设置审计权限

    • 创建用于存放连接日志的数据库和表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    create database auditlog;
    create table auditlog.t_audit(
    id int not null auto_increment,
    thread_id int not null,
    login_time timestamp,
    localname varchar(50) default null,
    matchname varchar(50) default null,
    primary key (id)
    )ENGINE=InnoDB default charset=utf8 comment '审计用户登录信息';

    • 授权某个用户拥有对审计表的select和insert权限

    1
    2
    3
    4
    5
    /*给出对所有用户授权的语句(拼结授权语句)*/
    SELECT concat("GRANT SELECT,INSERT ON auditlog.t_audit to '",user,"'@'",host,"';") FROM mysql.user;

    /*授权用户wsy*/
    GRANT SELECT,INSERT ON auditlog.* to wsy@'%';

    • 设置init_connect参数

    1
    SET GLOBAL init_connect='INSERT INTO auditlog.t_audit(id,thread_id,login_time,localname,matchname) VALUES(null,connection_id(),now(),user(),current_user());';


  3. 普通用户登录,执行操作

    • 查看登录记录

    1
    SELECT * FROM t_audit WHERE matchname='wsy@%';

    • 执行插入操作

    1
    INSERT INTO P VALUES ('P8', '丝轴', '银', 12);

    之后查看日志记录cat /var/lib/mysql/operation.log
    可以看到insert操作已经被记录下来

    • 查照操作者

    1
    2
    /*使用root用户*/
    SELECT * FROM t_audit;


    可以看到用户wsy在2019-05-07 19:10:56登录,并在2019-05-07 19:11:11进行了insert操作。