我们都知道windows系统有个回收站,凡是被删除的文件都可以通过回收站来恢复数据,即便是按住shift键永久删除了,也有很多数据恢复软件可供使用。那么Linux下如果数据被删除了,又该如何恢复呢,Linux系统可没有回收站,只能通过数据恢复软件来解决了。
Linux系统有很多开源的数据恢复工具,例如:debugfs、R-Linux、ext3grep、extundelete等,那么我要给大家介绍的是extundelete,这款工具是用来恢复ext格式(ext3、ext4等)的文件系统被误删除的数据。

一、extundelete恢复原理

在介绍使用extundelete进行恢复数据之前,我们来简单了解一下inode的知识。在Linux下可以通过“ls -id”命令来查看某个文件或目录的inode值,例如查看根目录的inode值,可以输入:

[root@localhost ~]# ls -id /
64 /

Linux系统通过rm等命令删除文件或目录,仅仅是将文件的inode结点中的扇区指针清零,实际文件或目录还存储在磁盘上,这些已被删除的数据块在还没有被系统重新分配出去之前,也就是说在还没有被新的数据覆盖之前,这些数据都还没有真正丢失。
使用extundelete恢复文件时并不依赖特定文件格式,首先extundelete会通过文件系统的inode信息来获得当前文件系统下所有文件的信息,包括存在的和已经删除的文件,这些信息包括文件名和inode。然后通过inode信息结合日志去查询该inode所在的block位置,包括直接块、间接块等信息。最后利用dd命令将这些信息备份出来,从而恢复数据文件。

二、安装extundelete软件

extundelete已经很久没有更新了,目前最新版本是extundelete-0.2.4。在安装extundelete之前需要安装e2fsprogs和e2fsprogs-libs两个依赖包。

[root@localhost tmp]# wget http://zy-res.oss-cn-hangzhou.aliyuncs.com/server/extundelete-0.2.4.tar.bz2
[root@localhost tmp]# yum -y install bzip2 e2fsprogs-devel e2fsprogs gcc-c++ make
[root@localhost tmp]# tar jxvf extundelete-0.2.4.tar.bz2
[root@localhost tmp]# cd extundelete-0.2.4
[root@localhost extundelete-0.2.4]# ./configure
[root@localhost extundelete-0.2.4]# make && make install

成功安装extundelete后,系统中会生成一个extundelete可执行文件,可通过“extundelete --help”获得此命令的使用方法。

三、extundelete命令使用方法

命令格式: extundelete [options] [--] device-file
其中,参数(options)有:
--version, -[vV],显示软件版本号。
--help,显示软件帮助信息。
--superblock,显示超级块信息。
--journal,显示日志信息。
--after dtime,时间参数,表示在某段时间之后被删的文件或目录。
--before dtime,时间参数,表示在某段时间之前被删的文件或目录。
动作(action)有:
--inode ino,显示节点“ino”的信息。
--block blk,显示数据块“blk”的信息。
--restore-inode ino[,ino,...],恢复命令参数,表示恢复节点“ino”的文件,恢复的文件会自动放在当前目录下的RESTORED_FILES文件夹中,使用节点编号作为扩展名。
--restore-file 'path',恢复命令参数,表示将恢复指定路径的文件,并把恢复的文件放在当前目录下的RECOVERED_FILES目录中。
--restore-files 'path',恢复命令参数,表示将恢复在路径中已列出的所有文件。
--restore-all,恢复命令参数,表示将尝试恢复所有目录和文件。
-j journal,表示从已经命名的文件中读取扩展日志。
-b blocknumber,表示使用之前备份的超级块来打开文件系统,一般用于查看现有超级块是不是当前所要的文件。
-B blocksize,通过指定数据块大小来打开文件系统,一般用于查看已经知道大小的文件。

四、使用extundelete恢复数据(测试)

(1)模拟删除数据
创建一个分区,并将该分区格式化为ext3,将此分区挂载到/data目录下,拷贝一些目录和文件到/data下,并删除一些文件和目录。
注:经过测试,ext4格式的分区数据恢复失败,看来extundelete还不支持ext4文件系统。

[root@localhost ~]# mkfs.ext3 /dev/sdb1
[root@localhost ~]# mkdir /data
[root@localhost ~]# mount /dev/sdb1 /data
[root@localhost ~]# cp -r /tmp/extundelete-0.2.4 /data/
[root@localhost ~]# cp /etc/redhat-release /data/
[root@localhost ~]# mkdir /data/test
[root@localhost ~]# echo "测试文件" > /data/test/test.txt
[root@localhost ~]# md5sum /data/redhat-release 
137e28b464c4b8e6e4347b36621a38ab  /data/redhat-release
[root@localhost ~]# md5sum /data/test/test.txt 
65be68a792b7ef18ae268b80e15dd55e  /data/test/test.txt
[root@localhost ~]# rm -rf /data/*

(2)数据恢复前的准备工作
一定要记住,数据一旦被误删除后,马上卸载这块磁盘分区。
[root@localhost ~]# umount /data/
查询可恢复的数据信息
注:/data是根分区,根分区的inode一般都为2。

extundelete /dev/sdb1 --inode 2
……
File name                                       | Inode number | Deleted status
.                                                 2
..                                                2
lost+found                                        11             Deleted
extundelete-0.2.4                                 524289         Deleted
redhat-release                                    12             Deleted
test                                              393217         Deleted

标注为Deleted的是已经删除的文件或目录,还有对应的inode值。
(3)恢复单个文件

[root@localhost /]# extundelete  /dev/sdb1 --restore-file redhat-release
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 80 groups loaded.
Loading journal descriptors ... 67 descriptors loaded.
Successfully restored file redhat-release
[root@localhost /]# cd RECOVERED_FILES/
[root@localhost RECOVERED_FILES]# md5sum redhat-release 
137e28b464c4b8e6e4347b36621a38ab  redhat-release

恢复单个文件使用参数“--restore-file”,恢复单个目录使用参数“--restore-directory”,需要使用文件的相对路径。/data是根目录,redhat-release文件的绝对路径是/data/redhat-release,相对路径便是redhat-release。
文件恢复成功后,在执行extundelete命令的当前目录下会创建一个RECOVERED_FILES目录,用于存放恢复出来的文件。
根据MD5码来看,redhat-release文件恢复成功。
(4)恢复单个目录

[root@localhost /]# extundelete /dev/sdb1 --restore-directory /test
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 80 groups loaded.
Loading journal descriptors ... 67 descriptors loaded.
Searching for recoverable inodes in directory /test ... 
57 recoverable inodes found.
Looking through the directory structure for deleted files ... 
56 recoverable inodes still lost.
[root@localhost /]# cd RECOVERED_FILES/
[root@localhost RECOVERED_FILES]# md5sum test/test.txt 
65be68a792b7ef18ae268b80e15dd55e  test/test.txt
[root@localhost RECOVERED_FILES]# cat test/test.txt 
测试文件

(5)恢复所有数据
使用“--restore-all”参数来恢复所有被删除的文件和目录。

[root@localhost /]# extundelete  /dev/sdb1 --restore-all
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 80 groups loaded.
Loading journal descriptors ... 67 descriptors loaded.
Searching for recoverable inodes in directory / ... 
57 recoverable inodes found.
Looking through the directory structure for deleted files ... 
0 recoverable inodes still lost.
[root@localhost /]# cd RECOVERED_FILES/
[root@localhost RECOVERED_FILES]# ls
extundelete-0.2.4  redhat-release  redhat-release.v1  test
[root@localhost RECOVERED_FILES]# du -sh extundelete-0.2.4/
5.2M    extundelete-0.2.4/

通过以上信息看到数据全部都恢复成功了。
(6)按时间段恢复数据
使用“--after”和“--before”参数,可以指定某个时间段,恢复这个时间段删除的数据,需要使用总秒数,可通过“date +%s”命令查看。

[root@localhost RECOVERED_FILES]# date +%s
1537513612
extundelete --after 1537513612 --restore-all /dev/sdb1  #恢复某个时间点之后删除的数据
extundelete --before 1537513612 --restore-all /dev/sdb1  #恢复某个时间点之前删除的数据
extundelete --after 1537513612 --before 1537513755 --restore-all /dev/sdb1  #恢复一个时间段内删除的数据

恢复时间段数据的测试内容我就不写了,大家可自行测试。