Форматирование винчестера
Скрипт , представленный ниже , удаляет все партиции на устройстве /dev/hdb
(slave drive на Primary IDE контроллере) , затем создает на нем одну партицию
и копирует на нее подготовленный специальный массив шифрованных данных.
Как все это проделывается ?
Удаление партиций
Для автоматизации утилиты fdisk используется Perl Expect script , имитирующий ввод пользователя.
Копирование данных
Простое удаление партиций недостаточно для удаления данных.
Запись порции данных поверх созданной партиции гарантирует удаление всех данных.
Для получения размера партиций используется sfdisk . Новая созданная партиция забивается
шифрованными данными под завязку.
В скрипте создаются случайные бинарные данные с использованием перловых функций random и chr.
Эти данные шифруются с помощью модуля Blowfish .
Форматирование вновь созданной партиции выполняется с помощью команды "mkfs" .
Perl Script
Был использован Perl 5.005_03 .
Были затрачены определенные усилия на то , чтобы сделать скрипт более дружественным.
В скрипте выполняется проверка ошибок и ведется диалог с пользователем .
(Text version of this listing)
#!/usr/bin/perl
use strict;
use Expect;
use Crypt::Blowfish;
#-----------------------------------------------
my $Junk;
### Устанавливаем на slave drive Primary IDE контроллера.
my $Drive = "hdb";
### Для получения реального random используем /etc/passwd
my $time = time();
my $Ran = rand($time);
my $Ran = rand(10000000000000);
my $LastLine = `tail -n 1 /etc/passwd`; chomp $LastLine;
$LastLine = substr ($LastLine,0,30);
my $Blowfish_Key = $LastLine . $Ran . $time;
$Blowfish_Key = substr ($Blowfish_Key,0,20);
while (length ($Blowfish_Key) < 56)
{
$Blowfish_Key .= $Ran = rand($time);
}
$Blowfish_Key = substr ($Blowfish_Key,0,56);
### Сгенерировав ключ , создаем обьект Blowfish Encryption .
my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;
#------------------------------------
system "clear";
print "Внимание! Сейчас мы сотрем все данные на /dev/$Drive\n";
print "Нажмите enter\n";
my $R = <STDIN>;
### Получим сисок партиций
my @Mounted = `df`;
@Mounted = grep($_ =~ /\/dev\/hdb/, @Mounted);
### Foreach mounted partition, umount it
foreach my $Mount (@Mounted)
{
my ($Partition,$Junk) = split(/\s+/, $Mount,2);
print "Unmounting $Partition\n";
my $Result = system ("umount $Partition");
if ($Result > 0)
{
print "ОШИБКА, невозможно применить umount к $Partition, выход, Error = $Result\n";
exit;
}
}
### Запуск expect script, имитирующего набор в командной строке
my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");
### Распечатаем таблицу партиций
print $Fdisk "p\n";
my $match=$Fdisk->expect(30,"Device Boot Start");
my $Temp = $Fdisk->exp_after();
my @Temp = split(/\n/, $Temp);
my @Partitions = grep($_ =~ /^\/dev\//, @Temp);
## Собственно удаление партиций в цикле
foreach my $Line (reverse @Partitions)
{
## Часть /dev/hdb с номером
my ($Part,$Junk) = split(/[\t ]/, $Line,2);
my $No = $Part;
$No =~ s/^\/dev\/$Drive//;
print "Партиция для удаления $Drive $No\n";
## удаление
print $Fdisk "d\n";
$match=$Fdisk->expect(30,"Partition number");
## Подставляем expect-rjl
print $Fdisk "$No\n";
$match=$Fdisk->expect(30,"Command (m for help):");
}
$Fdisk->clear_accum();
if (@Partitions < 1) {print $Fdisk "q\n"; $Fdisk->expect(2,":");}
else
{
print $Fdisk "w\n";
$Fdisk->expect(30,"Command (m for help):");
}
#-------------------------------
## Геометрия диска
my $Geometry = `/sbin/sfdisk -g /dev/$Drive`;
my ($Junk, $Cyl, $Junk2, $Head, $Junk3, $Sector,@Junk) = split(/\s+/,$Geometry);
if ($Cyl < 1)
{print "ERROR: невозможно определить цилиндры. выход\n"; exit;}
### симулируем вызов fdisk из командной строки
my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");
#### Создаем новую партицию
print $Fdisk "n\n";
$Fdisk->expect(5,"primary");
### Делаем ее primary partition
print $Fdisk "p\n";
$Fdisk->expect(5,":");
### Работаем с первой партицией
print $Fdisk "1\n";
$Fdisk->expect(5,":");
### Начинаем с 1-го цилиндра
print $Fdisk "1\n";
$Fdisk->expect(5,":");
### Заканчиваем
print $Fdisk "$Cyl\n";
$Fdisk->expect(5,":");
### Сохраняем
print $Fdisk "w\n";
$Fdisk->expect(30,"Command (m for help):");
#------------------------------------------
### Форматирование и монтирование партиции
my $Partition = "/dev/$Drive" . "1";
my $Result = system ("mkfs -t ext2 $Partition");
if ($Result > 0) {print "Ошибка при создани партиции,выход.\n"; exit;}
### Проверка ошибок
system "umount /tmp/WIPE_IT";
system "rm -rf /tmp/WIPE_IT";
system "mkdir -p /tmp/WIPE_IT";
system "chmod 700 /tmp/WIPE_IT";
## Подготовка монтирования
my $Result = system ("mount $Partition /tmp/WIPE_IT");
if ($Result > 0) {print "Ошибка монтирования устройства, выход.\n"; exit;}
system "chmod 700 /tmp/WIPE_IT";
#--------------------------------
### Создаем файл.
my $Count = 0;
my $Written_Size = 0;
### Открываем новый файл.
open(FILE,">>/tmp/WIPE_IT/Message.txt");
my $Ran = rand 259200000; # 10 лет
($Ran, $Junk) = split(/\./, $Ran, 2);
## Новый данные минус случайное число в секундах
my $Date = `date --date '-$Ran seconds'`;
print FILE "DATE CREATED $Date\n";
my $Ran = rand 50;
($Ran, $Junk) = split(/\./, $Ran, 2);
$Ran = $Ran + 10;
print FILE "Секретные данные :-) Доступ запрещен.\n";
### Создаем random number + 25000
my $Ran = rand 25000;
($Ran, $Junk) = split(/\./, $Ran, 2);
$Ran = $Ran + 25000;
### Создаем массив
my @Blank = (1..$Ran);
### Масиив переводим в строку
my $Blank = "@Blank";
### Удалим массив
@Blank = ();
my $B_Length = length $Blank;
### Определим свободное место на партиции
my @Temp = `df`;
@Temp = grep($_ =~ /^$Partition/, @Temp);
my $Line = $Temp[0];
my ($Junk,$Blocks,@Junk) = split(/\s+/, $Line,4);
### Блок в 1 килобайт
my $Size = $Blocks*1000;
## Заполняем партицию в цикле
while ($Written_Size < $Size)
{
$Count++;
### Периодически разбавляем пробелами
my $Ran = rand (10);
if ($Ran > 1)
{
print FILE $Blank;
$Written_Size = $Written_Size + $B_Length;
}
else
{
## Создадим длинную строку (10000 bytes)
my $Garbage = "";
my $Length = rand(10000);
($Length, $Junk) = split(/\./, $Length, 2);
for (my $i = 0; $i < $Length; $i++)
{
my $Ran = rand 256;
($Ran, $Junk) = split(/\./, $Ran, 2);
$Garbage .= chr $Ran;
}
## 8-битное шифрование
my $Temp = $Garbage;
my $Encrypted = "";
while (length $Temp > 0)
{
while (length $Temp < 8) {$Temp .= "\t";}
my $Temp2 = $Blowfish_Cipher->encrypt(substr($Temp,0,8));
$Encrypted .= $Temp2;
if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}
}
### Сохраняем в файл.
print FILE $Encrypted;
$Length = length $Encrypted;
$Written_Size = $Written_Size + $Length;
my $Rest = $Size - $Written_Size;
print "$Size - $Written_Size = $Rest to go\n";
}
### С периодичностью 1/50 пишем в файл
if ($Count =~ /500$/)
{
close FILE;
open(FILE,">>/tmp/WIPE_IT/$Count");
}
}
close FILE;
#----------------------------------------------------
my $Result = system ("umount $Partition");
if ($Result > 0) {print "Error unmounting partition $Partition, aborting.\n"; exit; }
### Форматирование партиции. Данные копируем
my $Result = system ("mkfs -t ext2 $Partition");
if ($Result > 0) {print "Error making partition, aborting.\n"; exit;}
Заключение
Использование Expect необязательно - показано просто для наглядности.
Использвание Blowfish необязательно.
References
- Perl.com website.
- Expect Perl Module
- Blowfish Perl Module
Copyright © 2001, Mark Nielsen.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 63 of Linux Gazette, Mid-February (EXTRA) 2001
|