怎么也没想到,我的个人网站数据库竟然被黑掉了。所有的库都被删掉,只留有一个勒索信息表。查看数据库日志,除了 drop
库和新建了一个 mysqlbackups
用户之外,并没发现其他记录。(已经撕票,还让我交钱,没有武德啊)。不过庆幸,只是侵入了数据库,并未发现服务器有异常,而且数据库的binlog文件都在。下面就尝试通过日志文件进行恢复。
关于 binlog
二进制日志 binlog 是 MySQL 最重要的日志之一,记录了对数据库的常见增删改查,索引,表的操作记录(DDL和DML);binlog 主要用于复制和数据恢复。关于复制,之前写过一个简单的示例 使用Docker实现简单的MySQL主从复制。本篇的内容主要介绍数据恢复。
binlog 默认开启,SET SQL_LOG_BIN=1
开启,SET SQL_LOG_BIN=0
关闭(重启生效)。
show master status
可以查看当前正在写入的 binlog 文件。binlog 的磁盘路径,默认应该位于 /var/lib/mysql
下,可以在数据库配置文件中自定义。(binlog 在生产环境作为重要的日志文件,一定要特别注意保存和维护)。
切换到 binlog 所在目录,可以看到日志文件分为两类。
- **.index (index后缀)记录所有有效的的二进制文件,index 就是 binlog 的索引目录文件。
- *.0000 (数字后缀) 记录数据库所有的 DDL 和 DML 语句事件。
日志恢复
可以使用 mysqlbinlog
命令去查看 binlog。注意:mysqlbinlog
是 shell 命令,而不是 MySQL 命令。
mysqlbinlog mysql-bin.000001
可以进行直接查看。当然,很少的情况会这样使用,因为通常 binlog 很大,会导致终端窗口无限滚动。
出现了错误?
直接执行
mysqlbinlog mysql-bin.000001
可能出现错误:mysqlbinlog: unknown variable 'default-character-set=utf8'
,这个问题可以通过带上参数--no-defaults
解决;
即mysqlbinlog --no-defaults mysql-bin.000002
下面所有的
mysqlbinlog
命令基于我本地服务器的环境,默认都带上--no-defaults
。
这就要求我们进行有目的地查询;比如手误删除了某个表中的数据,可以以该表的表名 table1
作为关键词进行查询;知道某个具体的自增主键的ID,也可以通过ID作为关键词。
mysqlbinlog --no-defaults mysql-bin.000001 | grep table1 -C 3;
这里通过 grep
查询关键词 table1
,其中 -C 3
表示查看关键词匹配行的上下三行内容。同理,-B 3
打印匹配行的前3行(B=before);-A 3
打印匹配行的后3行(A=after)。
上图是查询关键词 INSERT_ID=2734961
的终端截图。
这里有两个重要的信息(图中划红线的位置):position 事件位置和事件时间。下面几个参数可以用来框选日志的范围。
-
–start-datetime=开始时间
-
–stop-datetime=结束时间
-
–start-position=开始位置
-
–stop-position=结束位置
-
–database=数据库名称
mysqlbinlog --no-defaults --database=db --start-position=34926815 --stop-position=181096090 mysql-bin.000001 | /usr/bin/mysql -uroot -ppwd -v db
事件位置在 34926815 和 181096090 之间的脚本重新执行(恢复)到指定账户的数据库,只执行该数据库的事件 db 库有关的脚本。
总结
这次暂不清除什么原因导致数据库账户泄露,但终归是因为没有良好的数据库权限管理的习惯,而导致这次的"损失"。折腾一下午,数据算是恢复了。亡羊补牢,这里列出几个常见的tips:
- 数据库的 root 账户只能在数据库所在服务器进行本地使用,不得远程登录。
- 平时的数据库连接工具采用一个库一个账户的方式,防止鸡蛋放在一个篮子里。
- 接口服务的数据库连接账号只予以增删改查的权限
select,insert,update,delete
。因为代码都在云端托管,万一第三方出现信息泄漏(gitlab出现过账户信息泄漏),也能将风险劲量降低。
另外,对数据库的定期备份也是一个必须操作。因为这次好在数据库数据量不大,恢复也未太费功夫。倘若生产环境数年的数据被删除,即使可以通过日志进行恢复,恢复过程中的宕机损失也不能忽视。有了定期备份,需要恢复数据量的减少也会大大减少恢复本身所需的时间,从而减小意外事故带来的业务损失。
最后,害人之心不可有,防人之心不可无。