initramfs中的绑定和SSH服务器


每个系统都是安全性和可用性之间的折衷。


在内置的NAS中 ,存在一个严重的问题:没有安装就无法重新启动系统,这降低了数据可用性级别。


直到他们开始关闭紧急电源之时,这个问题才变得至关重要:持续三个月,两次持续数小时。 UPS是为短期故障而设计的,不应在电池上工作超过半小时(尽管实际上是大约一个小时),并且每次关闭电源后,为了重新打开系统,我不得不去另一个城市。


感谢ValdikSS提示 ,此问题已解决。 但是...



我需要接口绑定和远程SSH解锁。 而且我没有找到可以立即完成的手册,以便可以根据需要进行操作。


因此,我带来了带有绑定和动态IP的解决方案版本,可以在本地和远程对系统进行解锁。


我提醒您,要执行这些设置,您必须对NAS具有本地物理访问权限并具有备份启动功能。


在initramfs绑定


由于在NAS中,两个接口合并为一个通道,因此决定在引导时也这样做。


“将NFS根目录与绑定接口一起使用”这一问题中我获取了脚本。 文章“如何在不使用sysfs进行ifenslave的情况下管理linux绑定”帮助建立了绑定。


首先,您需要在用于运行网络的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/


为了提高绑定中的接口,需要第一个:


/ etc / initramfs-tools /脚本/ init-premount / 00_bonding_init
 #!/bin/sh -e PREREQS="" case $1 in prereqs) echo "${PREREQS}"; exit 0;; esac BOND_MASTER=${BOND_MASTER:-bond0} echo "Network interfaces loaded: " echo `ls /sys/class/net` if [ ! -e "/sys/class/net/${BOND_MASTER}" ]; then echo "Creating bonding master 'bond0'..." echo "+${BOND_MASTER}" > /sys/class/net/bonding_masters fi echo "Master interface: ${BOND_MASTER}" 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/${BOND_MASTER}/bonding/slaves" done 

第二个是在继续加载时停用绑定接口:


/ etc / initramfs-tools /脚本/ 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 

仅需设置将包含在绑定中的接口和用于获取地址的参数。
该地址将通过DHCP获得,因为 绑定将具有与启动后相同的MAC,因为路由器将发布固定IP并转发端口。


我在NAS运行时自动从bond0 bond中包含的接口获取接口:


 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上的ping仍将执行。


我注意到在Dracut中设置绑定非常容易,因为交付已经有脚本


initramfs中的SSH服务器


安装软件包以在initramfs中启用Dropbear SSH:


 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 

id_rsa密钥被id_rsa到将执行解锁的计算机上。 我假定它将被复制到~/.ssh/dropbear


/etc/dropbear-initramfs/authorized_keys ,必须指定每个密钥的密钥指纹和参数。


现在,只需添加一个键的指纹,您需要运行以下命令:


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

不需要文章中提到的包装器, /bin/unlock unlock-系统脚本(cryptroot-unlock)。


这是/etc/dropbear-initramfs/authorized_keys最后的样子:


 no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/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): 

在那之后,控制台将不断地收到关于缺少参数的错误( ash: -gt: argument expected ),但是解锁将继续。 这是系统解锁脚本中的错误,不会影响任何错误(该错误很容易纠正,但包装程序无法解决)。


可以在以下文章中找到更多详细信息:



侦错


为了进行调试,您可以在以下00_bonding_init ,在00_bonding_init脚本中插入对/bin/sh00_bonding_init


 case $1 in prereqs) echo "${PREREQS}"; exit 0;; esac 

解决绑定问题后,在authorized_keys中将command="/bin/unlock" command="/bin/sh"替换为command="/bin/sh"


通过SSH连接后,将为您提供可用于调试的shell。

Source: https://habr.com/ru/post/zh-CN419915/


All Articles