當我們從文件係統中刪除文件時,數據不會被物理刪除:操作係統隻是簡單地將文件先前占用的區域標記為空閑區域,並使其可用於存儲新信息。確保實際從設備中刪除數據的唯一方法是用其他數據覆蓋它。出於隱私方麵的考慮,我們可能希望執行此類操作(也許我們計劃出售該設備,並希望確保新的擁有者無法訪問我們的數據),或者在準備進行加密的設備。在本教程中,我們介紹一些工具,可用來完全擦除設備上的數據。類似經常被問到的問題是:
- Linux如何徹底刪除文件?
- Linux文件粉碎?
- Linux數據粉碎?
在本教程中,您將學習:
- 如何使用dd粉碎數據
- 如何使用shred實用程序來安全擦除文件和設備
- 如何使用badblocks(壞塊)覆蓋數據
使用的軟件要求和約定
類別 | 使用的要求,約定或軟件版本 |
---|---|
係統 | 各Linux版本一般都支持 |
軟件 | dd,shred或badblocks |
其他 |
|
約定 | #-要求linux命令可以直接以root用戶身份或通過使用root特權以root特權執行sudo 命令
$ -要求linux命令以普通非特權用戶身份執行 |
使用dd擦除數據
dd是一個非常強大的程序,默認情況下包含在所有主要的Linux發行版中。這裏,我們要做的就是用零或隨機數據覆蓋某個塊設備的內容。在這兩種情況下,我們都可以使用”special”文件生成的數據:/dev/zero
和dev/urandom
(或者/dev/random
) 。前者每次對其執行讀操作時都返回零。後者使用Linux內核隨機數生成器返回隨機字節。
要用零填充磁盤,我們可以運行:
$ sudo dd if=/dev/zero of=/dev/sdx
要使用隨機數據,請執行以下操作:
$ sudo dd if=/dev/urandom of=/dev/sdx
使用LUKS容器作為隨機數據生成器
使用隨機數據覆蓋設備是一項耗時的操作,但是在我們計劃使用全盤加密以使磁盤的已使用和未使用部分無法區分時尤其有用。為了加快這一過程,我們可以使用一些技巧:我們可以在要隨機填充的設備或分區上創建一個LUKS(Linux Unified Key Setup)容器
,並向其中寫入零。由於加密,數據將隨機透明地寫入基礎設備。
首先,我們創建LUKS
容器:
$ sudo cryptsetup luksFormat /dev/sdx
WARNING!
========
This will overwrite data on /dev/sdx irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sdx:
Verify passphrase:
在這種情況下,實際上不需要使用強密碼,因為我們將容器用作隨機數據生成器,並且在操作完成後將其清除。容器準備好後,我們通過運行以下命令將其打開:
$ sudo cryptsetup luksOpen /dev/sdx crypted
Enter passphrase for /dev/sdx:
現在容器已打開,我們可以使用dd並用零填充它。特別注意:我們寫入LUKS容器的是映射的/dev/mapper/crypted
,而不是直接用底層/dev/sdx
設備:
$ sudo dd if=/dev/zero of=/dev/mapper/crypted bs=1M
寫入所有數據後,我們關閉容器,並使用隨機數據覆蓋luks標頭。標頭的大小取決於使用的LUKS
:2MiB 對應
LUKS
格式,以及16MiB 對應
LUKS2
格式,後者已成為cryptsetup的最新版本中的默認格式。可以肯定的是,我們可以覆蓋磁盤的前20MiB:
$ sudo cryptsetup luksClose /dev/mapper/crypted
$ sudo dd if=/dev/urandom of=/dev/sdx bs=1M count=20
使用shred擦除數據
該實用程序的名稱很容易解釋:如手冊中所述,其主要目標是覆蓋文件並有選擇地刪除它。shred
實用程序依賴於以下假設:文件係統會覆蓋適當的數據。注意:
- 如果將應用程序安裝在ext4等日誌文件係統上(ext4可能是最常用的Linux文件係統)(使用data=journal選項),則該應用程序可能無法使我們獲得預期的結果。
- 如果在掛載ext4文件係統時,使用
data=ordered或
data=writeback
選項(前者是默認選項),在這兩種情況下shred
工作正常,會產生預期的結果。
在使用時data=journal
選項,不僅是元數據,而且數據本身在寫入主文件係統之前也被寫入文件係統日誌。很容易看出為什麽這會引起問題。
讓我們看一些應用程序用法的例子。假設我們要安全刪除一個名為”test”的文件。我們要做的就是運行以下命令(在這裏我們使用-v選項
使程序輸出更詳細內容):
$ shred -v test
shred: test: pass 1/3 (random)...
shred: test: pass 2/3 (random)...
shred: test: pass 3/3 (random)...
默認情況下,應用程序用隨機數據3次覆蓋指定的文件。設置覆蓋次數可以使用-n
(短缺--iterations
) 選項。要覆蓋文件6次,我們將運行:
shred -v -n 6 test
shred: test: pass 1/6 (random)...
shred: test: pass 2/6 (000000)...
shred: test: pass 3/6 (555555)...
shred: test: pass 4/6 (ffffff)...
shred: test: pass 5/6 (aaaaaa)...
shred: test: pass 6/6 (random)...
在某些情況下,我們可能希望隱藏對文件或設備執行了粉碎操作的事實。在這種情況下,我們可以使用該程序的-z
(也就是--zero
)選項,以使程序在粉碎後執行附加一次寫入零:
$ shred -v -n 6 -z test
shred: test: pass 1/7 (random)...
shred: test: pass 2/7 (ffffff)...
shred: test: pass 3/7 (aaaaaa)...
shred: test: pass 4/7 (555555)...
shred: test: pass 5/7 (000000)...
shred: test: pass 6/7 (random)...
shred: test: pass 7/7 (000000)...
從命令的詳細輸出中,我們確實可以注意到通過寫入零來執行最後一遍覆蓋(000000
)。我們可以通過運行hexdump
程序檢查驗證文件內容:
$ hexdump test
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0008000
刪除文件
如果在運行上麵示例中的命令之一後看一下文件係統,我們會注意到盡管被隨機數據覆蓋,但文件本身並未被刪除:發生這種情況是因為該命令可能用在了表示整個文件的設備或分區(例如,/dev/sda
),而它們不應該被刪除。
但是,在處理通用文件時,我們可能還希望在覆蓋文件後從文件係統中刪掉文件。要實現此行為,我們可以使用-u
或者--remove
選項。這兩個選項都會導致文件被刪除,但是對於後者,我們還可以指定刪除的方式。我們可以在以下兩者之間進行選擇:
- unlink:使用標準
unlink
係統調用刪除文件; - wipe:刪除前混淆文件名中的字節;
- wipesync:混淆的字節也同步到磁盤;
wipesync
模式是默認設置。
使用badblocks擦除數據
雖然badblocks
實用程序的主要目標是查找壞塊
,但是通過其write-mode選項做破壞性測試,我們可以有效地覆蓋和安全擦除設備上的現有數據。我們要做的就是啟動命令並指定-w
選項:將通過先寫入然後讀取(在每個塊上,0xaa
,0x55
,0xff
和0x00的數據模式)
並比較內容。我們可以使用-s
和-v
選項,分別使程序顯示進度信息以及遇到的讀取和寫入錯誤的數量。結合這幾點,要擦除設備數據,我們將運行:
$ sudo badblocks -wsv /dev/sdx
Checking for bad blocks in read-write mode
From block 0 to 3870719
Testing with pattern 0xaa: ^C6.30% done, 0:41 elapsed. (0/0/0 errors)
要運行上麵的運行,應先卸載(unmount)設備,否則badblocks
將拒絕運行,除非使用-f
選項。一次測試的默認塊數為64
;但是,我們可以使用-c
選項做修改。
結論
在本文中,我們看到了可用於在設備上粉碎數據的三個實用程序,以及一些用法示例。dd
和shred
是GNU核心工具集的一部分,因此幾乎可以肯定它們已經安裝在您的係統上。Badblocks
是用於測試不良塊是否存在的軟件:在執行read-write測試時,我們可以覆蓋設備上的數據。
另外,請注意,數據粉碎的有效性還取決於所用設備的類型:例如,固態驅動器必須處理諸如寫入放大率 的問題。