跳至內容

安全地擦除磁碟/提示和技巧

出自 Arch Linux 中文维基


主文章請見 安全地擦除磁碟

本文額外介紹了一些擦除工具,可替代專用擦除工具,並加快擦除速度。

警告:某些文件系統的保留塊不能通過創建文件的方式擦除,但可以使用工具 tune2fs 禁用。

擦除單個文件

[編輯 | 編輯原始碼]
警告:如果曾對存儲文件的分區進行了 碎片整理、調整大小或移動操作,或者文件曾在同一設備上被複製過,那麼擦除效果將受到影響。若數據存儲在加密容器上,並擦除整個加密容器,則文件恢復將變得困難得多,但加密可能會大幅降低 磁碟性能(除非使用硬體加密)。另見 安全地擦除磁碟#數據殘留
注意:要在擦除時保留文件的訪問和修改時間不變,在修改文件前先使用stat(1)獲取文件當前的時間信息,之後可使用touch(1)手動修改文件時間。另請參閱不同文件系統對元數據和時間戳的支持情況

本節將介紹擦除單個文件的兩種基本方法。此外,還有一種專門用於反取證的高級方法,其非常耗時,並且只能通過專用工具完成,本文不作介紹。

  • 在刪除前用隨機數據覆寫,或在不改變文件大小的情況下用其他內容替換原內容。
  • 使用專用工具擦除文件和文件系統存儲的元數據
    • 搜索整個磁碟,找到並清除已刪除文件的殘留部分,同時不對其它文件造成影響。

可以使用常見的 Linux 工具在不改變文件大小的情況下覆寫文件:

  • 使用 shred -x <目標文件>-x選項會用偽隨機數據替換文件的內容,且不改變文件大小。-u 選項會在覆寫後刪除文件。
  • 使用 mkfs 可以將文件格式化為文件系統,掛載該文件系統後,任何對文件系統的修改都將反映到文件上,在文件系統上存儲其它內容,可達到覆蓋原始文件內容的目的。
  • dd 可創建指定大小、內容的文件,若目標文件已存在,則直接會覆寫。通過組合 skipseek 選項,可以將整個文件或文件的一部分替換為其他內容。在操作前,需要知道文件大小,以避免意外擴容文件。文件大小可以使用 du -b <文件名> | cut -f1stat -c "%s" <文件名>獲取。注意使用dd時,必須指定 iflag=fullblock 選項,詳見 dd#Partial read: copied data is smaller than requested
  • 使用 perl 工具可以用單個符號(symbol)替換文件內容,同時避免文件大小發生變化。

要擦除文件的元數據,可以不斷創建新文件,直到填滿分區,這將迫使文件系統覆蓋舊的文件元數據條目,以存儲新創建文件的條目。此外,也可以使用專用工具。詳見#擦除可用空間

組合使用提到的文件創建和轉換工具擦除文件內容,可達到避免文件被恢復、誤導恢復工具及其使用者(可通過覆寫隨機數據或預先定義好的其它內容實現)的目的。具體的組合方式可依情況和需求而定。

注意:
  • 若存儲文件的文件系統還有可用空間,則簡單的覆寫操作可能無法清除文件的某些部分。
  • 若要覆寫特定文件的內容,同時確保該文件在硬碟上的邏輯位置不變,可以先創建一個或多個文件將文件所在分區填滿,再使用合適的工具重寫或替換目標文件的內容。不過,如果分區的可用空間很多,而要覆蓋的文件很少,這會消耗大量時間。

例如:

使用Perl,用 . 替換文件中所有內容的:

$ perl -p -i -e 's\[^*]\.\g' <文件名>

使用dd

$ <覆盖内容> | dd bs=<目标文件大小(字节)> count=1 iflag=fullblock of=<目标文件> seek=0

或者,也可使用stdout重定向。這種方式在創建文件時速度更快,但無法使用 seek 選項來跳過目標文件中的某些部分:

$ <覆盖内容> | dd bs=<目标文件大小(字节)> count=1 iflag=fullblock > <目标文件>
提示:如果覆蓋內容長度小於目標文件,需將其與下文介紹的 while 循環結合使用。

另見:

覆寫目標

[編輯 | 編輯原始碼]

防止擦除已掛載的分區

[編輯 | 編輯原始碼]

選擇要擦除的設備時需要格外小心,簡單的拼寫錯誤就可能導致錯誤的目標被擦除,從而損壞系統。為了降低風險,可以使用腳本來包裝選定的擦除工具。例如:

if [[ -e "$1" && -b "$1" ]];then
NOT_safe="$(lsblk -o "NAME,MOUNTPOINT" ${1//[0-9]/} | grep -e / -e '\]')";
 if [[ -z "$NOT_safe" ]];then
# 在这里你可以使用任何擦除工具擦除目标
# 擦除目标由命令行传入,并存储在变量“$1”中
#
  else
  echo 'Not allowed to destroy if any of the partitions is mounted: '"$NOT_safe"
 fi
fi 

使用dd進行高級擦除

[編輯 | 編輯原始碼]

在使用dd時,可以利用OpenSSL,使用隨機密碼進行AES加密,並將密文用於擦除目標,以實現隨機擦除:

# DEVICE="/dev/sdX"
# PASS=$(tr -cd '[:alnum:]' < /dev/urandom | head -c128)
# openssl enc -aes-256-ctr -pass pass:"$PASS" -nosalt < /dev/zero | dd obs=64K ibs=4K of=$DEVICE oflag=direct status=progress

上述命令使用/dev/urandom生成128位元組的加密密鑰,並使用 CTR 模式的 AES-256 算法來加密 /dev/zero 的輸出。相比直接使用偽隨機源,使用加密算法可能可以獲得更快的寫入速度。最終設備將被 AES 密文填充。

上述命令將塊大小設置為 64K,通常比默認的 512 字節更快。還可以嘗試更大的塊大小,以找到適合硬體的最佳傳輸速率。參考 [1]及其中的參考文獻。

類似的方法還可參見 Dm-crypt/準備磁碟#dm-crypt_擦除空設備或分區

使用模板文件

[編輯 | 編輯原始碼]

除了用零填充,還可以使用內容無關緊要的文件進行填充。若使用mkfs格式化了目標文件,需要掛載該文件系統,並使用特定內容填滿該文件系統(可以使用無關緊要的文件,或相關工具生成的重複輸出)。

一種方法是反覆使用模板文件進行擦除,直到設備末尾。若使用此方法,當出現到達設備末尾的錯誤時,必須手動使用停止鍵 來中斷 while 循環,因而不推薦使用:

$ while [ 1 -lt 2 ];do cat file1-to-use.as-template file2-to-use.as-template /tmp/templatefiles/* ;done > /dev/sd"XY"

若使用dd,如果通過選項正確設置了要擦除的大小,就可以安全地進行重複擦除,而不會出現空間不足的錯誤。這可通過將while循環產生的模板文件輸出作為dd的輸入實現。此外,通過設置skipseek 選項的值,還能確定要擦除的範圍。除了例子中使用的cat外,還可以使用head(1)tail(1)將模板文件的部分內容輸出到標準輸出。

while [ 2 -gt 1 ]; do
 if [ -z "$(pidof dd)"  ];then
  break ;
 fi;
cat file1-to-use.as-template file2-to-use.as-template /tmp/templatefiles/* ;
done | dd of=/dev/sd"XY" seek=<起始扇區> bs=<扇區大小> count=<擦除扇區數量>
提示:若要重複覆寫同一區域,可以在 while ... done | dd ... 外層新增一個循環,使用新增循環的循環變量,在每次循環中使用不同的模板文件進行覆寫。
注意:如果用於覆寫的預定義模板文件數量很多,可以利用 SquashFS 來壓縮文件和文件夾,並存放到掛載的 內存檔 中。這樣能最大限度地減少磁碟讀取次數,但同時會增加 CPU 使用率。此外,也可以為模板文件創建壓縮包,將壓縮包複製到內存檔中,並使用能夠將解壓後的內容輸出到標準輸出的解壓縮工具。使用壓縮包的缺點是,難以在每次覆寫時只是用壓縮包中的部分模板文件。不過,使用壓縮包也存在優點:若在創建壓縮包時使用了分卷壓縮,可以直接將某一分卷作為覆寫內容覆寫文件

另見:

擦除可用空間

[編輯 | 編輯原始碼]
警告:若正在為塊設備加密準備可用空間,不適合使用此方法。

可以通過以下幾種方式擦除可用空間:

  • 輸出重定向到一個文件,而不是分區或設備。
  • 在循環中,使用隨機文件名或目錄名創建多個文件副本(例如,使用cp),直到占滿所有可用空間。
  • 使用帶有文件加密功能的工具,並使用隨機密碼、隨機文件名進行加密。某些文件壓縮工具支持加密功能,且可以通過選項設置壓縮方法、文件類型等,有的還支持分卷壓縮。通過使用循環,在循環中隨機設置壓縮選項,可以用加密數據填滿可用空間,以覆寫以前的數據。
  • 使用專門用於擦除可用空間的程序,例如:

wipefreespace — 安全地擦除文件系統上的可用空間,以防止已刪除的敏感數據被恢復。

https://sourceforge.net/projects/wipefreespace/ || wipefreespaceAUR

zerofree — 掃描並以零填充文件系統中的非零空閒塊

https://frippery.org/uml/ || zerofreeAUR

使用 dd

[編輯 | 編輯原始碼]

可以使用 dd 創建一個文件來填滿可用空間:

dd if=<填充数据源> of=junk
sync
rm junk

<填充數據源> 可以是 /dev/urandom 隨機流或 /dev/zero 全零流。

注意需要確保數據已同步到磁碟後,再刪除該文件。

使用 7-Zip

[編輯 | 編輯原始碼]
Password="$(dd if=/dev/random bs=128 count=1 iflag=fullblock)"
DestinationFile="$((${RANDOM/0/1}$(date "+%s")/${RANDOM/0/1}))"
7z a -t7z -mhe=on -p"${Password}" -mx=0 -v1m ${DestinationFile} source

所用選項的詳細說明參見 7z --help

source 可以是一個包含隨機數據的文件,也可以是一個設備(例如 /dev/urandom),或者另一個塊設備或其上的分區(例如 /dev/sd"XY")。注意當使用塊設備時,該塊設備中不應含有敏感數據,並且,塊設備中已在文件系統層面刪除的數據也可能會被讀取並壓縮,以填充目標位置。

注意:
  • 不必設置壓縮級別,只需將數據存儲到壓縮文件中即可,以最大限度地減少 CPU 使用率並更快地填滿可用空間。
  • 如果使用單個文件作為源,可以將其放入 內存檔/tmp 文件夾。/tmp文件夾使用tmpfs,用於將文件存儲到內存中,可加快讀取速度。

藉助 timeout 命令創建多個文件

[編輯 | 編輯原始碼]

若在循環中使用timeout命令,並設置隨機的等待時間。則timeout將在隨機時間後中斷文件的創建,從而使得創建的文件大小隨機化。不過該方法速度較慢。

循環 中使用帶有隨機等待時間的 timeout 命令會中斷命令,從而留下一個隨機大小的文件。這是一種很慢的方法,但也是一種可行的替代方案。此外,對於文件名,可以在隨機部分之前附加特定的預定義前綴。

AA=${RANDOM/0/1};
timeout $((AA/100)) cat /dev/urandom > filename${RANDOM}.tmp;

另見

[編輯 | 編輯原始碼]
  • limits for the file creation on the different file systems.
  • meta-data in the filesystem may keep information about file after it was deleted.
  • forensic software uses meta-data to recovery and what need to do for wiping of the meta-data.