郑州1024MySQL数据库被比特币勒索及安全调整
一、中控安装后应该进行的调整
调整数据库管理员密码为强密码,开启binlog,做好数据库备份。
1、更新数据库管理员密码为强密码
# 1、进入mysql容器
docker exec -it mysql bash
# 2、更新root密码
mysql -uroot -ptest1234
MySQL> alter user 'root'@'localhost' IDENTIFIED BY 'CofcoRpa@12345!#.';
MySQL> alter user 'root'@'%' IDENTIFIED BY 'CofcoRpa@12345!#.';
MySQL> flush privileges;
2、开启log-bin记录数据库操作日志
5.7.x版本需要在配置文件添加参数,8.0.x版本默认开启log-bin
# 1、更新mysql配置文件开启log-bin日志
cat >> /data/cyclone/rpaplatform/data/middleware/mysql-conf/mysql.cnf <<EOFlog-bin=/var/lib/mysql/mysql-binlog
log-error=/var/lib/mysql/error.logEOF
# 2、重启mysql容器生效log-bin参数
docker restart mysql
# 3、查看log-bin是否生效
MySQL> show global variables like 'log_bin%';
+---------------------------------+-----------------------------------+
| Variable_name | Value |
+---------------------------------+-----------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysql-binlog |
| log_bin_index | /var/lib/mysql/mysql-binlog.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
+---------------------------------+-----------------------------------+
3、定期全量备份及自动删除7天前备份文件
# mysqldump参数
--master-data
=1 会把CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=1275;打印出来
=2 会把CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=1275;打印出来且注释
使用该参数会打开--lock-all-tables,锁定所有表,需要结合--single-transaction一起使用,会自动关闭--lock-tables
--single-transaction
通过在单个事务中转储所有表来创建一致的快照。只支持InnoDB,备份时不要使用ALTER TABLE、DROP TABLE、RENAME TABLE、TRUNCATE TABLE,因为一致快照不会隔离这些操作。
--set-gtid-purged 默认值auto
=off 如果关闭,则此选项不起任何作用。
=on 如果打开并且服务器上未启用GTID,则会报错。开启GTID,则会输出以下信息SET @@GLOBAL.GTID_PURGED='4de07665-1923-11ed-8a94-0242ac110002:1-10';到输出
=auto 如果自动,并且在服务器上启用了GTID,SET @@GLOBAL.GTID_PURGED被添加到输出。如果禁用GTID,则自动不执行任何操作。
# 1、创建备份目录
su - rpa
mkdir /data/cyclone/rpaplatform/data/middleware/mysql-bak -p
# 2、创建备份脚本
su - rpa
vi /data/cyclone/rpaplatform/data/middleware/mysqlbak.sh
#!/bin/bash
docker exec -it mysql mysqldump -uroot -ppwd --master-data=2 --single-transaction --set-gtid-purged=off -A >/data/cyclone/rpaplatform/data/middleware/mysql-bak/dball-`date +%Y%m%d%H%M%S`.sql
find /data/cyclone/rpaplatform/data/middleware/mysql-bak/ -mtime +7 -name "*.sql" -exec rm -rf {} \;
chmod +x /data/cyclone/rpaplatform/data/middleware/mysqlbak.sh
# 3、每天23:30自动备份全库数据
su - rpa
crontab -e
30 23 * * * sh /data/cyclone/rpaplatform/data/middleware/mysqlbak.sh
4、备份binlog
# 在要备份binlog服务器(192.168.1.1)
SQL> grant REPLICATION SLAVE on *.* 'repl'@'192.168.1.2' identified by 'repl';
SQL> flush privileges;
# 以下操作都是在备份binlog服务器操作(192.168.1.2)
shell> mkdir /data/mysql/backup/binlog
shell> cat /data/mysql/scripts/backup_binlog.sh
#!/bin/sh
#指定mysqlbinlog的位置
BACKUP_BIN=/usr/local/mysql/bin/mysqlbinlog
#指定将远程binlog备份到本地的位置
LOCAL_BACKUP_DIR=/data/mysql/backup/binlog/
#指定备份binlog时的日志
BACKUP_LOG=/data/mysql/backup/binlog/backup.log
#指定要备份哪台binlog的ip
REMOTE_HOST=192.168.1.1
REMOTE_PORT=3306
REMOTE_USER=repl
REMOTE_PASS=repl
FIRST_BINLOG=mysql-bin.000001
#time to wait before reconnecting after failure
SLEEP_SECONDS=10
cd ${LOCAL_BACKUP_DIR}
## 运行while循环,连接断开后等待指定时间,重新连接
while :
do
if [ `ls -A "${LOCAL_BACKUP_DIR}" |wc -l` -eq 0 ];then
LAST_FILE=${FIRST_BINLOG}
else
LAST_FILE=`ls -l ${LOCAL_BACKUP_DIR} | grep -v backup.log |tail -n 1 |awk '{print $9}'`
fi
#${BACKUP_BIN} --raw --read-from-remote-server --stop-never --host=${REMOTE_HOST} --port=${REMOTE_PORT} --user=${REMOTE_USER} --password=${REMOTE_PASS} ${LAST_FILE}
/usr/local/mysql/bin/mysqlbinlog --raw --read-from-remote-server --stop-never --host=${REMOTE_HOST} --port=${REMOTE_PORT} --user=${REMOTE_USER} --password=${REMOTE_PASS} ${LAST_FILE}
echo "`date +"%Y/%m/%d %H:%M:%S"` mysqlbinlog停止,返回代码:$?" | tee -a ${BACKUP_LOG}
echo "${SLEEP_SECONDS}秒后再次连接并继续备份" | tee -a ${BACKUP_LOG}
sleep ${SLEEP_SECONDS}
done
# 后台运行该备份脚本
shell> nohup sh /data/mysql/scripts/backup_binlog.sh &
二、比特币勒索排查
一般都是原本正常的服务,突然不能用了。进入数据库查看,一般会有一张readme表。
1、查看数据库内部信息
# 1、进入mysql容器
docker exec -it mysql bash
# 2、查看mysql数据库信息
mysql -uroot -p
MySQL> show databases;
MySQL> set names utf8;
MySQL> select * from readme;
+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+-----------------------+
| id | readme | BTC_address | email |
+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+-----------------------+
| 1 | 以下数据库已被删除:rpa_cs, rpa_lic, rpa_orc_serv, rpa_orc_trig, rpa_orc_wf。 我们有完整的备份。 要恢复它,您必须向我们的比特币地址bc1qr6n7hd72lzt0ew27mwlql5nnstgxfa2zhmuf8k支付0.0206比特币(BTC)。 如果您需要证明,请通过以下电子邮件与我们联系。 xiao2945@tutanota.com 。 任何与付款无关的邮件都将被忽略! | bc1qr6n7hd72lzt0ew27mwlql5nnstgxfa2zhmuf8k | xiao2945@tutanota.com |
+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+-----------------------+
1 row in set (0.00 sec)
2、查看数据库error.log和OS-messages
# 1、查看error.log过滤是否有非内网地址的IP连接到数据库
vim /data/cyclone/rpaplatform/data/middleware/mysql/error.log
# 2、查看操作系统日志在/var/log/最新的messages
是否能找到异常IP登录服务器信息
# 3、云厂商提供的环境建议由客户反馈给云厂商进行排查
三、数据库被勒索删除恢复
利用最后一次数据库全备+log-bin恢复数据,通过error.log和log-bin确认数据库被删除的最早时间。
1、利用全量log-bin恢复数据
解析log-bin恢复至删库时间点前的数据,需要有全量的log-bin日志。
# 1、确认要恢复的终点位置即被黑客删库的位置
mysqlbinlog -v mysql-bin.000001 | grep -i "drop database testdb"mysqlbinlog -v mysql-bin.000002 | grep -i "drop database testdb"mysqlbinlog -v mysql-bin.000003 | grep -i "drop database testdb"drop database testdb
# 解析mysql-bin.000003获取删库的准确位置
mysqlbinlog --no-defaults --base64-output=decode-rows mysql-bin.000003 >./2.sql#220811 16:01:40 server id 13306 end_log_pos 687 GTID last_committed=2 sequence_number=3 rbr_only=noSET @@SESSION.GTID_NEXT= '14f8109c-194b-11ed-9b55-0242ac110002:8'/*!*/;# at 687#220811 16:01:40 server id 13306 end_log_pos 786 Query thread_id=2 exec_time=0 error_code=0SET TIMESTAMP=1660204900/*!*/;drop database testdb删除数据库的位置为3号日志文件的687位置,恢复的终点可以设置为:3号日志的687。
# 2、mysqlbinlog常用选项
--start-position=55 起始pos点
--stop-position=555 结束pos点
--start-datetime="2019-11-29 13:00:00" 起始时间点
--stop-datetime="2019-11-29 17:00:00" 结束时间点
--database=douyin 指定只恢复douyin数据库(一台主机上往往有多个数据库,只限本地log日志)
--skip-gtids=true 如果是要恢复数据到源数据库或者和源数据库有相同GTID信息的实例,那么就要使用--skip-gtids=true参数。如果不带该参数的话,是无法恢复成功的。因为包含的GTID已经在源数据库执行过了,根据GTID特性,一个GTID信息在一个数据库只能执行一次,所以不会恢复成功。
# 3、开始恢复
# 终止日志前文件
mysqlbinlog --no-defaults mysql-bin.000001 mysql-bin.000002 --skip-gtids=true |mysql -uroot -p
# 终止日志文件
mysqlbinlog --no-defaults mysql-bin.000003 --stop-position=687 --skip-gtids=true |mysql -uroot -p
2、基于mysqldump全备和部分log-bin恢复数据
基于最后一次全备,解析log-bin恢复最后一次全备至删库时间点的数据。
# 1、确认mysqldump备份到的最终位置
cat dball.sql |grep "CHANGE MASTER TO MASTER_LOG_FILE"
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1235;
备份到了1号日志的1235位置,恢复的起点可以设置为:1号日志的1235。
# 2、确认要恢复的终点位置即被黑客删库的位置
mysqlbinlog -v mysql-bin.000001 | grep -i "drop database testdb"
mysqlbinlog -v mysql-bin.000002 | grep -i "drop database testdb"
mysqlbinlog -v mysql-bin.000003 | grep -i "drop database testdb"
drop database testdb
# 解析mysql-bin.000003获取删库的准确位置
mysqlbinlog --no-defaults --base64-output=decode-rows mysql-bin.000003 >./3.sql
#220811 16:01:40 server id 13306 end_log_pos 687 GTID last_committed=2 sequence_number=3 rbr_only=no
SET @@SESSION.GTID_NEXT= '14f8109c-194b-11ed-9b55-0242ac110002:8'/*!*/;
# at 687
#220811 16:01:40 server id 13306 end_log_pos 786 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1660204900/*!*/;
drop database testdb
删除数据库的位置为3号日志文件的687位置,恢复的终点可以设置为:3号日志的687。
# 3、开始全量备份恢复+binlog增量恢复
# 全量恢复
mysql -uroot -pmysql < /var/lib/mysql/dball.sql
# binlog增量恢复
# 这里分为3条命令执行,起始日志文件涉及到参数start-position参数,单独执行;中间的日志文件不涉及到特殊参数,全部一起执行; 中止文件涉及到stop-position参数,单独执行。
# 起始日志文件
mysqlbinlog --no-defaults mysql-bin.000001 --start-position=1235 --skip-gtids=true |mysql -uroot -p
# 中间日志文件
mysqlbinlog --no-defaults mysql-bin.000002 |mysql -uroot -p
# 终止日志文件
mysqlbinlog --no-defaults mysql-bin.000003 --stop-position=687 --skip-gtids=true |mysql -uroot -p
3、总结
# 1.对于DML操作,binlog记录了所有的DML数据变化:
--对于insert,binlog记录了insert的行数据
--对于update,binlog记录了改变前的行数据和改变后的行数据
--对于delete,binlog记录了删除前的数据
假如用户不小心误执行了DML操作,可以使用mysqlbinlog将数据库恢复到故障点之前。
# 2.对于DDL操作,binlog只记录用户行为,而不记录行变化,但是并不影响我们将数据库恢复到故障点之前。
总之,使用mysqldump全备加binlog日志,可以将数据恢复到故障前的任意时刻。
四、后续调整
# 1、不要对外网暴露3306端口,或者安装数据库时更改数据库端口
# 2、大权限用户,host不要设置%,设定内网IP段,或特定IP访问
# 3、对大权限用户密码加固
# 4、做好数据库备份和binlog日志备份
本文来自博客园,作者:up~up,转载请注明原文链接:https://www.cnblogs.com/soft-engineer/articles/16596371.html
浙公网安备 33010602011771号