Шифровать будем отдельный раздел на отдельном HDD, не содержащий корневую файловую систему, алгоритмом, использующимся по-умолчанию в каждом конкретном случае. Как обычный пользователь, я не разбираюсь в нюансах стандартов шифрования (например, чем отличается хэширование RIPEMD-160 от Whirpool, какой из этих режимов быстрее, какой способствует более высокой защите), поэтому просто положимся на то, что производители каждого программного продукта выбрали достаточно криптостойкие параметры по-умолчанию. Может, это и не совсем корректно, т. к. производительность различных алгоритмов шифрования неодинакова. При желании, конечно можно сменить тип шифрования, но я не уверен, что во всех тестируемых продуктах существует абсолютно идентичный набор алгоритмов. Тестировать будем:
1) LUKS — нативная система шифрования, в теории должна быть самой быстрой. Тома, зашифрованные LUKS можно использовать в Windows через FreeOTFE.
2) Truecrypt — в отличии от LUKS имеет, кроме консольного, и GUI-интерфейс, что делает его на порядок удобнее в использовании. Мультиплатформенное ПО. Обеспечение двух уровней правдоподобного отрицания наличия зашифрованных данных, необходимого в случае вынужденного открытия пароля пользователем. Тома Truecrypt не имеют заголовка, их нельзя отличить от набора случайных данных. В теории медленнее, чем LUKS, т.к. использует FUSE.
3) eCryptfs — система, по умолчанию предлагаемая пользователям Ubuntu для шифрования домашних каталогов, поэтому и включена в данный тест. Работает поверх уже существующей ФС. Шифрует каждый файл отдельно, поэтому всем видны права, даты изменения, количество зашифрованных файлов; по-умолчанию также видны имена файлов, хотя и существует опция для их шифрования. Самое малофункциональное средство из представленных.
Итак, для тестов выделена отдельная машина довольно преклонного возраста в следующей конфигурации: ЦП — Intel Celeron 2000Mhz, ОЗУ — 512 Mb DDR PC2700, системный HDD — WD Caviar SE 5400 RPM 80Gb, тестовый HDD — WD Caviar SE 7200 RPM 80Gb.
ОС — Ubuntu 12.04 LTS, версии всего ПО актуальные для репозиториев этой ОС на момент написания статьи (Truecrypt 7.1a-linux-x86 не из репозиториев).
Тестировать будем дефолтную для большинства дистрибутивов файловую систему ext4. Для тестирования производительности будем использовать утилиту iozone3 и написанный «на коленке» shell-скрипт для измерения процентной разницы в тестах.
#!/bin/sh gendifffile () { #процедура генерирует файл, который удобно анализировать. Во-первых, обрезаются #не подлежащие анализу строки; во-вторых, в каждой строке обрезаются первых два числа, обозначающие #размер файла и размер записи соответственно; в-третьих, весь файл выводится построчно - #один результат теста на одну строку cat $1 | while read LINE ; do echo $LINE| grep "^[[:space:]]*[[:digit:]]" | awk '{for (i=3;i<=NF;i++) {print $i}}' done >> $2 } getline () { #процедура выводит строку номер $2 файла $1 head -n $2 "$1" | tail -n 1 } compare () { #процедура сравнивает построчно файлы $1 и $2, вычисляя процентную разницу каждой пары тестов #затем вычисляется среднее арифметическое значение, на сколько процентов быстрее или медленнее #файл, содержащий первую группу тестов, файла, содержащего вторую группу P=0 MAX=0 L1=`cat "$1" | wc -l` #количество тестов в файле L2=`cat "$2" | wc -l` if [ $L1 -ne $L2 ]; then #если файлы содержат разное количество тестов, то сравнивать их мы не будем echo error return fi STEP=$(( $L1*5/100 )) J=0 for I in `seq 1 $L1`; do J=$(( $J+1 )) if [ $J -eq $STEP ]; then J=0 echo "$(( 100*$I/$L1 ))% завершено ($I из $L1)" fi A=`getline "$1" $I` B=`getline "$2" $I` if [ `echo $A \> $B|bc -l` -eq 1 ]; then D=`echo "100-($B*100/$A)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; then MAX=$D sleep 5 fi else D=`echo "100-($A*100/$B)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; then MAX=$D sleep 5 fi D="-$D" #если значение имеет знак "-", значит, данный тест был выполнен быстрее #во втором файле, а не в первом fi P=`echo "$P+$D"| bc -l` done P=`echo $P/$L1| bc -l` #вычислим среднее арифметическое echo PERCENT=$P MAX_PERCENT=$MAX } genaverage () { #процедура генерации подготовленного к анализу файла, каждой строкой которого является #среднее арифметическое соответствующих строк всех файлов отчётов, лежащих в анализируемой директории AVG=`mktemp` F=`ls "$1"|wc -l` #количество файлов с отчётами в заданной директории #при условии, что там хранятся только такие файлы и больше ничего другого #проверять корректность данного допущения мы не будем if [ ! -d "$1" -o $F -lt 2 ]; then echo error >/dev/stderr #в этой процедуре будем выводить все сообщения в stderr, т.к. #stdout подставляется в другую процедуру rm -f $AVG exit fi TMP=`mktemp` find "$1" -type f| while read FILE; do #для каждого файла отчёта iozone, лежащего в заданной директории I=`mktemp` #сгенерируем временный файл, подготовленный для анализа gendifffile "$FILE" "$I" #имена всех таких файлов запишем в "TMP" построчно echo "$I">>$TMP done L=`cat \`getline "$TMP" 1\`|wc -l` cat "$TMP"| while read LINE; do #немного проверок не помешает L1=`cat "$LINE"| wc -l` #все ли файлы содержат одинаковое количество тестов if [ $L -ne $L1 ]; then echo error >/dev/stderr exit fi done STEP=$(( $L*5/100 )) J=0 for I in `seq 1 $L`; do J=$(( $J+1 )) if [ $J -eq $STEP ]; then J=0 echo "$(( 100*$I/$L ))% завершено ($I из $L)" >/dev/stderr fi SUMFILE=`mktemp` #таким образом я получаю значение переменной SUM из вложенного цикла SUM=0 cat "$TMP"| while read LINE; do SUM=$(( `getline "$LINE" $I`+$SUM )) echo $SUM > "$SUMFILE" done echo `tail -n 1 "$SUMFILE"`/$F|bc -l >> $AVG #получаем среднее арифметическое #и запишем его в соответствующее место #файла AVG rm -f "$SUMFILE" done cat "$TMP"| while read LINE; do #удалим временныe файлы rm -f "$LINE" done rm -f "$TMP" echo $AVG } printf %b "\\033[1;31mШаг 1/3\n" printf %b "\\033[1;37m" echo Генерируем усреднённый файл для директории \""$1"\" A=`genaverage "$1"` printf %b "\\033[1;31mШаг 2/3\n" printf %b "\\033[1;37m" echo Генерируем усреднённый файл для директории \""$2"\" B=`genaverage "$2"` printf %b "\\033[1;31mШаг 3/3\n" printf %b "\\033[1;37m" echo Сравниваем усреднённые файлы compare "$A" "$B" rm -f $A $B
Положимся на режим -a, в котором iozone должен произвести в автоматическом режиме серию тестов, которые покрывают всевозможные операции с файлами разных размеров и разной длиной записи (моя версия произвела 1638 тестов).
В ходе эксперимента выяснилось, что одна серия тестов iozone может отличаться от другой по производительности на 5%, поэтому я не буду рассчитывать на результаты одного-единственного набора тестов и поступлю таким образом: проведу набор тестов несколько раз и сгенерирую файл с усредненными значениями по каждому из тестов (во всех расчётах данной статьи под усредненными значениями понимается среднеарифметическое значение). После этого я сравню усредненный файл, содержащий серию тестов по незашифрованной файловой системе с аналогичным файлом, содержащим серию тестов на зашифрованной ФС таким образом: каждый тест первого файла будет сравнен с соответствующим тестом второго в процентном соотношении, результаты сложим, а сумму разделим на количество тестов, получив среднеарифметическое значение, на сколько процентов первая группа тестов быстрее или медленнее второй.
Также, для простой оценки скорости, в дополнение к вышеописанным вычислениям, проведем простенький тест — копирование средствами dd 500 мегабайт из urandom на зашифрованную ФС блоками, равными размеру кластера ext4 по-умолчанию (4 килобайта). dd if=/dev/urandom of=testfile bs=4k count=128000. Шифровать будет раздел целиком (за исключением eCryptfs, которая этого делать не умеет). Я не буду приводить команды для каждого конкретного случая, покажу только результаты.
Итак, приступим:
1) Система шифрования: нет
Количество проведенных серий тестов: 14
Средняя разница в производительности между одинаковыми сериями тестов: 1,3%
Результат dd: 524288000 bytes (524 MB) copied, 187.823 s, 2.8 MB/s
2) Система шифрования: LUKS. Используя ключи по-умолчанию, наш том будет зашифрован так:
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha1
Количество проведенных серий тестов: 8
Средняя разница в производительности между одинаковыми сериями тестов: 1,4%
Результат dd: 524288000 bytes (524 MB) copied, 199.505 s, 2.6 MB/s
Падение производительности по сравнению с нешифрованной ФС: 7,9%
3) Система шифрования: Truecrypt. Применяя все параметры по-умолчанию, том будет зашифрован AES с алгоритмом хеширования RIPEMD-160.
Количество проведенных серий тестов: 22
Средняя разница в производительности между одинаковыми сериями тестов: 3,2%
Результат dd: 524288000 bytes (524 MB) copied, 199.719 s, 2.6 MB/s
Падение производительности по сравнению с нешифрованной ФС: 7%
4) Система шифрования: eCryptfs
aes: blocksize = 16; keysize = 16
Количество проведенных серий тестов: 9
Средняя разница в производительности между одинаковыми сериями тестов: 0,9%
Результат dd: 524288000 bytes (524 MB) copied, 199.624 s, 2.6 MB/s
Падение производительности по сравнению с нешифрованной ФС: 49,5%
Итог: производительность eCryptfs по всевозможным файловым операциям оставляет желать лучшего, хотя обычный тест dd с оптимальным размером блока показывает скорость, аналогичную остальным системам шифрования. Шифровать целиком ей домашнюю директорию я бы не стал. Удобно применять лишь при шифровании отдельных поддиректорий. Ожидания меньшей производительности Truecrypt из-за использования FUSE не оправдались, в моём случае он оказался даже немного быстрее LUKS.
В дополнение, как бонус, приведу аналогичный тест dd для Truecrypt и LUKS, но для file-hosted контейнера (все параметры шифрования аналогичны).
1) LUKS
524288000 bytes (524 MB) copied, 207.07 s, 2.5 MB/s
2) Truecrypt
524288000 bytes (524 MB) copied, 205.046 s, 2.6 MB/s
Падение производительности можно объяснить тем, что появляются дополнительные накладные расходы на чтение файла контейтера с уже существующей файловой системы вместо прямого обращения к разделу.
ссылка на оригинал статьи http://habrahabr.ru/post/201694/
Добавить комментарий