dd 명령이 shred를 사용하여 삭제된 파일을 복구할 수 있는 이유는 무엇입니까?

dd 명령이 shred를 사용하여 삭제된 파일을 복구할 수 있는 이유는 무엇입니까?

을 사용하여 파일의 inode를 찾았습니다 ls -li. 그런 다음 디스크에서 파일의 시작 블록을 찾았습니다. 나는 이 명령을 사용하여 블록의 내용을 다른 디렉토리에 복사합니다 dd. 그런 다음 유틸리티 를 사용하여 파일을 파쇄했습니다 shred. 같은 명령을 다시 실행합니다 shred -uvz -n=10 file1.txt. dd파일이 복원되었습니다. 파일이 파쇄된 후에는 00000을 얻어야 합니다. 내가 무엇을 놓치고 있나요?

두 번째 반복에서는 shred -vz -n=10 file2.txt파일을 삭제하지 않는 대신 실행합니다. 이전과 동일한 단계를 거쳐 다시 dd명령 및 블록 위치를 사용하여 원본 파일을 복원 할 수 있었습니다 . 그러나 파쇄된 파일의 내용은 와 같이 00000 입니다 hexdump file2.txt. 내가 무엇을 놓치고 있나요?

답변1

파일 시스템은 해당 블록 장치에 독점적으로 액세스할 수 있어야 합니다. dd파일 시스템을 마운트할 때 블록 장치에서 직접 작업하면 안 됩니다.

dd(또는 다른 사용자 공간 프로그램)을 사용하여 블록 장치에서 직접 바이트를 읽으면 읽기가 캐시됩니다. 다시 반복하면 dd캐시에서 데이터를 읽습니다.

불행하게도 (파일 시스템을 통해) 데이터 쓰기는 이 캐시를 업데이트하지 않습니다. 따라서 캐시의 데이터가 디스크의 데이터를 반영하지 않는 상황이 발생할 수 있습니다.

이런 일이 일어나는 또 다른 예는 TRIM입니다. 블록 장치 데이터가 캐시된 경우 TRIM이 해당 데이터를 제거한 경우에도 캐시에서 데이터를 계속 가져올 수 있습니다. 그렇기 때문에TRIM 테스트 시 캐시를 삭제해야 합니다..

일부 파일로 파일 시스템을 만듭니다.

# truncate -s 10G filesystem.img
# mkfs.ext4 filesystem.img
# losetup --find --show filesystem.img
/dev/loop1
# mount /dev/loop1 loop/
# for n in {000..100} ; do yes $n | dd bs=1M count=1 iflag=fullblock of=loop/$n; done 2> /dev/null
# sync

파일 내용과 물리적 오프셋을 확인하세요.

# hexdump -C loop/042
00000000  30 34 32 0a 30 34 32 0a  30 34 32 0a 30 34 32 0a  |042.042.042.042.|
*
00100000
# filefrag -ve loop/042
Filesystem type is: ef53
File size of loop/042 is 1048576 (256 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..     255:      44800..     45055:    256:             last,eof
loop/042: 1 extent found

블록 장치에서 읽기:

# dd bs=4096 skip=44800 count=256 if=/dev/loop1 | hexdump -C
00000000  30 34 32 0a 30 34 32 0a  30 34 32 0a 30 34 32 0a  |042.042.042.042.|
*
00100000

조각:

# shred -v -n 1 loop/042
shred: loop/042: pass 1/1 (random)...

블록 장치(캐시)에서 읽기:

# dd bs=4096 skip=44800 count=256 if=/dev/loop1 | hexdump -C
00000000  30 34 32 0a 30 34 32 0a  30 34 32 0a 30 34 32 0a  |042.042.042.042.|
*
00100000

블록 장치에서 읽기() iflag=nocache:

# dd bs=4096 skip=44800 count=256 if=/dev/loop1 iflag=nocache | hexdump -C
00000000  30 34 32 0a 30 34 32 0a  30 34 32 0a 30 34 32 0a  |042.042.042.042.|
*
00100000
# dd bs=4096 skip=44800 count=256 if=/dev/loop1 iflag=nocache | hexdump -C | head
00000000  59 c2 d8 d4 5a 02 35 15  a1 fb f1 07 ae 53 59 99  |Y...Z.5......SY.|
00000010  5b 47 4f fc 2c e7 d3 db  10 70 c6 72 3e 6f 0b 05  |[GO.,....p.r>o..|
00000020  f5 07 c6 f7 95 64 8b a2  4e 7f 32 4f 0c b1 a3 32  |.....d..N.2O...2|
00000030  18 b5 99 7d 7d 6e 6d d6  b9 36 77 af 30 02 ba 23  |...}}nm..6w.0..#|
00000040  f5 55 a5 b7 01 51 cd 5b  64 c9 29 1f f6 48 23 6c  |.U...Q.[d.)..H#l|

dd iflag=nocache캐시에서만 데이터 삭제뒤쪽에캐시에서 읽혀지므로 새 데이터를 보려면 두 번 수행해야 합니다. 또는 sync; echo 3 > /proc/sys/vm/drop_caches모든 캐시를 지우거나 직접 I/O를 사용하여 행운을 시험해 볼 수도 있습니다.

관련 정보