Поскольку у меня были случаи, когда мой arr2
мог быть пустым, но установленным, я не мог найти простого решения. Поэтому мне пришлось использовать функцию и глобальную временную переменную. Но это работает во всех случаях, и в bash 3.2 и bash 4
function set_temp_array()
{ # 1 - source_array_name $2-* default_values
local default="$1"
shift
if declare -p $default >& /dev/null; then
default="${default}[@]"
TEMP_VAR=("${!default}")
else
TEMP_VAR=("${@}")
fi
}
set_temp_array arr1 "${arr2[@]}"
arr1="${TEMP_VAR[@]}"
я использую косвенную ссылку на массив для копирования значений в TEMP_VAR
, но я не мог определить косвенное присвоение массива в bash, поэтому две строки и временная переменная
Для вас установите -eu
fan out there
function set_temp_array()
{ # 1 - source_array_name $2-* default_values
local default="$1"
shift
if declare -p $default >& /dev/null; then
default="${default}[@]"
TEMP_VAR=(${!default+"${!default}"})
else
TEMP_VAR=(${@+"${@}"})
fi
}
set_temp_array arr1 ${arr2+"${arr2[@]}"}
arr1=(${TEMP_VAR+"${TEMP_VAR[@]}"})
Debian и Ubuntu поставляют скрипт кэширования паролей decrypt _keyctl с пакетомcryptsetup .
Сценарийdecrypt _keyctl предоставляет один и тот же пароль для нескольких зашифрованных целей LUKS, избавляя вас от необходимости вводить его несколько раз. Его можно включить вcrypttabс опцией keyscript=decrypt_keyctl
. Один и тот же пароль используется для целей, которые имеют одинаковый идентификатор в поле ключевого файла . При загрузке пароль для каждого идентификатора запрашивается один раз.
Пример crypttab:
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks luks,keyscript=decrypt_keyctl
part2_crypt /dev/disk/... crypt_disks luks,keyscript=decrypt_keyctl
Сценарий decrypt_keyctl
зависит от пакета keyutils
(, который только предлагается и поэтому не обязательно должен быть установлен ).
После того, как вы обновите свой cryptab , вам также потребуется обновить initramfs, чтобы изменения вступили в силу. Используйтеupdate-initramfs -u
.
Полный файл readme для расшифровки _keyctl находится в/usr/share/doc/cryptsetup/README.keyctl
К сожалению, в настоящее время это не работает в системах Debian, использующих systemd init из-заошибки(другие системы инициализации не должны затрагиваться ). Из-за этой ошибки systemd второй раз запрашивает пароль, что делает невозможным удаленную разблокировку через ssh. Debianсправочная страница crypttabпредлагает в качестве обходного пути использовать параметр initramfs
для принудительной обработки на этапе загрузки initramfs. Итак, чтобы обойти эту ошибку, пример для /etc/crypttab в Debian
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks luks,initramfs,keyscript=decrypt_keyctl
part2_crypt /dev/disk/... crypt_disks luks,initramfs,keyscript=decrypt_keyctl
Если decrypt _keyctrl не предусмотрен вашим дистрибутивом, устройство можно разблокировать с помощью ключевого файла в зашифрованной корневой файловой системе.Это когда корневая файловая система может быть разблокирована и смонтирована раньше любого другого зашифрованного устройства.
LUKS поддерживает несколько слотов для ключей. Это позволяет альтернативно разблокировать устройство с помощью пароля, если файл ключа недоступен/утерян.
Сгенерируйте ключ со случайными данными и установите его права доступа только для чтения владельцем, чтобы избежать его утечки. Обратите внимание, что файл ключа должен находиться в корневом разделе, который разблокируется первым.
dd if=/dev/urandom of=<path to key file> bs=1024 count=1
chmod u=rw,g=,o= <path to key file>
Добавьте ключ на устройство LUKS
cryptsetup luksAddKey <path to encrypted device> <path to key file>
Настройте crypttab для использования файла ключа. Первая строка должна быть корневым устройством, так как устройства разблокируются в том же порядке, что и в crypttab . Используйте абсолютные пути для ключевых файлов.
<target> <source> <keyfile> <options>
root_crypt /dev/disk/... none luks
part1_crypt /dev/disk/... <path to key file> luks
Вот мой обходной путь для Debian, учитывая ошибку, упомянутую выше @sebasth.
Мои настройки немного отличаются. У меня есть зашифрованный корневой раздел и куча рейдовых дисков. Для меня мне пришлось добавить опцию initramfs в crypttab:
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs
part2_crypt /dev/disk/... crypt_disks plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs
Это сообщает обновлению -initramfs, что я хочу смонтировать эти записи crypttab в initramfs. Я проверил свой crypttab, запустив
cryptdisks_start part1_crypt
cryptdisks_start part2_crypt
Обратите внимание, что мои рейд-диски представляют собой обычный dm -crypt. Это означало, что я не мог использовать метод ключевого файла luks, который работает с ошибкой ключевого скрипта systemd. Для обычного dm -crypt мне пришлось бы хранить парольную фразу в виде открытого текста.
Перед запуском update-initramfs
необходимо установить пакет keyutils и смонтировать зашифрованные диски; иначе он выдаст ошибки.При сборке initramfs мне пришлось искать следующие строки:
update-initramfs -u -v | grep 'keyctl'
, который показал следующие два файла:
/bin/keyctl
cryptkeyctl
добавляется в файл initramfs.
Наконец, мне пришлось отключить systemd для обработки моего crypttab, чтобы справиться с ошибкой, упомянутой выше :systemd не поддерживает опцию keyscript в crypttab. Для этого я добавил параметр ядра
GRUB_CMDLINE_LINUX_DEFAULT="quiet luks.crypttab=no"
в /etc/default/grub и запустил update-grub
. systemd теперь игнорирует crypttab, а все зашифрованные разделы загружаются в файл initramfs.
Поскольку у меня есть зашифрованный корневой раздел, похоже, что cryptroot не кэширует мой ключ. Это означает, что я должен ввести свой пароль дважды; один для корневого раздела и один раз для моего массива рейдов.
Другой вариант — использовать скрипт /lib/cryptsetup/scripts/decrypt_derived
, который также является частью cryptsetup в Debian/Ubuntu.
Вместо кэширования ключа вы используете ключ тома одного диска в качестве дополнительного пароля для второго диска. Для этого требуется добавить второй пароль ко второму (и третьему и т. д. )зашифрованным дискам, но LUKS поддерживает это. Поэтому это решение также работает, если ваши несколько зашифрованных дисков не используют один и тот же пароль.
Пример добавления ключа из sda6crypt в sda5:
Добавить ключ тома sda6crypt в качестве дополнительного пароля для sda5:
mkfifo fifo
/lib/cryptsetup/scripts/decrypt_derived sda6crypt > fifo &
cryptsetup luksAddKey /dev/sda5 fifo
rm fifo
Настройте автоматическую разблокировку sda5crypt в/etc/crypttab
ls -la /dev/disk/by-uuid/ | grep sda5
echo "sda5crypt UUID=<uuid> sda6crypt luks,initramfs,keyscript=/lib/cryptsetup/scripts/decrypt_derived" >> /etc/crypttab
При этом используется именованный канал(fifo
)для передачи ключа, чтобы не хранить ключ громкости во временном файле на диске.
Параметр keyscript
работает только в том случае, если crypttab
обрабатывается оригинальными инструментами cryptsetup Debian, повторная реализация systemd в настоящее время не поддерживает его. Если ваша система использует systemd (, то есть большинство систем ), вам нужна опция initramfs
, чтобы принудительно выполнить обработку в initrd с помощью инструментов cryptsetup до запуска systemd.
На основанииhttps://unix.stackexchange.com/a/32551/50793