【运维安全】文件误删除恢复实战

本文涉及的产品
运维安全中心(堡垒机),免费版 6个月
简介: 趁着你对象吃泡面的功夫,我修复了误删除的文件

在这里插入图片描述
@[toc]

前言

如果你一不小心删除了文件,该如何恢复?

这句话已经成了面试官口中的高频面试题,作为运维的你,真的知道如何恢复吗?快来跟我一起查缺补漏,通过一个实战案例来实现误删除文件的恢复吧。

一. linux下文件删除原理

1.1 文件删除原理的简单介绍

简单的说,文件系统由文件名,inode,block 三部分组成。

当一个文件要申请inode,首先GDT检索然后跳到inode位图看哪的inode空闲,把stat存到inode,然后开始写文件内容。

如果要删除文件,其实就是将数据块block bit map置0,inodebitmap置0,所以删除很快,而数据内容在磁盘还在相应的数据块。

在inode中并没有文件名这个信息, 因为电脑是根据inode来判断文件的。

那么文件名存放在什么位置呢?

答案是: 存在目录中,根目录的inode默认为2,寻找文件名会从根目录开始:

一般的寻址过程,找到目录的数据块,匹配记录项,文件名,再找到inode编号。

这里有两个通识:

  • 删除文件其实删除的inode
  • inode号一旦释放,若有其他文件申请到了这个刚刚释放的inode号,对应这个inode号位置的数据就会被覆盖。

1.2 测试inode号是否容易被覆盖?

## 创建测试 目录
[root@mufeng71 ~]# mkdir test
# 创建测试文件
[root@mufeng71 ~]# touch a.txt
## 查看文件的inode
[root@mufeng71 ~]# ls -i a.txt
34503763 a.txt
## 删除文件后,再次创建a.txt,看是否还是原来的inode号
[root@mufeng71 ~]# rm -rf a.txt
[root@mufeng71 ~]# touch a.txt
[root@mufeng71 ~]# ls -i a.txt
33803902 a.txt
## 如果第一次与原来不同,可能是正好有缺省的inode,可以再次测试
[root@mufeng71 ~]# rm -rf a.txt
[root@mufeng71 ~]# touch a.txt
[root@mufeng71 ~]# ls -i a.txt
33803902 a.txt
## 这里第二次测试的时候,发现inode和被删除时候的inode一致
[root@mufeng71 ~]# touch b.txt
## 创建一个不同的文件名测试
[root@mufeng71 ~]# ls -i b.txt
33803903 b.txt
[root@mufeng71 ~]# rm -rf b.txt 
[root@mufeng71 ~]# touch b.txt
[root@mufeng71 ~]# ls -i b.txt
33803903 b.txt
##测试创建文件名不同,占用inode是相同的吗?
[root@mufeng71 ~]# rm -rf b.txt 
[root@mufeng71 ~]# touch c.txt
[root@mufeng71 ~]# touch b.txt
[root@mufeng71 ~]# ls -i b.txt
33803903 b.txt
[root@mufeng71 ~]# ls -i c.txt
33803901 c.txt
[root@mufeng71 ~]# rm -rf c.txt
[root@mufeng71 ~]# touch d.txt
[root@mufeng71 ~]# ls -i d.txt
33803901 d.txt
## 可以看到即使文件名不同,inode也有可能相同

根据以上代码测试,我们总结出一个规律:

  • inode的申请是随机的,申请到的必然是空闲的inode
  • inode指向block (真正存放数据的地方)

那我们是否可以通过inode号来恢复数据?

二. 实验测试过程

2.1 实验环境:

[root@mufeng71 ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)

2.2 新增一块硬盘测试

选择硬盘-添加添加,如下图:

image-20220518151437271
创建新的磁盘
image-20220518151527399
指定磁盘容量并设置存储为单个文件
image-20220518151629177

新增磁盘结束之后,开启虚拟机

2.3 对磁盘分区

2.3.1 分区(使用fdisk分区)

[root@mufeng71 ~]# ll /dev/sdb*
brw-rw----. 1 root disk 8, 16 5月  18 23:16 /dev/sdb
[root@mufeng71 ~]# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x95ad17d7.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

...

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-2610, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +5G

Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x95ad17d7

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         654     5253223+  83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[root@mufeng71 ~]# ll /dev/sdb*
brw-rw----. 1 root disk 8, 16 5月  18 23:19 /dev/sdb
brw-rw----. 1 root disk 8, 17 5月  18 23:19 /dev/sdb1

2.3.2 格式化,创建目录挂载

创建挂载目录

[root@mufeng71 ~]# mkdir /tmp/sdb1

开始格式化

[root@mufeng71 ~]# mkfs.ext4 /dev/sdb1
mke2fs 1.41.12 (17-May-2010)
文件系统标签=
操作系统:Linux
块大小=4096 (log=2)
分块大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
328656 inodes, 1313305 blocks
65665 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=1346371584
41 block groups
32768 blocks per group, 32768 fragments per group
8016 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736

正在写入inode表: 完成                            
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

进行目录挂载

挂载目录:
[root@mufeng71 ~]# mount /dev/sdb1 /tmp/sdb1
[root@mufeng71 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        20G  3.5G   15G  20% /
tmpfs           2.2G   72K  2.2G   1% /dev/shm
/dev/sda1       190M   40M  140M  23% /boot
/dev/sdb1       4.9G   11M  4.6G   1% /tmp/sdb1

2.3.3 创建测试文件

[root@mufeng71 ~]# cp /etc/passwd /tmp/sdb1
[root@mufeng71 ~]# cp /etc/hosts /tmp/sdb1
[root@mufeng71 ~]# echo aaa > a.txt
[root@mufeng71 ~]# mkdir -p /tmp/sdb1/a/b/c
[root@mufeng71 ~]# cp a.txt  /tmp/sdb1/a
[root@mufeng71 ~]# cp a.txt  /tmp/sdb1/a/b
[root@mufeng71 ~]# touch !$/kong.txt
touch /tmp/sdb1/a/b/kong.txt
/etc/passwd  

创建完成后查看目录结构:

## 镜像挂载
[root@mufeng71 sdb1]# mount /dev/cdrom /mnt
mount: block device /dev/sr0 is write-protected, mounting read-only

## 安装tree命令
[root@mufeng71 sdb1]# yum install tree*
## 使用tree命令查看
[root@mufeng71 sdb1]# tree
.
├── a
│   ├── a.txt
│   └── b
│       ├── a.txt
│       ├── c
│       └── kong.txt
├── hosts
├── lost+found
└── passwd

4 directories, 5 files

2.3.4 删除文件测试

将文件全部删掉,并查看:

[root@mufeng71 sdb1]# ls
a  hosts  lost+found  passwd
[root@mufeng71 sdb1]# rm -rf ./*

删除文件后,为了防止数据被覆盖掉:
卸载分区,或者设置为只读,我们再此处用卸载分区的方法:

[root@mufeng71 ~]# umount /dev/sdb1
[root@mufeng71 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        20G  3.5G   15G  20% /
tmpfs           2.2G   72K  2.2G   1% /dev/shm
/dev/sda1       190M   40M  140M  23% /boot
/dev/sr0        3.7G  3.7G     0 100% /mnt
[root@mufeng71 ~]# 

2.3.5 安装工具extundelte

使用工具 extundelete进行数据恢复,可以提前下载好,然后用rz命令上传。

若没有rz命令,需要提前使用 yum进行安装

[root@mufeng71 ~]# yum install lr*

安装完成后,执行rz,然后选择你要上传的包即可, 传完后可以在虚拟机查看到此文件:

上传完成:

[root@mufeng71 ~]# ls extundelete-0.2.4.tar.bz2
 extundelete-0.2.4.tar.bz2

安装extundelete

安装环境:
[root@mufeng71 ~]# yum install gcc* 
[root@mufeng71 extundelete-0.2.4]# yum install e2fsprogs-devel

解压并开始进行安装

[root@mufeng71 ~]# tar xf extundelete-0.2.4.tar.bz2 
[root@mufeng71 ~]# cd extundelete-0.2.4

开始编译安装

[root@mufeng71 extundelete-0.2.4]# ./configure 
Configuring extundelete 0.2.4
Writing generated files to disk
[root@mufeng71 extundelete-0.2.4]# make && make install

2.3.6 使用工具去恢复数据

1. 查看之前被删除的文件的inode号


[root@mufeng71 test]# extundelete /dev/sdb1 --inode 2
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Group: 0
Contents of inode 2:
................

File name                                       | Inode number | Deleted status
.                                                 2
..                                                2
lost+found                                        11             Deleted
passwd                                            12             Deleted
hosts                                             13             Deleted
a                                                 128257         Deleted
[root@mufeng71 test]# 

2. 通过inode号来恢复

目前inode 12 是passwd文件,我们直接用inode号进行恢复即可:

[root@mufeng71 test]# extundelete /dev/sdb1  --restore-inode 12
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
[root@mufeng71 test]# ls
RECOVERED_FILES
[root@mufeng71 test]# cd RECOVERED_FILES/
[root@mufeng71 RECOVERED_FILES]# ls
file.12
## 使用md5测试,发现和源文件一致
[root@mufeng71 RECOVERED_FILES]# md5sum file.12 /etc/passwd
53baee54724c650df260e45099a82100  file.12
53baee54724c650df260e45099a82100  /etc/passwd
[root@mufeng71 RECOVERED_FILES]# 

3. 通过文件名来恢复

[root@mufeng71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-file passwd
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Successfully restored file passwd
[root@mufeng71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@mufeng71 RECOVERED_FILES]# ls
passwd
[root@mufeng71 RECOVERED_FILES]# md5sum passwd /etc/passwd
53baee54724c650df260e45099a82100  passwd
53baee54724c650df260e45099a82100  /etc/passwd
[root@mufeng71 RECOVERED_FILES]# 

4. 通过目录名字来恢复

[root@mufeng71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-directory a
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Searching for recoverable inodes in directory a ... 
8 recoverable inodes found.
Looking through the directory structure for deleted files ... 
4 recoverable inodes still lost.
[root@mufeng71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@mufeng71 RECOVERED_FILES]# ls
a
[root@mufeng71 RECOVERED_FILES]# tree a
a
├── a.txt
└── b
    └── a.txt

1 directory, 2 files
[root@mufeng71 RECOVERED_FILES]# 

5. 一次性恢复所有文件

[root@mufeng71 RECOVERED_FILES]# extundelete /dev/sdb1  --restore-all
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 41 groups loaded.
Loading journal descriptors ... 62 descriptors loaded.
Searching for recoverable inodes in directory / ... 
8 recoverable inodes found.
Looking through the directory structure for deleted files ... 
0 recoverable inodes still lost.
[root@mufeng71 RECOVERED_FILES]# cd RECOVERED_FILES/
[root@mufeng71 RECOVERED_FILES]# ls
a  hosts  passwd
[root@mufeng71 RECOVERED_FILES]# tree
.
├── a
│   ├── a.txt
│   └── b
│       └── a.txt
├── hosts
└── passwd

2 directories, 4 files
[root@mufeng71 RECOVERED_FILES]# 

image-20220518160434915
有没有发现空文件和空目录没有被恢复? 这是因为 在ext4系统中,默认会认为空文件和空目录没有恢复的必要。但在XFS系统中,由于有默认的备份机制,空文件和空目录是可以恢复的。

写在最后

✨原创不易,还希望各位大佬支持一下
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!
相关文章
|
2月前
|
缓存 运维 监控
运维之道:从故障响应到系统优化的实战之旅
在信息技术飞速发展的今天,高效、可靠的系统运维已成为企业IT部门的核心任务。本文将通过一系列真实案例分析,深入探讨运维团队如何从日常的故障响应出发,逐步过渡到系统性能的深度优化。我们将一起探索运维的最佳实践,包括自动化工具的应用、性能监控的重要性以及如何构建一个弹性和高可用性的系统架构。文章旨在为读者提供一套完整的运维解决方案,帮助他们在面对复杂多变的技术环境时,能够迅速定位问题并实施有效的解决策略。
161 0
|
27天前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19257 28
|
3月前
|
运维 监控 关系型数据库
运维实战:Windows服务挂掉了怎么办,通过Bat脚本实现自动重启
本文介绍了如何使用Bat脚本自动监控并重启Windows服务器上的挂掉服务,例如MySQL,以避免在假期等情况下需要紧急处理问题。首先,创建一个Bat脚本,设定每小时检查一次服务状态,如果服务停止则自动重启。脚本内容包括检查服务是否运行并根据状态执行相应操作。同时,脚本中包含了确保以管理员权限运行的代码。 脚本需设置为ANSI编码以防止乱码。推荐将Bat脚本封装为Windows服务以保证稳定运行,提供了使用NSSM工具、Windows服务程序和开源的Java工具winsw将批处理脚本转化为服务的方法。这些方法可以确保服务在后台可靠运行,即使在服务意外停止时也能自动恢复。
|
4月前
|
运维 监控 安全
构建高效自动化运维体系:Ansible与Docker的协同实战
【5月更文挑战第25天】 在当今快速迭代的软件发布环境中,自动化运维成为确保部署效率和可靠性的关键。本文通过深入分析Ansible和Docker技术,探索它们如何协同工作以构建一个高效的自动化运维体系。文章不仅介绍了Ansible的配置管理功能和Docker容器化的优势,还详细阐述了将两者结合的实践策略,旨在帮助读者理解并实现更智能、更灵活的基础设施管理。
|
4月前
|
运维 Oracle 容灾
Oracle dataguard 容灾技术实战(笔记),教你一种更清晰的Linux运维架构
Oracle dataguard 容灾技术实战(笔记),教你一种更清晰的Linux运维架构
|
2月前
|
人工智能 运维 Cloud Native
实战基于阿里云的AIGC在运维领域的探索
传统运维模式已难以应对日益复杂的海量数据和业务需求,效率低下,故障难解。而人工智能的崛起,特别是AIGC技术的出现,为运维领域带来了新的机遇。AIGC能够自动生成运维脚本、分析海量数据,预测潜在故障,甚至提供解决方案,为运维工作注入智能化力量,推动运维向更高效、更智能的方向发展。
16334 19
实战基于阿里云的AIGC在运维领域的探索
|
17天前
|
运维 监控 应用服务中间件
自动化运维的新篇章:Ansible Playbooks入门与实战
【9月更文挑战第1天】在追求效率和稳定性的今天,自动化运维已经成为IT行业的必修课。本文将带你走进自动化工具Ansible的世界,通过实战案例深入理解Ansible Playbooks的编写和应用。文章不仅介绍基础概念,更通过具体代码示例,展示如何利用Ansible简化日常运维任务,提升工作效率。无论你是运维新手还是希望深化自动化技能的资深人士,本指南都将为你开启一段新的学习旅程。
|
19天前
|
运维 安全 应用服务中间件
自动化运维的利器:Ansible入门与实战网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【8月更文挑战第30天】在当今快速发展的IT时代,自动化运维已成为提升效率、减少错误的关键。本文将介绍Ansible,一种流行的自动化运维工具,通过简单易懂的语言和实际案例,带领读者从零开始掌握Ansible的使用。我们将一起探索如何利用Ansible简化日常的运维任务,实现快速部署和管理服务器,以及如何处理常见问题。无论你是运维新手还是希望提高工作效率的资深人士,这篇文章都将为你开启自动化运维的新篇章。
|
21天前
|
运维 Ubuntu 应用服务中间件
自动化运维的利器:Ansible入门与实战应用
【8月更文挑战第28天】在现代IT运维领域,自动化已成为提升效率、确保一致性和可靠性的关键。本文将引导读者了解Ansible——一种流行的自动化工具,它通过简化配置管理、部署和任务自动化流程,助力运维人员轻松应对日常挑战。从基础安装到高级用法,我们将一步步探索Ansible的魔力,并通过实际案例展示如何有效利用Ansible优化运维工作。无论你是初学者还是有经验的管理员,这篇文章都将为你提供宝贵的知识和技能,让你的运维之旅更加顺畅。
|
23天前
|
缓存 运维 Linux
深入解析:一步步掌握 CentOS 7 安装全流程及运维实战技巧
深入解析:一步步掌握 CentOS 7 安装全流程及运维实战技巧