Установка дополнительных пакетов
В 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/
Добавить комментарий