盒子
盒子
文章目录
  1. 0.背景
  2. 1.查看SSH登录情况
  3. 2.数据恢复
  4. 3.防御措施
  5. 4.其他防范建议
  6. 5.总结

CentOS服务器防护策略 & 从binlog恢复MySQL数据

0.背景

  最近,著名的B507全栈实验室打造了一套Git系统,让小伙伴们往我们自有的Git系统上迁移项目,目的是便于管理,也便于大家相互学习。但是,没想到安全策略没做,很快就被暴力破解了。黑客删除了我们的数据库,并留下如下信息:

1
To recover your lost databases and avoid leaking it: visit http://hn4wg4o6s5nc7763.onion and enter your unique token 5bfd6d74fbb45a0a and pay the required amount of Bitcoin to get it back. Databases that we have: xxx, xxx. Your databases are downloaded and backed up on our servers. If we dont receive your payment in the next 9 Days, we will sell your database to the highest bidder or use them otherwise. To access this site you have use the tor browser https://www.torproject.org/projects/torbrowser.html

1.查看SSH登录情况

  CentOS 可以通过命令查看相关的登录情况,方便判断服务器的受攻击情况。

  • lastlog 查看所有用户最近(最新一条)的登录信息,主要包括 IP 和时间;
  • last 查看最近多条(包括当前已登录)登录信息用户信息,主要包括 IP、登录时间范围和时长;
  • lastb 查看失败尝试的登录信息。

  使用如下命令可统计指定用户名的登录失败的 IP 情况,可以不使用 grep 命令,即可统计所有用户:

1
lastb | grep user_name | awk '{print $3}' | sort | uniq -c | sort -nr | more

  使用如下命令可统计被尝试最多的用户名:

1
lastb | awk '{print $1}' | sort | uniq -c | sort -nr | more

2.数据恢复

  发现被攻击后,我登录服务器,查看了SSH相关日志,确定服务器一直在被尝试暴力破解,每秒都在遭受大量的攻击。既然都攻破了,那先就不管吧,我决定看看数据有没有恢复的可能性。

  查看 /etc/my.cnf 发现 MySQL 开启了 binlog 日志,索性检查一下日志是否还在,尝试恢复,步骤大致如下:

  • 使用 find / -name "binlog*",找到了位于 /usr/local/lighthouse/softwares/btpanel/server/data 路径下的 binlog 文件;

  • 找到 MySQL 的 bin 目录,例如 /www/server/mysql/bin,其中有一个名为 mysqlbinlog 的可执行文件;

  • 将 binlog 文件拷贝到 bin 目录下,例如 mysql-bin.000001 文件,并执行 mysqlbinlog mysql-bin.000001 -d database_name > database_name.sql,导出成 SQL 语句。

  查看 database_name.sql 文件,可以看到如下信息,而真正有用的 SQL 语句并不多,且不能直接使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#200930 13:26:59 server id 1 end_log_pos 120 CRC32 0x877fe63c Start: binlog v 4, server v 5.6.49-log created 200930 13:26:59 at startup
ROLLBACK/*!*/;
...
# at 48733
#201009 14:50:46 server id 1 end_log_pos 48867 CRC32 0x63a2bb70 Query thread_id=498 exec_time=0 error_code=0
SET TIMESTAMP=1602226246/*!*/;
UPDATE access SET mode = 3 WHERE user_id = 5 AND repo_id = 1
/*!*/;
# at 48867
#201009 14:50:46 server id 1 end_log_pos 48898 CRC32 0x5f1fd816 Xid = 8965
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

  这里写了一段简单的 Java 代码进行处理,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
//BufferedReader是可以按行读取文件
FileInputStream inputStream = new FileInputStream("C:\\database_name.sql");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
BufferedWriter out = new BufferedWriter(new FileWriter("C:\\database_name_out.sql"));
String str = null;
while((str = bufferedReader.readLine()) != null) {
if (str.startsWith("INSERT") || str.startsWith("UPDATE") || str.startsWith("DELETE")) {
System.out.println(str);
out.write(str + ";\n");
}
}
//close
inputStream.close();
bufferedReader.close();
out.close();
}
}

  处理完成之后,就可以导入 SQL 文件到 MySQL 中,数据基本就恢复了。

3.防御措施

  早在 VPS防止SSH暴力登录尝试攻击 一文中,我就已经提到过使用 DenyHosts 进行防御的方法,之前是基于 Ubuntu 的,本次是 CentOS,过程略有不同。

  • 下载最新版 denyhosts,执行命令 wget https://sourceforge.net/projects/denyhosts/files/latest/download -O denyhosts-lastest.zip
  • 解压文件,unzip denyhosts-lastest.zip
  • 进入其文件夹,例如我这里下载的最新版是 2.10cd denyhosts-2.10
  • 如果未安装 Python ,请使用命令安装:yum install python2 –y
  • 安装 DenyHostspython setup.py install

  安装完成后,在进行相关配置,并启动服务。

  • 先进入 /etc ,编辑 denyhosts.conf 文件,将原本的 SECURE_LOG 属性注释掉,解掉 Redhat or Fedora Core 下的注释;
  • 进入 /usr/bin 目录,编辑 daemon-control-dist 文件,将 DENYHOSTS_BIN 属性从 "/usr/local/bin/denyhosts-2.10/denyhosts.py" 改为 "/usr/bin/denyhosts.py"
  • 启动前,最好删除 /var/log/secure 文件,重新开始记录;
  • 使用命令 daemon-control-dist start 启动服务。

  启动完成后,可以使用命名 tailf /var/log/secure 查看不断在尝试登录的 IP 地址,同时使用命令 tailf /etc/hosts.deny 查看文件是否有源源不断地添加攻击者 IP ,有则服务生效。但注意将 ALL: 127.0.0.1 先加入 /etc/hosts.allow 中,以免出现本地都无法访问的情况。

4.其他防范建议

  • 建议为不同的服务,新建一个 MySQL 用户,并在创建完所需要的表后,revoke 掉不必要的权限,例如新增或删除表;
  • 禁止 MySQL 用户直接远程登录;
  • 在遭受攻击后,及时更改服务器用户密码和 MySQL 用户密码;
  • 最后,编写脚本,定时备份数据库,并通过 crontab -e 命令,在末尾添加 0 * * * * /path/to/back_db.sh > /dev/null 2>&1 &,即每小时定时备份数据库:
1
2
3
4
5
6
#! /bin/sh
yestoday=$(date "+%Y%m%d-%H" -d "-24hour")
time=$(date "+%Y%m%d-%H")
rm -f /path/to/bak/$yestoday.sql
mysqldump -uroot -p123456 --databases database_name -y > /path/to/bak/$time.sql

  设置完成后,可通过 /var/log/cron 日志看到执行情况。

5.总结

  虽然不是什么特别重要的数据,但这个故事告诉我们,服务器首先得做安全措施,然后再部署服务。并且,无论是SSH还是MySQL,都不应该使用常见的弱密码。

转载请注明出处,无偿提供。

支持一下
感谢大佬们的支持