关于安全:技术分享-是谁删了表

5次阅读

共计 4379 个字符,预计需要花费 11 分钟才能阅读完成。

作者:王少鹏
爱可生 DBA 团队成员,负责我的项目数据库日常问题解决及公司 DMP 平台问题解决,对数据库有强烈的趣味。认为不会游泳的厨师绝不是一个好数据库工程师。
本文起源:原创投稿
* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


背景

某日某公司的测试数据库突发告警!

故障初步定位很可能是新来的几位实习生没有恪守运维标准,误操作(没加 where 条件)删表导致服务异样,目前还没确认操作用户身份。

DELETE TABLE XXXXX;(环境 autocommit=1,没有手动开启事务)

只管测试环境不影响线上利用,但影响了新性能开发进度,暴露出运维治理上的破绽。

通过以上案例思考,MySQL 自身并没有操作审计的性能,又如何依据现有的性能进行行为剖析,防止喜剧再次发生?

文章整顿了运维时罕用的定位 MySQL 操作用户办法,帮你疾速查看用户行为记录。

一、思路

  1. 设置 init_connect 参数;
  2. 创立用户连贯信息表;
  3. 通过 binlog 日志进行查看执行的危险 SQL 语句;
  4. 通过 thread_id 找到对应的用户及起源 IP 地址。

init_connect 参数的性能:当用户在客户端连贯 MySQL 时,隐式执行的一条自定义的 SQL 语句(参数值)。

留神:

  • 开启 binlog 日志记录性能;
  • 对领有 super_priv 权限的用户有效。

二、筹备工作

2.1 init_connect 参数

mysql> show variables like 'init_connect';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| init_connect  |       |
+---------------+-------+
1 row in set (0.00 sec)
​
​
mysql> set global init_connect='insert into auditdb.accesslog(connectionID,ConnUser,MatchUser,LoginTime) values(connection_id(),user(),current_user(),now());';
Query OK, 0 rows affected (0.00 sec)
​
​
mysql> show variables like 'init_connect';
+---------------+-------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                         |
+---------------+-------------------------------------------------------------------------------------------------------------------------------+
| init_connect  | insert into auditd.accesslog(connectionID,ConnUser,MatchUser,LoginTime) values(connection_id(),user(),current_user(),now()); |
+---------------+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

既然是要 insert 一条数据,那是不是这个普通用户要对这张表领有 insert 权限呢?

答案是必定的。

2.2 连贯信息表

mysql> create database auditdb charset utf8mb4;
Query OK, 1 row affected (0.01 sec)
​
mysql> create table auditdb.accesslog (id int (10) unsigned not null primary key auto_increment,
       Connectionid int(10) unsigned,ConnUser varchar (30) not null default '',
       MatchUser varchar (30) not null default '',
       Logintime datetime);
Query OK, 0 rows affected (0.02 sec)

对所有用户都赋予 insert 权限

mysql> grant insert on auditdb.accesslog to mindoc@'%';
Query OK, 0 rows affected (0.00 sec)

留神:

此办法须要给数据库所有用户都对 auditdb.accesslog 授写权限,否则插入用户信息会失败;

不要受权 update、delete 等权限,否则普通用户登录 MySQL 能够手动删除他连贯的信息。

三、误删除试验

3.1 模仿误删除

[root@db ~]# mysql -u mindoc -p -h 172.18.1.76
Enter password:
​
mysql> create table temp(id int,name varchar(32));
Query OK, 0 rows affected (0.03 sec)
​
mysql> insert into temp values(1,'aa');
Query OK, 1 row affected (0.01 sec)
​
mysql> insert into temp values(2,'aa');
Query OK, 1 row affected (0.01 sec)
​
mysql> insert into temp values(3,'aa');
Query OK, 1 row affected (0.01 sec)
​
mysql> delete from temp;
Query OK, 3 rows affected (0.01 sec)

此时数据曾经被删除了,你的应用程序应该会报错或开始告警。通过查看利用日志,可大抵推断工夫范畴。

3.2 导出并剖析 binlog 日志

[root@db ~]# mysqlbinlog -v --base64-output=decode-rows /usr/local/mysql-5.7.20/binlog/mysql-bin.000002 > audit.log

查看危险语句的过程 ID 号(在解析后的 binlog 文件搜寻危险命令关键字)

通过执行的 delete 语句与大略执行工夫,确定是哪个用户连贯(thread_id=130)

[root@db ~]# tail -35 audit.log
# at 49003
#191120 13:02:18 server id 76  end_log_pos 49080 CRC32 0x73dc1dda     Query    thread_id=130    exec_time=0    error_code=0
SET TIMESTAMP=1574226138/*!*/;
BEGIN
/*!*/;
# at 49080
#191120 13:02:18 server id 76  end_log_pos 49135 CRC32 0x360e7fe4     Table_map: `mindoc_db`.`temp` mapped to number 249
# at 49135
#191120 13:02:18 server id 76  end_log_pos 49194 CRC32 0xbbf0d78f     Delete_rows: table id 249 flags: STMT_END_F
​
BINLOG '
2sjUXRNMAAAANwAAAO+/AAAAAPkAAAAAAAEACW1pbmRvY19kYgAEdGVtcAACAw8CgAAD5H8ONg==
2sjUXSBMAAAAOwAAACrAAAAAAPkAAAAAAAEAAgAC//wBAAAAAmFh/AIAAAACYWH8AwAAAAJhYY/X
8Ls=
'/*!*/;
### DELETE FROM `mindoc_db`.`temp`
### WHERE
###   @1=1
###   @2='aa'
### DELETE FROM `mindoc_db`.`temp`
### WHERE
###   @1=2
###   @2='aa'
### DELETE FROM `mindoc_db`.`temp`
### WHERE
###   @1=3
###   @2='aa'
# at 49194
#191120 13:02:18 server id 76  end_log_pos 49225 CRC32 0x277ece0b     Xid = 23721
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

3.3 查看对应工夫对应的用户信息

能够看到线程 threadid=130,并且工夫也是 2019-11-20 中午一点左右。能够确定就是 mindoc@’%’用户操作的 delete 语句。

通过 ConnUser 字段能够看到是 172.18.1.99 这个地址应用 mindoc@’%’用户连贯的 MySQL 数据库。

mysql> select * from auditdb.accesslog where Connectionid=130;
+----+--------------+--------------------+-----------+---------------------+
| id | Connectionid | ConnUser           | MatchUser | Logintime           |
+----+--------------+--------------------+-----------+---------------------+
|  1 |          130 | mindoc@172.18.1.99 | mindoc@%  | 2019-11-20 12:59:21 |
+----+--------------+--------------------+-----------+---------------------+
1 row in set (0.00 sec)

而后你就能够去找谁应用的 mindoc@% 用户了,还有定位下 172.18.1.99 这个 IP 地址谁在应用。

实现了通过行为定位用户的操作。

正文完
 0