ITСooky

IT-рецепты съедобные и не очень!

Зашифрованное хранилище с запуском по USB ключу и паролю!

дата 06.09.2011

Создаем зашифрованное хранилище данных на файл-сервере с запуском с USB ключом и вводом пароля.

Ингредиенты:

1. Сервер FreeBSD 8.1 с установленной Samba
2. SATA HDD любого размера
3. SATA DAT кабель
4. USB flash накопитель
5. PuTTY

Вставляем жесткий диск, тут самое трудное открыть корпус и найти свободное место. У меня корпус экзотический Desktop Delux «B166» Slim, но очень удобный площадка под HDD и DVD отворачивается в сторону чтобы можно было поставить устройства, в собранном виде это не получится слишком тесно всё.

Два HDD WD, зеленой тихой, экономичной, не скоростной серии, отлично смотрятся вместе!

Кабели SATA дата и питания турдно подключить не правильно, а вот сломать после подключения легко, не надо их дергать особенно вниз! Если в корпусе нет разъема питания SATA нужен переходник питания PATA HDD->SATA HDD.

Другой конец SATA дата кабеля втыкаем в мать, если первый раз то не важно куда, после установки в ОС и последующей разборки кабеля надо возвращать на свои места.

Блок питания в этом корпусе слабый, пришлось вешать питание на разные кабели обязательно. Вот так все выглядит в сборе, все кабели спрятаны под диски, отличный корпус!

Всё включаем сервер заходим на него с помощью PuTTY по SSH. Новый жесткий диск установлен системой определяется делаем:

ls /dev

видим в списке новый диск

ad6

Приступаем к установке шифрования для этого надо пересобрать ядро ОС с нужными параметрами! Для начала посмотрим что у нас за версия ситемы делаем:

uname -a

или

sysctl kern.version

видим

FreeBSD Server.home 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Apr 20 22:44:28 MSD 2009     root@Server.home:/usr/src/sys/i386/compile/ipfw  i386

У нас не стандартное ядро, кто-то его уже пересобирал (я даже знаю кто :@) ) и назвал ipfw — это важно именно в файл с этим именем надо добавить новые параметры чтобы сохранились старые!

Перед сборкой ядра надо установить его исходники например с CD, делать это надо при первой пересборке ядра!

sysinstal

выбираем
Configure>Distributions>
[] src Source for everything
[x] sys
OK

Теперь приступаем к сборке ядра тут используем ранее выясненное имя ядра ipfw

cd /usr/src/sys/i386/conf
cp ipfw ipfwcrypt

Открываем файл, напоминаю команды редактора vi — кнопки [esc] [i] редактировать, [esc] [x] удалить, [esc] [:q!] [enter] выйти без записи, [esc] [:wq!] [enter] выйти записать.

vi ipfwcrypt

меняем строку на

ident    ipfwcrypt

добавляем снизу где нибудь

options GEOM_ELI
device crypto

далее делаем

config ipfwcrypt
cd /usr/src/sys/i386/compile/ipfwcrypt
make cleandepend && make && make install

Последняя операция занимает значительное количество времени, по окончании надо добавить в /boot/loader.conf

vi /boot/loader.conf

текст

geom_eli_load="YES"

И перезагружаемся

reboot

Самое время выбрать алгоритм шифрования. Blowfish — отличный алгоритм его хвалят за стойкость и скорость. Ключ может быть от 16 до 448 бит, у нас будет 256. А вот скорость сильно зависит от процессора(не проверял но проверю), в моем случаи (Dual Celeron E1200 1,6Mhz, 1Gb) она упала в 5 раз со 100мб/c до 20 мб/c, на одном диске просто разные разделы зашифрованный и нет.
Скорость можно проверить командой

diskinfo -t ad6

Идем в папку /root

cd /root

Генерируем ключ под каким нибудь незамысловатым обычным именем расширение файла не важно

dd if=/dev/random of=ads.txt bs=256 count=1 

Диск ad6 у нас новый никак не прописанный в системе так что сразу делаем его шифродиском

geli init -s 4096 -K ads.txt -e Blowfish -l 256 /dev/ad6

Система запросит два раза пароль на этот шифро диск — его надо запомнить
Подключаем шифро диск

geli attach -k ads.txt /dev/ad6

В выводе команды ls /dev должно появится ad6.eli
Создаем на нем раздел

newfs /dev/ad6.eli

Теперь для проверки делаем папку и монтируем туда шифродиск

mkdir /root/test
mount /dev/ad6.eli/ /root/test

Смотрим

df -h

Всё на своем месте

/dev/ad6.eli    1.8T    8.0K    1.6T     0%    /root/2

Далее размонтируем диск и отключим

umount /dev/ad6.eli
geli detach /dev/ad6.eli

Для уже включенного в систему диска его надо удалить из загрузки, у нас это ad4s3d, все данные с него будут потеряны конечно же!

vi /etc/fstab

убираем или комментируем # строчку

/dev/ad4s2d            /usr/data/hdd1             ufs     rw

и повторяем все выше описанные действия для этого слайса, конечно меняя имена и пароли!

На данном этапе у нас есть шифродиск, теперь сделаем так чтобы ключ хранился на USB(чтобы его оперативно прятать или глотать(что бессмысленно флешка не успеет растворится(хотя кто знает тестов не было))), а пароль вводился с любой машины которая в тойже сети что и файл-сервер при помощи специального ярлыка программы — все это поможет упростить процесс подключения.

Флешку берем любую обычную. Я взял не такую маленькую но по своему эффектную флешку от SanDisk, кстати на ней уже есть что-то для шифрования но нам это не нужно!



Вставляем флешку в сервер, её можно увидеть командой

ls /dev

она будет выглядит вот так, если она выглядит по другому надо это учесть в программе которая будет ниже

 da0
da0s1

Создаем папку для флешки

mkdir /mnt/usb

Монтируем флешку

mount -t msdosfs /dev/da0s1 /mnt/usb

Копируем на флешку ключ он может лежать как в корне так и в папке, лучше как кто прятать

cp /root/ads.txt /mnt/usb/

Отключаем флешку, при это главное не сидеть в её папке в этот момент

cd /
umount /dev/da0s1

На нашем сервере будет лежать скрипт на языке expect — устанавливаем её из коллекции портов (которую можно поставить с DVD)

cd /usr/ports/lang/expect
make install

Идем в папку /root и делаем файл

cd /root
vi shd

Вставляем туда текст

#!/usr/local/bin/expect -f
set timeout 300
stty -echo
# Nastroiki
set raz1 ad5
set raz2 ad6
set key1 1.txt
set key2 2.txt
set dir1 /usr/data/1
set dir2 /usr/data/2
set usbdir "" 
# dalshe ne menyat
set pass 0000
set v0 0
set v1 0
set v2 0
set v3 0
set v4 5 
set v5 0
set v6 1 
log_user 0 
spawn df
expect  "da0s\[1-9]" {
   set usbname $expect_out(0,string)
catch {system umount /dev/$usbname}}
puts "__________________________________
!!! Vremya dlya otveta na voprosi
ogranicheno 5-u minutami!!!
__________________________________
Vstavti USB flash s kluchami v Server
"
while { $v0 eq 0} {
spawn ls /dev
expect  "da0s\[1-9]" {
   set usbname $expect_out(0,string)
set v0 1
 puts "__________________________________
USB Flash obnaruzhena"
system mount_msdosfs /dev/$usbname /mnt/usb
}
}
spawn ls /mnt/usb$usbdir
expect  "$key1" {set v1 1}
if {$v1 eq 1} {
puts "__________________________________
Naiden kluch $key1"
spawn df
expect "$raz1" {set v3 1}
if {$v3 eq 0} {
puts "__________________________________
Podkluchaem razdel $raz1"
while {$v4 > 0} {
puts "__________________________________
Vvedite kluch dlya razdela $raz1 
Posle vvoda nazhmite \[ENTER\]:"
expect_user -re "(.*)\n" {set pass $expect_out(0,string) 
set v6 1
}
spawn geli attach -k /mnt/usb/$key1 /dev/$raz1
expect "Enter passphrase:"
send "$pass\r"
expect "Wrong key" {set v4 [expr $v4-1]
set v6 0}
if {$v6 eq 0} {puts "__________________________________
!!! Nepravilniy kluch !!!
Ostalos popitok $v4"
} else {spawn mount /dev/$raz1.eli $dir1
expect "Operation not permitted" {set v6 2}
if {$v6 eq 2} {puts "Neobjodima proverka diska pered podklucheniem
veroyatno bilo avarionoie otkluchenoe electropitania
zhdite okonchaniya___________________________"
system /sbin/fsck -y -t ufs /dev/$raz1.eli&&mount /dev/$raz1.eli $dir1
set v4 0
} else {set v4 0}
puts "__________________________________
!!! Razdel $raz1 PODKLUCHEN USPEWNO!" 
}}
} else {puts "__________________________________
Razdel $raz1 uzhe podkluchen"
}
} else {puts "__________________________________
!!! Kluch $key1 ne nauden"}
set v0 0
set v1 0
set v2 0
set v3 0
set v4 5
set v5 0
set v6 1 
spawn ls /mnt/usb/$usbdir
expect  "$key2" {set v1 1}
if {$v1 eq 1} {
puts "__________________________________
Naiden kluch $key2"
spawn df
expect "$raz2" {set v3 1}
if {$v3 eq 0} {
puts "__________________________________
Podkluchaem razdel $raz2"
while {$v4 > 0} {
puts "__________________________________
Vvedite kluch dlya razdela $raz2 
Posle vvoda nazhmite \[ENTER\]:"
expect_user -re "(.*)\n" {
   set pass $expect_out(0,string)
set v6 1
}
spawn geli attach -k /mnt/usb/$usbdir/$key2 /dev/$raz2
expect "Enter passphrase:"
send "$pass\r"
expect "Wrong key" {set v4 [expr $v4-1]
set v6 0}
if {$v6 eq 0} {puts "__________________________________ 
!!! Nepravilniy kluch !!!
Ostalos popitok $v4"
} else {spawn mount /dev/$raz2.eli $dir2
expect "Operation not permitted" {set v6 2}
if {$v6 eq 2} {puts "Neobjodima proverka diska pered podklucheniem
veroyatno bilo avarionoie otkluchenoe electropitania
zhdite okonchaniya___________________________"
system /sbin/fsck -y -t ufs /dev/$raz2.eli&&mount /dev/$raz2.eli $dir2
set v4 0
} else {set v4 0}
puts "__________________________________
!!! Razdel $raz2 PODKLUCHEN USPEWNO!"
}}
} else {puts "__________________________________
Razdel $raz2 uzhe podkluchen"
}
} else {puts "__________________________________
!!! Kluch $key2 ne nauden"}
puts "__________________________________"
system umount /dev/$usbname && df -h | grep eli

Имена под которыми у вас шифродиски

set raz1 ad4s3d
set raz2 ad6

Имена ключей соответствующие дискам

set key1 ad4s3d.key
set key2 ads.txt

Папки куда монтируем диски, они должны быть уже созданы (

mkdir

) и чтобы сразу раздавать файлы должны быть в папке Samba’ы

set dir1 /mnt/1
set dir2 /root/test

Папки где лежат ключ «/» слеш сзади и спереди не ставим

set usbdir1 tmp/trash
set usbdir2 tmp

Чтобы скрипт запускался его надо сделать исполняемым

chmod 755 shd

Теперь делаем программу для запуска все операции, на Windows машине создаем папку с в которой создаем файл start.bat
а в нем текст

@echo off
plink.exe -t -ssh 192.168.1.100 -l root -pw expect /root/shd
pause

Даем ему права на исполнение

chmod 755 shd

Здесь IP нашего сервера и строка запуска скрипта shd

В эту же папку кладем файл plink.exe качаем его от сюда http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Уже можно пробовать запускаем файл start.bat так как это первый заход по ssh (ну на чужой машине возможно первый) создаем ssh ключи, в следующие разы это не повторится. Сначала вводим пароль админа, потом система пытается подключить 1 usb флешку (в сервере должна быть одна) и ищет там ключи, если находит ключи предлагает ввсети пароль, в конце вводит на экран кооманду

df -h

видно что подключилос!

Теперь делаем все одним исполняемым файлом — который кстати не содержит не ключей ни паролей только IP сервера можно его не прятать! Скачиваем программу BAT to EXE converter к сожалению на новые версии программы наложено ограничение можно запускать результат только на том ПК на котором он был сделан, так что пользуемся старой версией, скачиваем например от сюда http://www.f2ko.de/programs.php?lang=en&pid=b2e


Batch file это наш start.bat, галочки как на картинке, во вкладке Include добавляем plink.exe, во вкладке Versioninfomations можно выбрать иконку.

Теперь почти всё! Чтобы защифрованный диск у нас не висел вечно будем его отключать, пока по расписанию (потом может чтото красивее придумаю)
Для начала узнаем какое у нас время

date

Результат явно опаздывает от реальноти

Tue Sep  6 13:46:45 MSD 2011

Меняем

date 201109061703
Tue Sep  6 17:03:00 MSD 2011

Лезем в планировщик (можно так его назвать)

crontab -e

Добавляем строчку которая отключит шифродиск в 5 17 минут утра каждого дня, правила редактирования такие же как в vi

17 5 * * * /sbin/umount /dev/ad6.eli && /sbin/geli detach /dev/ad6.eli

Второй вариант
Скрипт который отключает шифродиски при простое Файл Сервер Samba больше заданного времени от минуты(связано также с периодичностью его запуска) до 30 дней. Скрип учитывает первое обнаружение шифродисков или активность Samba — это исключает отклбчение при скачивание больших файлов.

И так идем в папку /root и делаем файл

cd /root
vi status_off

Вставляем следующий код

#!/usr/local/bin/expect -f
# Nastroiki
# ot 0-59
set minout 0 
# ot 0-23
set hourout 0
#ot 0 do 30 pogrewnost 1-2 dnya
set dayout 1
# cmd - "commanda" ili "commanda $ comanda & ... " 
set cmd "/sbin/umount -f /dev/ad5.eli && /sbin/geli detach /dev/ad5.eli && /sbin/umount -f /dev/ad6.eli && /sbin/geli detach /dev/ad6.eli"
#dalshe ne menyat
set out [expr $minout+$hourout*100+$dayout*10000] 
set timeout 300
set date 0
set v1 0
set l 0 
set file 0
log_user 0 
spawn /bin/date +"%d%H%M"
expect "\[0-9]\[0-9]\[0-9]\[0-9]\[0-9]\[0-9]" {
set date $expect_out(0,string)
} 
spawn /usr/local/bin/smbstatus -L
expect "\[0-9]\[0-9] \[0-9]\[0-9]:\[0-9]\[0-9]" { 
set l $expect_out(0,string)
regsub -all {:| } $l {} l 
system /bin/echo "$l" >>  /tmp/t.d 
exit
}
spawn /bin/ls /tmp
expect "t.d" {set l 1}
if {$l eq 1} { 
set file [open "/tmp/t.d" r]
seek $file -7 end
set v1 [read $file 7]
} else {
spawn /bin/df -h
expect "eli" {
system /bin/echo "$date" >>  /tmp/t.d
set v1 $date
}
exit
}
set a1 0
set a2 0
regexp {..$} $date $a1
regexp {..$} $v1 $a2
if [expr $a1-$a2]<0 {
set $date [expr $date+60]
}
set a1 0
set a2 0
regexp {....$} $date $a1
regexp {....$} $v1 $a2
if [expr $a1-$a2]<0 {
set $date [expr $date+2300]
}
if [expr $date-$v1]<0 {
set $date [expr $date+290000]
}
if [expr $date-$v1]>$out {
catch {system $cmd}
catch {system /bin/rm /tmp/t.d}
} else {exit}

Настройки

set cmd "/sbin/umount -f /dev/ad5.eli && /sbin/geli detach /dev/ad5.eli && /sbin/umount -f /dev/ad6.eli && /sbin/geli detach /dev/ad6.eli"

— здесь в кавычках пишем команду которую хотим выполнить, при срабатывание нашего условия, тут две команды объединенные && — это значит что вторая не начнется пока не кончится первая команда. Чтобы отключить второй диск добавляем в строчку еще такую же команду(со новыми именами) соединяя её с первым блоком & — это значит начало исполнения этой команды не зависит от успешного завершения предыдущей.

set minout

— максимальное время простоя, в минутах от 0 до 59

set hourout

— максимальное время простоя, в часах от 0 до 23

set dayout

— максимальное время простоя, в днях от 0 до 30, будет погрешность в 1-2 дня зависит от месяца

Даем ему права на исполнение

chmod 755 status_off

Лезем в планировщик (можно так его назвать)

crontab -e

Добавляем строчку которая будет запускать скрипт каждые 15 минут(не больше вашего минимального интервала простоя), правила редактирования такие же как в vi

15 * * * * /usr/local/bin/expect -f /root/status_off >> /dev/null 2>&1