数据恢复(一)-linux下ext文件系统数据删除原理浅析
nanshan 2024-12-26 15:43 9 浏览 0 评论
rm 删除文件过程
应急工作中经常会遇到日志或关键信息文件等被删除的情况,为溯源排查带来了不小的阻碍。但是大多数文件被删除的情况都并非真正意义上的删除(除非文件block位置已经被覆盖),数据还在磁盘上都是有恢复的可能。本文对linux下文件系统的文件删除机制并结合相关删除的案例进行分析。
导语
这是数据恢复系列的第一篇文章,先了解linux下文件删除的机制,才能弄明白恢复如何去恢复文件。本文希望尽可能简单地阐述清楚。因为太偏底层的东西,大家不愿意看或许看不懂,所以就不打算写的太深入。先从最简单的开始,所见即所得。
实验环境
- 腾讯云 CVM 一台
- 操作系统 centos7
- 文件系统 ext4
先抛出一个非常基础的问题?
linux上如何直接从磁盘上读取文件内容?
正常读取一个文件,通常是使用命令后面跟上文件的路径。
command [filepath] # 例如 cat /etc/passwd
如果使用cat这类文件读取的命令,能否直接从磁盘上读取到 /etc/passwd 文件的内容?
答案是可以的,但需要先理解 inode(索引节点)的概念。
理解inode,文件索引节点
以ext4为例,文件储存在硬盘上,硬盘的最小存储单位叫做”扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。这种由多个扇区组成的”块”,是文件存取的最小单位。“块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。
文件系统将文件的实际内容和属性分开存放
- 文件的属性保存在 inode 中(i 节点)中,每个 inode 都有自己的编号。每个文件各占用一个 inode。不仅如此,inode 中还记录着文件数据所在 block 块的编号;
- 文件的实际内容保存在 block 中(数据块),类似衣柜的隔断,用来真正保存衣物。每个 block 都有属于自己的编号。当文件太大时,可能会占用多个 block 块。
- 另外,还有一个 super block(超级块)用于记录整个文件系统的整体信息,包括 inode 和 block 的总量、已经使用量和剩余量,以及文件系统的格式和相关信息等。
获取文件的inode
获取文件inode最简单的办法就是用 ls -i 打印。
[root@VM-0-15-centos ~]# ls -i /etc/
524782 glvnd 265533 passwd 797789 vmware-tools
262904 gnupg 263306 passwd- 921729 vsftpd
262238 GREP_COLORS 265510 pbm2ppa.conf 270349 wgetrc
262318 groff 265457 pinforc 263817 wpa_supplicant
265425 group 262241 pkcs11 265463 wvdial.conf
263114 group- 262223 pki 262218 X11
同样也可以使用 stat 命令查看。而stat命令实际就是读取的该文件inode中的信息。
[root@VM-0-15-centos ~]# stat /etc/passwd
File: ‘/etc/passwd’
Size: 2520 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 265533 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2022-02-24 16:34:07.312444179 +0800
Modify: 2022-02-21 16:33:23.074731968 +0800
Change: 2022-02-21 16:33:23.078731959 +0800
Birth: -
以 /etc/passwd 为例,该文件的inode为 265533 。获取inode后使用debugfs 查看该inode中文件内容真实的block所在位置。
df 命令获取文件系统类型
[root@VM-0-15-centos ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 3.9G 16K 3.9G 1% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 2.0M 3.9G 1% /run
/dev/vda1 ext4 50G 24G 24G 50% /
使用df命令查看当前系统磁盘的文件系统类型,以这里为例当前的磁盘为 /dev/vda1 ,类型为 ext4 。
debugfs 命令获取文件的block位置
[root@VM-0-15-centos ~]# debugfs /dev/vda1 -R "stat <265533>"
debugfs 1.42.9 (28-Dec-2013)
Inode: 265533 Type: regular Mode: 0644 Flags: 0x80000
Generation: 3455122358 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 2520
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x62134e53:12c56adc -- Mon Feb 21 16:33:23 2022
atime: 0x621742ff:4a7e144c -- Thu Feb 24 16:34:07 2022
mtime: 0x62134e53:11d14700 -- Mon Feb 21 16:33:23 2022
crtime: 0x62134e53:11d14700 -- Mon Feb 21 16:33:23 2022
Size of extra inode fields: 28
EXTENTS:
(0):12666063
最后的EXTENTS也就是文件的block位置,也可以用blocks命令直接获取。
注意这里的stat并非系统中的命令,而是debugfs中的子命令参数。
[root@VM-0-15-centos ~]# debugfs /dev/vda1 -R "blocks <265533>"
debugfs 1.42.9 (28-Dec-2013)
12666063
[root@VM-0-15-centos ~]# debugfs /dev/vda1 -R "blocks /etc/passwd"
debugfs 1.42.9 (28-Dec-2013)
12666063
可以看到使用文件路径和 <inode> 的方式获取的结果都是一样。使用 dumpe2fs 获取文件系统的相关信息。
dumpe2fs 查看superblock文件系统信息
[root@VM-0-15-centos ~]# dumpe2fs /dev/vda1 | head -n 100
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name: <none>
Last mounted on: /
...
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
Flex block group size: 16
...
Journal features: journal_incompat_revoke journal_64bit
Journal size: 128M
Journal length: 32768
Journal sequence: 0x001b19ff
Journal start: 30146
Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
Block bitmap at 1025 (+1025), Inode bitmap at 1041 (+1041)
Inode table at 1057-1568 (+1057)
21802 free blocks, 0 free inodes, 1011 directories
Free blocks: 10752-11903, 12032-13951, 14038-32767
...
当前系统的 Block size 为 4096即4KB并且从0块开始。现在就可以使用dd命令找到对应的block的位置直接从磁盘中将 /etc/passwd 的内容读取出来。
dd 命令读取磁盘指定block位置数据信息
[root@VM-0-15-centos ~]# dd if=/dev/vda1 bs=4096 count=1 skip=12666063
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
......
现在就成功从磁盘中读取到了 /etc/passwd 文件的内容。这里不指定of就输出到标准输出。bs=4096 是根据文件系统而定,当前系统默认一个block的大小为4096,bs就设定为该大小。因为dd命令是从到开始读取的,所以skip=12666063直接跳过之前的block读取指定block的内容。
dd 参数说明:
- if=文件名:输入文件名,默认为标准输入。即指定源文件。
- of=文件名:输出文件名,默认为标准输出。即指定目的文件。
- bs=bytes:同时设置读入/输出的块大小为bytes个字节。
- skip=blocks:从输入文件开头跳过blocks个块后再开始复制。
- count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
dd命令补充
之前在测试过程中,未理解bs=4096的含义,发现只要修改bs的值读取到的磁盘内容就不一样。不理解的同学可以试一下下面的命令。
[root@VM-0-15-centos ~]# dd if=/dev/vda1 bs=4096 count=1 skip=12666063 2>/dev/null | head -n 1
root:x:0:0:root:/root:/bin/bash
[root@VM-0-15-centos ~]# dd if=/dev/vda1 bs=2048 count=1 skip=25332126 2>/dev/null | head -n 1
root:x:0:0:root:/root:/bin/bash
当bs改为之前的一半后,skip改为两倍,读取到的内容是一样的。这下就能理解dd读取的原理了吧。
如何获取磁盘中inode的数据?
上面展示了如何通过命令的方式获取到inode对应的block位置,那么inode实际的数据又是如何保存在磁盘上的呢?
获取inode表所在block位置
[root@VM-0-15-centos ~]# debugfs /dev/vda1 -R "imap /etc/passwd"
debugfs 1.42.9 (28-Dec-2013)
Inode 265533 is part of block group 32
located at block 1048819, offset 0x0c00
使用imap可以查看该文件的inode表所在block位置为1048819,偏移位置为0x0c00。
从磁盘中读取inode表信息
inode表数据结构
struct dinode
{
unsigned short di_mode; / *文件和文件类型* /
short di_nlink; / *文件的链接数* /
short di_uid; / *所有者的用户ID * /
short di_gid; / *访问控制文件(gid)* /
off_t di_size; / *文件中的字节数* /
char di_addr [40]; / *磁盘块地址* /
time_t di_Atime; / *上次访问时间* /
time_t di_mtime; / *最后修改时间* /
time_t di_ctime; / *创建时间* /
};
stat命令的本质就是介绍文件inode所在block所在磁盘的信息获取文件的属性。
inode表在磁盘上的储存
[root@VM-0-15-centos ~]# dd if=/dev/vda1 bs=4096 count=1 skip=1048819 | hexdump -C
...
00000c00 a4 81 00 00 d8 09 00 00 ff 42 17 62 53 4e 13 62 |.........B.bSN.b|
00000c10 53 4e 13 62 00 00 00 00 00 00 01 00 08 00 00 00 |SN.b............|
00000c20 00 00 08 00 01 00 00 00 0a f3 01 00 04 00 00 00 |................|
00000c30 00 00 00 00 00 00 00 00 01 00 00 00 cf 44 c1 00 |.............D..|
00000c40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000c60 00 00 00 00 b6 fb f0 cd 00 00 00 00 00 00 00 00 |................|
00000c70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000c80 1c 00 00 00 dc 6a c5 12 00 47 d1 11 4c 14 7e 4a |.....j...G..L.~J|
00000c90 53 4e 13 62 00 47 d1 11 00 00 00 00 00 00 00 00 |SN.b.G..........|
00000ca0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000d00 80 81 00 00 00 00 00 00 0f ed a5 61 18 ed a5 61 |...........a...a|
这里只截取了偏移部分的位置,因为ext4中一个inode表的大小为256byte。从0x0c00开始到0x0d00为该inode的所有内容。
比如0xc30的最后8位 cf 44 c1 00 ,磁盘是逆序储存的,表示数据为00c144cf 。表示当前文件的block位置。这里只选取了block作为例子,其他的数据都可以通过该方式表示。
linux 的 rm 命令是如何删除文件的?
这里先复制一个passwd的备份。
[root@VM-0-15-centos recovery]# cp /etc/passwd ./
[root@VM-0-15-centos recovery]# ls -i
661514 passwd
[root@VM-0-15-centos recovery]# debugfs /dev/vda1 -R "stat <661514>"
debugfs 1.42.9 (28-Dec-2013)
Inode: 661514 Type: regular Mode: 0644 Flags: 0x80000
Generation: 3455446134 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 2520
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x6218a151:b95de8a4 -- Fri Feb 25 17:28:49 2022
atime: 0x6218a152:4672e7ac -- Fri Feb 25 17:28:50 2022
mtime: 0x6218a151:b95de8a4 -- Fri Feb 25 17:28:49 2022
crtime: 0x6218a151:b95de8a4 -- Fri Feb 25 17:28:49 2022
Size of extra inode fields: 28
EXTENTS:
(0):2671346
可以看到显示了文件inode的所有信息。现在删除掉passwd文件。
[root@VM-0-15-centos recovery]# rm -f passwd
[root@VM-0-15-centos recovery]# ls -a
. ..
[root@VM-0-15-centos recovery]# debugfs /dev/vda1 -R "ls -d /root/recovery/"
debugfs 1.42.9 (28-Dec-2013)
661511 (12) . 393219 (4084) .. <661514> (4072) passwd
删除文件后,通常我们是不知道文件的inode的,可以通过debugfs工具的ls -d命令查看目录所有文件的inode信息(包括已删除的文件)。
[root@VM-0-15-centos recovery]# debugfs /dev/vda1 -R "stat <661514>"
debugfs 1.42.9 (28-Dec-2013)
Inode: 661514 Type: regular Mode: 0644 Flags: 0x80000
Generation: 3455446134 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 0
File ACL: 0 Directory ACL: 0
Links: 0 Blockcount: 0
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x6218a28c:e77b2a3c -- Fri Feb 25 17:34:04 2022
atime: 0x6218a152:4672e7ac -- Fri Feb 25 17:28:50 2022
mtime: 0x6218a28c:e77b2a3c -- Fri Feb 25 17:34:04 2022
crtime: 0x6218a151:b95de8a4 -- Fri Feb 25 17:28:49 2022
dtime: 0x6218a28c -- Fri Feb 25 17:34:04 2022
Size of extra inode fields: 28
EXTENTS:
获取被删除后的文件信息。对比发现
- 文件的inode是没有发生改变的
- 文件中的ctime,atime,mtime,crtime还在
- 多了个dtime,可用于检测文件被删除的时间
- 文件的block和size信息没有了
直接从磁盘上观察inode表的变化。
根据文件删除之前的block地址,直接从磁盘读取。
[root@VM-0-15-centos ~]# dd if=/dev/vda1 bs=4096 count=1 skip=2671346 2>/dev/null | head -n 5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
发现还是能从磁盘上读取到原始文件的内容。说明文件并没有真正意义上的删除。
rm 删除文件原理
rm删除文件的原理是将文件inode中的数据block所在位置全部用0填充,此时指向文件真实物理存储地址的指针就没了,并把inode标记为未使用的状态。虽然真实block位置的数据并没有被覆盖删除(依旧在磁盘上),但是后续有新的数据不断写入磁盘,就有可能将这块block给覆盖掉。这样文件就永远无法找回来了。
总结
文章详细分析了文件读取的过程以及rm删除文件的原理。限于篇幅原因,对于linux下文件的恢复会在下一篇文章中分析,了解数据恢复工具的原理,如何手工对磁盘上的已删除的文件进行恢复。
相关推荐
- Let’s Encrypt免费搭建HTTPS网站
-
HTTPS(全称:HyperTextTransferProtocoloverSecureSocketLayer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入...
- 使用Nginx配置TCP负载均衡(nginx tcp负载)
-
假设Kubernetes集群已经配置好,我们将基于CentOS为Nginx创建一个虚拟机。以下是实验种设置的详细信息:Nginx(CenOS8Minimal)-192.168.1.50Kube...
- Nginx负载均衡及支持HTTPS与申请免费SSL证书
-
背景有两台minio文件服务器已做好集群配置,一台是192.168.56.41:9000;另一台是192.168.56.42:9000。应用程序通过Nginx负载均衡调用这两台minio服务,减轻单点...
- HTTPS配置实战(https配置文件)
-
原因现在网站使用HTTPS是规范操作之一,前些日子买了腾讯云服务,同时申请了域名http://www.asap2me.top/,目前该域名只支持HTTP,想升级为HTTPS。关于HTTPS的链接过程大...
- 只有IP地址没有域名实现HTTPS访问方法
-
一般来说,要实现HTTPS,得有个注册好的域名才行。但有时候呢,咱只有服务器的IP地址,没注册域名,这种特殊情况下,也能照样实现HTTPS安全访问,按下面这些步骤来就行:第一步,先确认公网...
- 超详解:HTTPS及配置Django+HTTPS开发环境
-
众所周知HTTP协议是以TCP协议为基石诞生的一个用于传输Web内容的一个网络协议,在“网络分层模型”中属于“应用层协议”的一种。在这里我们并不研究该协议标准本身,而是从安全角度去探究使用该协议传输数...
- Godaddy购买SSL之后Nginx配置流程以及各种错误的解决
-
完整流程:参考地址:https://sg.godaddy.com/zh/help/nginx-generate-csrs-certificate-signing-requests-3601生成NGI...
- Nginx从安装到高可用,一篇搞定(nginx安装与配置详解)
-
一、Nginx安装1、去官网http://nginx.org/下载对应的nginx包,推荐使用稳定版本2、上传nginx到linux系统3、安装依赖环境(1)安装gcc环境yuminstallgc...
- 阿里云免费证书申请,配置安装,使用tomcat,支持http/https访问
-
参数说明商品类型默认已选择云盾证书服务(无需修改)。云盾证书服务类型SSL证书服务的类型。默认已选择云盾SSL证书(无需修改),表示付费版SSL证书。如果您需要免费领取或付费扩容DV单域名证书【免费试...
- 你试过两步实现Nginx的规范配置吗?极速生成Nginx配置小工具
-
NGINX是一款轻量级的Web服务器,最强大的功能之一是能够有效地提供HTML和媒体文件等静态内容。NGINX使用异步事件驱动模型,在负载下提供可预测的性能。是当下最受欢迎的高性能的Web...
- 从零开始搭建HTTPS服务(搭建https网站)
-
搭建HTTPS服务的最初目的是为了开发微信小程序,因为wx.request只允许发起HTTPS请求,并且还必须和指定的域名进行网络通信。要从零开始搭建一个HTTPS的服务需要下面4...
- 群晖NAS使用官网域名和自己的域名配置SSL实现HTTPS访问
-
安全第一步,群晖NAS使用官网域名和自己的域名配置SSL实现HTTPS访问【新手导向】NAS本质还是一个可以随时随地访问的个人数据存储中心,我们在外网访问的时候,特别是在公网IP下,其实会面临着很多安...
- 让网站快速升级HTTPS协议提高安全性
-
为什么用HTTPS网络安全越来越受到重视,很多互联网服务网站,都已经升级改造为https协议。https协议下数据包是ssl/tcl加密的,而http包是明文传输。如果请求一旦被拦截,数据就会泄露产生...
- 用Https方式访问Harbor-1.9版本(https访问流程)
-
我上周在头条号写过一篇原创文章《Docker-Harbor&Docker-kitematic史上最详细双系统配置手册》,这篇算是它的姊妹篇吧。这篇文章也将用到我在头条写的另一篇原创文章的...
- 如何启用 HTTPS 并配置免费的 SSL 证书
-
在Linux服务器上启用HTTPS并配置免费的SSL证书(以Let'sEncrypt为例)可以通过以下步骤完成:---###**一、准备工作**1.**确保域名已解析**...
你 发表评论:
欢迎- 一周热门
-
-
极空间如何无损移机,新Z4 Pro又有哪些升级?极空间Z4 Pro深度体验
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
10个免费文件中转服务站,分享文件简单方便,你知道几个?
-
[常用工具] OpenCV_contrib库在windows下编译使用指南
-
日本海上自卫队的军衔制度(日本海上自卫队的军衔制度是什么)
-
【系统配置】信创终端挂载NAS共享全攻略:一步到位!
-
Ubuntu系统Daphne + Nginx + supervisor部署Django项目
-
UOS服务器操作系统防火墙设置(uos20关闭防火墙)
-
WindowsServer2022|配置NTP服务器的命令
-
- 最近发表
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)