Хабрахабр

Bonding и SSH сервер в initramfs

Всякая система является компромиссом между безопасностью и удобством использования.

В построенном NAS, существовала серьёзная проблема: нельзя было перезагрузить систему, не присутствуя на месте, что понижало уровень доступности данных.

ИБП рассчитан на кратковременные сбои и не предполагается работа от батарей более получаса (хотя реально — около часа), и при каждом таком отключении, чтобы снова включить систему, приходилось ездить в другой город. Эта проблема не была критичной, до того момента, как начали аварийно отключать электричество: за три месяца два раза на несколько часов.

Но... Благодаря подсказке от ValdikSS, эту проблема была решена.

А мануала, по которому возможно сделать сразу так, чтобы работало как мне надо, я не нашёл. Мне был нужен бондинг интерфейсов и удалённая разблокировка по SSH.

Поэтому, я привожу свой вариант решения с бондингом и динамическим IP, в котором систему возможно разблокировать, как локально, так и удалённо.

Напоминаю, что для выполнения этих настроек, вы должны иметь локальный физический доступ к NAS и резервные возможности для загрузки.

Поскольку, в NAS два интерфейса объединены в один канал, решено было также сделать и при загрузке.

Статья "How to manage linux bonding without ifenslave using sysfs" помогла в настройке бондинга. Из вопроса "Using NFS-root with bonded interfaces" я взял скрипт.

Делается это следующей командой: Сначала нужно включить в initramfs модули, которые используются для работы сети.

while read m _; do /sbin/modinfo -F filename "$m";
done </proc/modules | sed -nr "s@^/lib/modules/`uname -r`/kernel/drivers/net(/.*)?/([^/]+)\.ko\$@\2@p" >> /etc/initramfs-tools/modules

Теперь скопируйте два скрипта в /etc/initramfs-tools/scripts/.

Первый нужен для того, чтобы поднять интерфейсы в бондинге:

/etc/initramfs-tools/scripts/init-premount/00_bonding_init

#!/bin/sh -e
PREREQS=""
case $1 in prereqs) echo "$"; exit 0;;
esac echo "Network interfaces loaded: "
echo `ls /sys/class/net` for x in $cmdline; do case $x in bondslaves=*) bondslaves="${x#bondslaves=}" ;; esac
done IFS=","
for x in $bondslaves; do echo "+$x" > /sys/class/net/bond0/bonding/slaves
done

Второй, чтобы деактивировать бондинг-интерфейс при продолжении загрузки:

/etc/initramfs-tools/scripts/init-bottom/iface_down

#!/bin/sh -e PREREQS=""
case $1 in prereqs) echo "${PREREQS}"; exit 0;;
esac if [ ! -d /sys/class/net/bond0 ]; then exit 0
fi echo "Remove bonding interface..." for x in $cmdline; do case $x in bondslaves=*) bondslaves="${x#bondslaves=}" ;; esac
done IFS=","
for x in $bondslaves; do echo "-$x" > /sys/class/net/bond0/bonding/slaves
done echo "-bond0" > /sys/class/net/bonding_masters

Если этого не сделать, сеть после загрузки не будет работать.

Не забудьте дать скриптам права на выполнение:

chmod +x /etc/initramfs-tools/scripts/init-premount/00_bonding_init /etc/initramfs-tools/scripts/init-bottom/iface_down

бондинг будет иметь тот же MAC, что и после загрузки, потому роутер выдаст фиксированный IP и осуществит проброс портов. Остаётся только задать интерфейсы, которые войдут в бондинг и параметры получения адреса.
Адрес будет получаться по DHCP, т.к.

Интерфейсы я получаю автоматически из тех, которые входят в бондинг bond0 при работающем NAS:

sed -i "s/\(GRUB_CMDLINE_LINUX_DEFAULT=\)\"\(.*\)\"/\1\"\2 $(echo -n ip=:::::bond0:dhcp bondslaves=$(sed -e 's/ /,/' /sys/class/net/bond0/bonding/slaves))\"/" /etc/default/grub

Ну и напоследок обновите конфиг GRUB и образ initramfs:

update-grub
update-initramfs -u -k $(uname -r)

Если всё настроено корректно, после перезагрузки и запуска стартового скрипта в initrmafs, пинги на IP NAS будут идти, несмотря на то, что ОС ещё не загружена. На этом всё.

Замечу, что настройка бондинга в Dracut делается гораздо легче, потому что уже есть скрипты в поставке.

Установите пакет для включения Dropbear SSH в initramfs:

apt-get install dropbear-initramfs

Dropbear SSH будет включен в initrmafs автоматически, и он запустится, если на раннем этапе загрузки будет поднят хотя бы один сетевой интерфейс с IP адресом.

После этого сконвертируйте ключ Dropbear в формат OpenSSH и закройте его паролем:

/usr/lib/dropbear/dropbearconvert dropbear openssh /etc/dropbear/dropbear_rsa_host_key \ id_rsa dropbearkey -y -f /etc/dropbear/dropbear_rsa_host_key | \ grep "^ssh-rsa " > id_rsa.pub
ssh-keygen -p -f id_rsa

Я буду предполагать, что он будет скопирован в каталог ~/.ssh/dropbear. Ключ id_rsa скопируйте на машину, с которой будет осуществляться разблокировка.

В /etc/dropbear-initramfs/authorized_keys должен быть указаны отпечатки ключа и параметры для каждого ключа.

Пока достаточно добавить отпечаток одного ключа, для чего надо выполнить следующую команду:

echo 'no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/cryptroot-unlock"' $(cat id_rsa.pub) >> /etc/dropbear-initramfs/authorized_keys

Никакие обёртки, упомянутые в статьях не нужны, /bin/cryptroot-unlock — системный скрипт.

Примерно так должен выглядеть /etc/dropbear-initramfs/authorized_keys в конечном итоге:

no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/cryptroot-unlock" ssh-rsa AAAA...XDa root@nas

Обновите конфиг GRUB и образ initramfs и перезагрузитесь:

update-grub
update-initramfs -u -k $(uname -r)
reboot

С машины, куда вы скопировали ключ теперь возможно подключиться к NAS и выполнить разблокировку:

$ ssh -i .ssh/dropbear/id_rsa_initram -o UserKnownHostsFile=.ssh/dropbear/known_hosts root@nas.NAS.cloudns.cc
Enter passphrase for key '.ssh/dropbear/id_rsa_initram':
X11 forwarding request failed on channel 0
Please unlock disk root_crypt1 (/dev/disk/by-id/ata-Samsung_SSD_850_PRO_256GB-part3):

Это ошибка в системном скрипте разблокировки, которая ни на что не влияет (правится ошибка легко, но обёртки её не лечат). После этого в консоль будет постоянно выдаваться ошибка об отсутствии аргумента, но разблокировка пойдёт.

Подробнее возможно посмотреть в этих статьях:

Показать больше

Похожие публикации

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

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

Кнопка «Наверх»