Удаленное разблокирование томов зашифрованных luks в CentOS6 через ssh

от автора

Приведенный ниже материал является адаптацией и дополнением метода удаленного разблокирования томов, предложенного «Michael Scherer» в bagzilla redhat, применительно к CentOS 6 x64. Суть метода заключается в модификации initramfs.

Установка дополнительных пакетов

В initramfs мы добавим ssh-сервер dropbear, его нет в стандартных репозиториях, по этому нужно подключить внешний — epel:

rpm -Uhv http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm yum -y install dropbear 

Модификация initramfs

В CentOS 6 для генерации initramfs используется довольно удобная система- dracut, дополнительный модуль для которой мы и будем создавать. Он представляет из себя папку в /usr/share/dracut/modules.d со скриптами установки и необходимыми файлами.

cd /usr/share/dracut/modules.d mkdir 40unlock cd 40unlock 

Основной скрипт установки модуля:

cat > install << 'EOF' #!/bin/bash  cat /etc/shadow|grep root > ${moddir}/shadow  dracut_install /lib64/libnss_compat.so.2  dracut_install /lib64/libnss_files.so.2  dracut_install /lib64/libnss_dns.so.2  inst_dir "/etc/dropbear"  inst "${moddir}/dropbear_rsa_host_key" "/etc/dropbear/dropbear_rsa_host_key"  inst_dir "/home"  inst_dir "/home/root"  inst_dir "/home/root/.ssh"  inst "${moddir}/.profile" "/home/root"  [ -s "${moddir}/authorized_keys" ] && inst "${moddir}/authorized_keys" "/home/root/.ssh/authorized_keys"  inst "/etc/localtime"  inst "${moddir}/nsswitch.conf" "/etc/nsswitch.conf"  inst "/etc/resolv.conf"  inst "/etc/host.conf"  inst "/etc/hosts"  inst "${moddir}/shadow" "/etc/shadow"  inst "${moddir}/passwd" "/etc/passwd"  inst "${moddir}/shells" "/etc/shells"  inst "${moddir}/unlock" "/bin/unlock"  inst_hook pre-trigger 01 "$moddir/remote-ssh.sh"  inst_hook pre-pivot 01 "$moddir/clean.sh"  dracut_install sed awk dropbear ifconfig route blkid cut killall true mkdir  dracut_install -o ps find grep less cat tac head tail false rmdir rm touch vi ping ssh scp lsmod EOF 

Он берет из shadow зашифрованный пароль root, для возможности удаленного входа по паролю, если вам нужна авторизация по ключу, то положите в эту же папку файл authorized_keys c публичным ключём внутри и правами доступа 600. Также происходит установка всех необходимых конфигурационных файлов, команд и динамических библиотек. Файлы hosts, resolv.conf и host.conf берутся системные. Ставятся 2 хука: первый(remote-ssh.sh) запускает dropbear еще до запроса пароля и второй(clean.sh) убивает процесс dropbear перед сменой корневой фс. В «dracut_install -o» указаны опциональные команды, которые могут быть установлены в initramfs при наличии в основной системе.

Скрипт «проверки»:

cat > check << 'EOF' #!/bin/sh exit 0 EOF 

Если не хотите чтобы этот модуль использовался dracut по умолчанию, то поменяйте код выхода на 255, а так при обновлении ядра новый initramfs будет включать в себя этот модуль.

Скрипт установки модулей ядра:

cat > installkernel << 'EOF' #!/bin/bash instmods e1000 EOF 

Включение нужных модулей ядра в initramfs, в данном случае для поддержки сетевой карты intel e1000, замените на свой( посмотреть можно командой lspci -k ).

Теперь создадим все необходимые конфигурационные файлы и наши скрипты.

echo 'root:x:0:0:root:/home/root:/bin/sh' > passwd echo '/bin/sh' > shells echo 'export PATH=/sbin:/usr/sbin:$PATH' >.profile dropbearkey -t rsa -f dropbear_rsa_host_key 

«Создаем» root пользователя, указываем список системных «шелов», модифицируем переменную PATH и генерируем rsa ключ для dropbear.

cat >nsswitch.conf << 'EOF' passwd:  files shadow:  files group:  files initgroups: files hosts:  files dns bootparams: files ethers:  files netmasks: files networks: files protocols: files rpc:  files services: files automount: files aliases: files EOF 

Указываем откуда брать пользователей и как преобразовывать dns имена.

Скрипт подъема сетевых интерфейсов и запуска dropbear:

cat >remote-ssh.sh << 'EOF' #!/bin/sh /sbin/modprobe e1000 /sbin/ifconfig lo 127.0.0.1/8 /sbin/ifconfig lo up /sbin/ifconfig eth0 192.168.100.203/24 /sbin/ifconfig eth0 up /sbin/route add default gw 192.168.100.1 /bin/mkdir -p /var/log /usr/sbin/dropbear -E -m -p 2222 -a -K 600 > /var/log/lastlog EOF 

После modprobe подставьте подгрузку модуля необходимого для вашей сетевой карты( тот что указывали в скрипте installkernel ), также замените сетевые настройки и имя интерфейса на свои, подразумевается, что ip статистический, если выдача происходит через dhcp — в сркрипт install надо будет добавить установку dhclient и всех необходимых для него библиотек.

Скрипт остановки dropbear:

cat > clean.sh << 'EOF' #!/bin/sh /usr/bin/killall dropbear EOF 

Скрипт разблокировки всех luks томов, требующих ввода пароля:

cat > unlock << 'EOF' if [ -f /etc/crypttab ] ; then sed '/^$/d;/^#/d' /etc/crypttab > /tmp/crypttab n=1 line="`sed -n "$n"p /tmp/crypttab`" while [ -n "$line" ]; do   name="`echo $line|awk '{ print $1 }'`"   dev="`echo $line|awk '{ print $2 }'`"   key="`echo $line|awk '{ print $3 }'`"   if [ "$key" = "none" ]; then     luksname="$name"     if [ "${dev%%=*}" = "UUID" ]; then       device="`blkid -t $dev|cut -d: -f1`"     else       device=$dev     fi     echo "Password [$device ($luksname)]:"      while :;     do       cryptsetup luksOpen $device $luksname && break     done   fi   n=$((n+1))   line="`sed -n "$n"p /tmp/crypttab`" done sed -i /cryptsetup/c\ true /pre-pivot/* [ "$1" = "-noexit" ] && exit 0 killall plymouth killall cryptroot-ask fi exit 0 EOF 

Тут мы сначала создаем «чистый» crypttab без закоментированных и пустых строк, затем в цикле перебираем и расшифровываем все тома для которых нужен пароль. Так как модуль luks от dracut перед сменой корневой фс отключает все неиспользуемые luks тома, то модифицируем срикпты лежащие в /pre-pivot, чтобы этого не происходило. Если скрипту передать параметр -noexit, то процессы препятствующие загрузке не будут убиты и можно будет из initramfs модифицировать основную систему, предварительно смонтировав нужные разделы. Для продолжения загрузки нужно отмонтировать ранее вручную смонтированные разделы и выполнить команду:
killall cryptroot-ask

Разблокировка делается именно так, а не методом предложенным в bugzilla потому, что все остальные luks тома( отличные от root ) будут подключаться только после смены корневой фс, тоисть dropbear у нас еще будет висеть(если убрать хук на его убиение), но ниодной команды в нем уже не выполнить.

В итоге в папке /usr/share/dracut/modules.d/40unlock у вас должны быть следующие файлы:

[root@crypt 40unlock]# ls -al итого 56 drwxr-xr-x.  2 root root 4096 Окт 31 17:36 . drwxr-xr-x. 32 root root 4096 Окт 31 17:35 .. -rwxr-xr-x.  1 root root   17 Окт 31 17:35 check -rwxr-xr-x.  1 root root   36 Окт 31 17:36 clean.sh -rw-------.  1 root root  427 Окт 31 17:36 dropbear_rsa_host_key -rwxr-xr-x.  1 root root 1066 Окт 31 17:35 install -rwxr-xr-x.  1 root root   27 Окт 31 17:36 installkernel -rw-r--r--.  1 root root  222 Окт 31 17:36 nsswitch.conf -rw-r--r--.  1 root root   35 Окт 31 17:36 passwd -rw-r--r--.  1 root root   34 Окт 31 17:36 .profile -rwxr-xr-x.  1 root root  270 Окт 31 17:36 remote-ssh.sh -rw-r--r--.  1 root root    8 Окт 31 17:36 shells -rwxr-xr-x.  1 root root  740 Окт 31 17:36 unlock 

Теперь даем права исполнения для всех скриптов и пересобираем initramfs.

chmod a+x check clean.sh install installkernel remote-ssh.sh unlock dracut -f  

При следующей загрузке можно будет зайти удаленно через ssh и разблокировать все luks тома требующие ручного ввода пароля командой:

unlock 

Минусы:
Это не будет работать если система запущенна в виртуальной мащине и сетевая карта является virtio устройством. Вероятно до запуска udev она не успевает распознаться. Как вариант обхода можно попробовать на хук pre-trigger повесить скрипт- который будет добавлять правила udev, выполняющееся перед правилом luks( а разблокировка происходит именно за счет udev- при нахождении luks тома запускается соответствующая команда) и запускающее скрипт remote-ssh.sh.
Пример:

SUBSYSTEM!="block", GOTO="luks_end" ACTION!="add|change", GOTO="luks_end" ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/bin/remote-ssh.sh" LABEL="luks_end" 

Этот вариант я не тестировал.

Ссылки по теме:

Dracut + encrypted root + networking
Dracut manual

PS: Приведенный код скриптов достаточно просто скопировать в консоль и выполнить- все запишется в соответствующий файл.

ссылка на оригинал статьи http://habrahabr.ru/post/156989/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *