作者:Mike Frank 译:徐轶韬
面临的挑战
使用敏感信息时您需要拥有审计日志。通常,此类数据将包含一个分类级别作为行的一部分,定义如何处理、审计等策略。在之前的博客中,我讨论了如何审计分类数据查询。本篇将介绍如何审计对机密数据所做的数据更改。
敏感数据可能被标记为–高度敏感
最高机密
分类
受限制的
需要清除
高度机密
受保护的
合规要求通常会要求以某种方式对数据进行分类或标记,并审计该数据上数据库中的事件。特别是对于可能具有数据访问权限但通常不应查看某些数据的管理员。
敏感数据可以与带有标签的数据穿插在一起,例如公开
未分类
其他
当然,您可以在MySQL Audit中打开常规的插入/更新/选择审计。但是在这种情况下,您将审计所有的更改。如果您只想审计敏感数据是否已更改,下面是您可以执行的一种方法。
一个解决方法
本示例使用MySQL触发器来审计数据更改。
我们的示例表很简单,包含id,name,desc,并且还有一个用于sec_level的附加列。我们要审计sec_level高的行– H,H–表示已插入,更新为H或从H更新或删除。CREATE SCHEMA test_datachange_audit;
CREATE TABLE `test_datachange_audit`.`info_cat_test` (
`id` INT NOT NULL,
`name` VARCHAR(20) NULL,
`desc` VARCHAR(20) NULL,
`sec_level` CHAR(1) NULL,
PRIMARY KEY (`id`));
让我们添加几行数据。INSERT INTO `test_datachange_audit`.`info_cat_test` (`id`, `name`, `desc`, `sec_level`) VALUES ('1', 'fred', 'engineer', 'H');
INSERT INTO `test_datachange_audit`.`info_cat_test` (`id`, `name`, `desc`, `sec_level`) VALUES ('2', 'jill', 'program manager', 'M');
INSERT INTO `test_datachange_audit`.`info_cat_test` (`id`, `name`, `desc`, `sec_level`) VALUES ('3', 'joe', 'maintenance', 'L');
启用EE审计(要求使用企业版 –如果需要使用 MySQL shell连接显示版本信息。–您将需要MySQL EE 8.0.17或更高版本–截至本文撰写时,最新版本为8.0.22)
> mysqlshmysql> select @@version;
> bin/mysql -u root -pINSTALL COMPONENT "file://component_audit_api_message_emit";
在[mysqld]中启用启动时的审计并设置选项。例如:
>vi etc/my.cnfplugin-load-add=audit_log.so
audit-log=FORCE_PLUS_PERMANENT
audit-log-format=JSON
audit-log-strategy=SYNCHRONOUS
有关审计选项和变量的更多详细信息,请参考审计日志手册。
重新启动MySQL服务器。
注意:有多种方法可以启用审计而无需重新启动。但是您要强制执行审计-因此,上面是您的操作方式。
以下简单过程将用于写入我想在我的审计跟踪中拥有的审计元数据。FOR和ACTION是写入审计日志的元数据标签。在这种情况下,FOR将具有要更改其级别数据的名称,而ACTION将是在更新(之前和之后),插入或删除时使用的名称。DELIMITER $$
CREATE PROCEDURE test_datachange_audit.audit_api_message_emit_sp(name CHAR(20), ttype CHAR(3))
BEGIN
DECLARE aud_msg VARCHAR(255);
select audit_api_message_emit_udf('sec_level_trigger',
'TRIGGER audit_change_attempt',
'Change H level sec data',
'FOR ', name,
'ACTION',ttype
) into aud_msg;
END$$
DELIMITER ;
接下来,我们需要在表格上创建触发器DELIMITER $$
CREATE TRIGGER test_datachange_audit.audit_delete
BEFORE DELETE ON `test_datachange_audit`.`info_cat_test`
FOR EACH ROW
BEGIN
IF OLD.sec_level = 'H' THEN
CALL audit_api_message_emit_sp(OLD.name,'DEL' );
END IF;
END$$
DELIMITER ;DELIMITER $$
CREATE TRIGGER test_datachange_audit.audit_insert
BEFORE INSERT ON `test_datachange_audit`.`info_cat_test`
FOR EACH ROW
BEGIN
IF NEW.sec_level = 'H' THEN
CALL audit_api_message_emit_sp(NEW.name,'INS');
END IF;
END$$
DELIMITER ;DELIMITER $$
CREATE TRIGGER test_datachange_audit.audit_update
BEFORE UPDATE ON `test_datachange_audit`.`info_cat_test`
FOR EACH ROW
BEGIN
IF OLD.sec_level = 'H' THEN
CALL audit_api_message_emit_sp(OLD.name,'UPO');
END IF;
IF NEW.sec_level = 'H' THEN
CALL audit_api_message_emit_sp(NEW.name, 'UPN');
END IF;
END$$
DELIMITER ;
接下来运行在“ H”级或“ M”和“ L”级更改
请记住,只有对“ H” sec_level列进行更改时,触发器才会审计。DELETE from `test_datachange_audit`.`info_cat_test` where id=1;
INSERT INTO `test_datachange_audit`.`info_cat_test` (`id`, `name`, `desc`, `sec_level`) VALUES ('5', 'joey', 'spy', 'H');
INSERT INTO `test_datachange_audit`.`info_cat_test` (`id`, `name`, `desc`, `sec_level`) VALUES ('8', 'jessie', 'engineer', 'L');
UPDATE`test_datachange_audit`.`info_cat_test` set sec_level='H' where id=2;
UPDATE`test_datachange_audit`.`info_cat_test` set sec_level='M' where id=2;
您将看到ACTION的4个不同标签-INS,DEL,UPN(N的意思为新的–表示没有“ H”的人已更新为“ H”)和UPO(O表示旧的–带有“ H”的人从'H'进行了更新)
现在,我们可以在审计日志中看到它。
注意:使用位置–默认情况下是您的“select @@datadir;”
对于我而言,我将运行以下OS命令,并寻找sec_level_trigger来从日志中过滤掉这些审计事件。>sudo cat usr/local/mysql/data/audit.log | grep sec_level_trigger
{ "timestamp": "2020-11-17 20:04:32", "id": 13, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "DEL", "FOR ": "fred" } } },
{ "timestamp": "2020-11-17 20:04:32", "id": 14, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "DEL", "FOR ": "joey" } } },
{ "timestamp": "2020-11-17 20:04:35", "id": 2, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "INS", "FOR ": "fred" } } },
{ "timestamp": "2020-11-17 20:04:45", "id": 2, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "DEL", "FOR ": "fred" } } },
{ "timestamp": "2020-11-17 20:04:47", "id": 2, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "INS", "FOR ": "joey" } } },
{ "timestamp": "2020-11-17 20:04:51", "id": 2, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "UPN", "FOR ": "jill" } } },
{ "timestamp": "2020-11-17 20:04:54", "id": 2, "class": "message", "event": "user", "connection_id": 9, "account": { "user": "root", "host": "localhost" }, "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" }, "message_data": { "component": "sec_level_trigger", "producer": "TRIGGER audit_change_attempt", "message": "Change H level sec data", "map": { "Action": "UPO", "FOR ": "jill" } } },
结论
您可能会采用这种方法。这只是一个例子。通常审计其特性与数量的关系。以及有关评估审计日志内容的信息-这样您就可以发现任何滥用情况。
与往常一样,感谢您使用MySQL。
感谢您关注“MySQL解决方案工程师”!