wiper.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env bash
  2. #variables:
  3. random_pass=2
  4. zeroing_pass=1
  5. prereq_list="pv smartmontools hdparm"
  6. YUM_CMD=$(which yum)
  7. APT_CMD=$(which apt-get)
  8. #check that a disk has been provided:
  9. if [ -z "$1" ]
  10. then
  11. echo "USAGE: \"./wiper.sh diskname\", for example: \"./wiper.sh sdb\""
  12. exit
  13. fi
  14. #check the disk exists:
  15. if [ ! -e "/dev/$1" ]; then
  16. echo "ERROR: /dev/$1 does not exists. exiting."
  17. exit
  18. fi
  19. #check that a disk has been provided:
  20. if [ "$2" == "--override" ]
  21. then
  22. override=1
  23. fi
  24. #prerequisites:
  25. if [[ ! -z $APT_CMD ]]; then
  26. for prereq in $prereq_list; do
  27. PKG_OK=$(dpkg-query -W --showformat='${Status}\n' $prereq|grep "install ok installed")
  28. #echo Checking for $prereq: $PKG_OK
  29. if [ "" = "$PKG_OK" ]; then
  30. echo "INFO: $prereq is not present. Setting up $prereq."
  31. sudo apt-get --yes install $prereq
  32. fi
  33. done
  34. elif [[ ! -z $YUM_CMD ]]; then
  35. for prereq in $prereq_list; do
  36. if ! rpm -qa | grep -qw $prereq; then
  37. yum install $prereq
  38. fi
  39. done
  40. else
  41. echo "ERROR: error can't find the correct installer for the prerequisites"
  42. exit 1;
  43. fi
  44. echo "---"
  45. #collect data about disk type:
  46. disk_type=$(smartctl -a /dev/$1 | grep -i "Rotation Rate:" | cut -d':' -f2 | tr -d " ")
  47. #store if the disk is an ssd:
  48. if [[ $disk_type == *"SolidStateDevice"* ]]; then
  49. disk_ssd=1
  50. # echo "disk is ssd"
  51. elif [[ $disk_type == *"rpm"* ]]; then
  52. disk_ssd=0
  53. # echo "disk is not ssd"
  54. else
  55. echo "disk type unknown"
  56. read -p "Continue anyway?" choice
  57. case "$choice" in
  58. y|Y ) echo "continuing";;
  59. n|N ) echo "exiting" && exit;;
  60. * ) echo "invalid" && exit;;
  61. esac
  62. # exit
  63. fi
  64. #
  65. if [[ "$override" -eq 1 ]]; then
  66. echo "INFO: continuing to wipe since override has been issued"
  67. else
  68. #check for disk errors, differentiating by device type since smart output is different between sata and sas drives:
  69. if smartctl -a /dev/$1 | grep -q "SATA"; then
  70. #echo "Type of disk: SATA"
  71. if smartctl -a /dev/$1 | grep -q "No Errors Logged"; then
  72. echo "INFO: This is a SATA disk, detecting no errors, going on:"
  73. else
  74. sata_model=$(smartctl -a /dev/$1 | grep -i "Device Model:" | cut -d':' -f2 | tr -d " ")
  75. sata_serial=$(smartctl -a /dev/$1 | grep -i "Serial number:" | cut -d':' -f2 | tr -d " ")
  76. echo "!!! ERRORS !!!"
  77. echo "SATA errors, aborting!!!"
  78. echo "NO WIPING NEEDED, JUST DESTROY THE DISK MECHANICALLY"
  79. echo "!!! EXITING !!!"
  80. echo ""
  81. echo "Model: $sata_model"
  82. echo "Serial: $sata_serial"
  83. exit
  84. fi
  85. elif smartctl -a /dev/$1 | grep -q "SAS"; then
  86. #echo "Type of disk: SAS"
  87. sas_errors=$(smartctl -a /dev/$1 | grep "Elements in grown defect list" | cut -d':' -f2 | tr -d " ")
  88. if [ "$sas_errors" -gt 0 ]; then
  89. sas_vendor=$(smartctl -a /dev/$1 | grep -i "Vendor:" | cut -d':' -f2 | tr -d " ")
  90. sas_model=$(smartctl -a /dev/$1 | grep -i "Product:" | cut -d':' -f2 | tr -d " ")
  91. sas_serial=$(smartctl -a /dev/$1 | grep -i "Serial number:" | cut -d':' -f2 | tr -d " ")
  92. echo "!!! ERRORS !!!"
  93. echo "Elements in grown defect list: " $sas_errors
  94. echo "NO WIPING NEEDED, JUST DESTROY THE DISK MECHANICALLY"
  95. echo "!!! EXITING !!!"
  96. echo ""
  97. echo "Vendor: $sas_vendor"
  98. echo "Model: $sas_model"
  99. echo "Serial: $sas_serial"
  100. exit
  101. else
  102. echo "INFO: This is a SAS disk, detecting no errors, going on:"
  103. fi
  104. else
  105. echo "ERROR: the disk type is none of the expected ones, exiting"
  106. exit
  107. fi
  108. fi
  109. #warning if is an ssd
  110. if [ "$disk_ssd" -eq 1 ]; then
  111. echo "WARNING: DISK IS AN SSD, Remember that sectors are reallocated thus unwanted data might remain on the flash."
  112. #TODO: ATA Secure erase? https://grok.lsu.edu/article.aspx?articleid=16716
  113. fi
  114. #calculate disk bytes:
  115. disk_blocks=$(cat /proc/partitions | grep -w $1 | tr -s ' ' | cut -d " " -f4);
  116. disk_bytes=$(( 1024*disk_blocks ))
  117. #wipe:
  118. #see: https://wiki.archlinux.org/title/Securely_wipe_disk/Tips_and_tricks#dd_-_advanced_example
  119. for r_pass in $(seq 1 $random_pass); do
  120. echo "INFO: Random pass $r_pass of $random_pass :"
  121. openssl enc -pbkdf2 -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt </dev/zero | pv --progress --eta --rate --bytes --size $disk_bytes | dd of=/dev/$1 bs=2M oflag=direct iflag=fullblock
  122. done
  123. for z_pass in $(seq 1 $zeroing_pass); do
  124. echo "INFO: Zeroing pass $z_pass of $zeroing_pass :"
  125. dd if=/dev/zero | pv --progress --eta --rate --bytes --size $disk_bytes | dd of=/dev/$1 bs=2M oflag=direct iflag=fullblock
  126. done
  127. echo "!!! FINISHED wiping $1 !!!"
  128. #some of the sources used:
  129. #https://stackoverflow.com/questions/12806176/checking-for-installed-packages-and-if-not-found-install
  130. #https://stackoverflow.com/questions/19477682/bash-script-determine-vendor-and-install-system-apt-get-yum-etc
  131. #https://jschumacher.info/2016/03/erasing-with-openssl/
  132. #https://wiki.archlinux.org/title/Securely_wipe_disk/Tips_and_tricks#dd_-_advanced_example
  133. #https://serverfault.com/questions/6440/is-there-an-alternative-to-dev-urandom