Skip to content

使用shred工具彻底粉碎文件

引言

shred - overwrite a file to hide its contents, and optionally delete it

Overwrite the specified FILE(s) repeatedly, in order to make it harder for even very expensive hardware probing to recover the data.

很多时候删除一个文件,实际上只是在文件系统里面将该文件所在存储位置标记为可用、可覆盖状态,这个时候是可以通过恢复工具来进行恢复的;但如果这块存储位置之后反复被其他内容填充、覆盖的话,恢复的难度就增加了。

shred工具在coreutils软件包中,一般Linux系统都自带有这个工具。它通过多次覆盖的方式来删除文件,避免文件被恢复工具重新恢复,达到彻底粉碎的效果。但实际使用中,还是有一些需要注意的地方,并不能保证任何情况下都可以覆盖、删除干净,还是可能被恢复回来。

安装coreutils

$ sudo apt-get install coreutils
$ sudo yum install coreutils

基本使用

  • 参数选项:
Usage: shred [OPTION]... FILE...

  -f, --force               如果需要则会强制改变权限为可写,从而可以覆盖文件
  -n, --iterations=N        默认覆盖3次,否则覆盖N次
      --random-source=FILE  从指定文件中随机获取内容用于覆盖目标文件
  -s, --size=N              覆盖多少字节的内容,可以使用后缀(K,M,G)
  -u, --remove[=HOW]        覆盖文件后先截断再删除
  -v, --verbose             显示进度详情
  -x, --exact               不自动将随机文件大小增加到临近块大小,一般对于非普通文件都默认激活此选项
  -z, --zero                最后用0覆盖一遍目标文件, 对文件系统隐藏覆盖行为
  • 例子:粉碎一个普通文本文件:
$ cat test.txt
hello
world

$ shred test.txt

$ file test.txt
test.txt: data
  • 例子:粉碎后并删除
$ shred -u test1.txt test2.txt

$ shred -v -u test.txt
shred: test.txt: pass 1/3 (random)...
shred: test.txt: pass 2/3 (random)...
shred: test.txt: pass 3/3 (random)...
shred: test.txt: removing
shred: test.txt: renamed to 00000000
shred: 00000000: renamed to 0000000
shred: 0000000: renamed to 000000
shred: 000000: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: test.txt: removed
  • 例子:多次覆盖和zero覆盖
$ shred -v -n 10 test.txt
shred: test.txt: pass 1/10 (random)...
shred: test.txt: pass 2/10 (000000)...
shred: test.txt: pass 3/10 (b6db6d)...
shred: test.txt: pass 4/10 (ffffff)...
shred: test.txt: pass 5/10 (aaaaaa)...
shred: test.txt: pass 6/10 (random)...
shred: test.txt: pass 7/10 (555555)...
shred: test.txt: pass 8/10 (249249)...
shred: test.txt: pass 9/10 (db6db6)...
shred: test.txt: pass 10/10 (random)...

$ shred -v -n 10 -z test.txt
shred: test.txt: pass 1/11 (random)...
shred: test.txt: pass 2/11 (249249)...
shred: test.txt: pass 3/11 (aaaaaa)...
shred: test.txt: pass 4/11 (ffffff)...
shred: test.txt: pass 5/11 (924924)...
shred: test.txt: pass 6/11 (random)...
shred: test.txt: pass 7/11 (492492)...
shred: test.txt: pass 8/11 (555555)...
shred: test.txt: pass 9/11 (000000)...
shred: test.txt: pass 10/11 (random)...
shred: test.txt: pass 11/11 (000000)...
  • 例子: 粉碎指定字节大小内容
$ cat test.txt
hello
world

$ shred -v -s 5 test.txt
shred: test.txt: pass 1/3 (random)...
shred: test.txt: pass 2/3 (random)...
shred: test.txt: pass 3/3 (random)...

$ cat test.txt
P�Wr9
world
  • 例子:粉碎设备分区
$ shred /dev/hda0
$ shred -vfz -n 10 /dev/md1

注意事项

shred的工作前提是在覆盖文件的时候,文件系统会在文件原有位置直接覆盖写入的,以下情况可能达不到粉碎效果:

  • 日志结构或带日志的文件系统,这种可能会根据日志可以恢复文件,比如AIX 和 Solaris(以及 JFS、ReiserFS、XFS、Ext3 等)
  • 带冗余功能的文件系统,比如基于RAID的文件系统
  • 会创建快照的文件系统,比如NFS服务器
  • 缓存在临时位置的文件系统,比如NFS版本3客户端
  • 带压缩的文件系统

一般带备份的文件系统或者带远程镜像功能的系统,在shred粉碎后还是可以恢复文件。

文档手册

$ info coreutils 'shred invocation'

'shred' overwrites devices or files, to help prevent even very expensive
hardware from recovering the data.

   Ordinarily when you remove a file (*note rm invocation::), the data
is not actually destroyed.  Only the index listing where the file is
stored is destroyed, and the storage is made available for reuse.  There
are undelete utilities that will attempt to reconstruct the index and
can bring the file back if the parts were not reused.

   On a busy system with a nearly-full drive, space can get reused in a
few seconds.  But there is no way to know for sure.  If you have
sensitive data, you may want to be sure that recovery is not possible by
actually overwriting the file with non-sensitive data.

   However, even after doing that, it is possible to take the disk back
to a laboratory and use a lot of sensitive (and expensive) equipment to
look for the faint "echoes" of the original data underneath the
overwritten data.  If the data has only been overwritten once, it's not
even that hard.
   The best way to remove something irretrievably is to destroy the
media it's on with acid, melt it down, or the like.  For cheap removable
media like floppy disks, this is the preferred method.  However, hard
drives are expensive and hard to melt, so the 'shred' utility tries to
achieve a similar effect non-destructively.

   ......

   If you are not sure how your file system operates, then you should
assume that it does not overwrite data in place, which means that shred
cannot reliably operate on regular files in your file system.

   Generally speaking, it is more reliable to shred a device than a
file, since this bypasses the problem of file system design mentioned
above.  However, even shredding devices is not always completely
reliable.  For example, most disks map out bad sectors invisibly to the
application; if the bad sectors contain sensitive data, 'shred' won't be
able to destroy it.

如果不确定文件系统目前是否会在文件原先位置覆盖,那么粉碎整个设备分区比单独粉碎某个文件更可靠。

coreutils源码

$ git clone git://git.sv.gnu.org/coreutils

$ ls -l coreutils/src/shred.c