Bonding and SSH server in initramfs
Every system is a compromise between safety and usability.
In the built NAS , there was a serious problem: it was impossible to reboot the system without being present on site, which lowered the level of data availability.
This problem was not critical, until the moment they started to turn off the electricity in emergency: in three months, two times for several hours. The UPS is designed for short-term failures and does not assume battery operation for more than half an hour (although it is real for about an hour), and with each such shutdown, in order to turn the system back on, you had to travel to another city.
Thanks to a hint from ValdikSS , this problem has been resolved. But...
I needed interface bonding and remote unlocking over SSH. And I couldn’t find the manual, which I can do right away so that I work as I need.
Therefore, I provide my solution with bonding and dynamic IP, in which the system can be unblocked, both locally and remotely.
I remind you that in order to perform these settings, you must have local physical access to the NAS and backup capabilities to boot.
Bonding in initramfs
Since, in the NAS, two interfaces are combined into one channel, it was also decided to do this at boot time.
From the question "Using NFS-root with bonded interfaces" I took the script. The article "How to manage linux bonding without ifenslave using sysfs" helped in setting up a bonding.
First you need to include in the initramfs modules that are used for networking. This is done by the following command:
whileread 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
Now copy the two scripts into /etc/initramfs-tools/scripts/
.
The first is needed in order to raise the interfaces in bonding:
#!/bin/sh -e
PREREQS=""case$1in
prereqs) echo"${PREREQS}"; exit 0;;
esacecho"Network interfaces loaded: "echo `ls /sys/class/net`
for x in$cmdline; docase$xin
bondslaves=*)
bondslaves="${x#bondslaves=}"
;;
esacdone
IFS=","for x in$bondslaves; doecho"+$x" > /sys/class/net/bond0/bonding/slaves
done
The second to deactivate the bonding interface while continuing to download:
#!/bin/sh -e
PREREQS=""case$1in
prereqs) echo"${PREREQS}"; exit 0;;
esacif [ ! -d /sys/class/net/bond0 ]; thenexit 0
fiecho"Remove bonding interface..."for x in$cmdline; docase$xin
bondslaves=*)
bondslaves="${x#bondslaves=}"
;;
esacdone
IFS=","for x in$bondslaves; doecho"-$x" > /sys/class/net/bond0/bonding/slaves
doneecho"-bond0" > /sys/class/net/bonding_masters
If this is not done, the network will not work after booting.
Do not forget to give scripts permissions to execute:
chmod +x /etc/initramfs-tools/scripts/init-premount/00_bonding_init /etc/initramfs-tools/scripts/init-bottom/iface_down
It remains only to specify the interfaces that will be included in the bonding and the parameters for obtaining the address.
The address will be obtained by DHCP, because Bonding will have the same MAC as after the download, because the router will issue a fixed IP and forward ports.
Interfaces I get automatically from those that are bonded bond0
while the NAS is running:
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
And finally, update the GRUB config and the initramfs image:
update-grub
update-initramfs -u -k $(uname -r)
That's all. If everything is configured correctly, after rebooting and launching the startup script in initrmafs, pings on the IP NAS will go, despite the fact that the OS is not yet loaded.
I note that setting up a bonding in Dracut is made much easier, because there are already scripts in the delivery .
SSH server in initramfs
Install the package to enable Dropbear SSH in initramfs:
apt-get install dropbear-initramfs
Dropbear SSH will be enabled automatically in initrmafs, and it will start if at least one network interface with an IP address is picked up early in the boot process.
After that, convert the Dropbear key to the OpenSSH format and close it with a password:
/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
Copy the key to the machine, which will be unlocked. I will assume that it will be copied to the directory ~/.ssh/dropbear
.
B /etc/dropbear-initramfs/authorized_keys
must contain key prints and parameters for each key.
For now, it suffices to add a single-key fingerprint, for which the following command should be executed:
echo'no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/unlock"' $(cat id_rsa.pub) >> /etc/dropbear-initramfs/authorized_keys
No wrappers mentioned in the articles are needed /bin/unlock
- system script (cryptroot-unlock).
Something like this should look like /etc/dropbear-initramfs/authorized_keys
in the end:
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/unlock" ssh-rsa AAAA...XDa root@nas
Update the GRUB config and the initramfs image and reboot:
update-grub
update-initramfs -u -k $(uname -r)
reboot
From the machine where you copied the key it is now possible to connect to the NAS and unlock it:
$ 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):
After that, an error about the absence of an argument ( ash: -gt: argument expected
) will be constantly output to the console , but the unlock will go. This is an error in the system unlock script that does not affect anything (the error is corrected easily, but wrappers do not cure it).
More details can be found in these articles:
- Remote unlocking of LUKS-encrypted root in Ubuntu / Debian .
- Unlocking via SSH fully encrypted ubuntu-server 12.04 .
- Remote unlocking LUKS encrypted LVM using Dropbear SSH in Ubuntu Server 04/04/1 .
- Unlock full-encrypted system via SSH .
Debugging
For debugging, you can insert a call /bin/sh
into the script 00_bonding_init
after:
case$1in
prereqs) echo"${PREREQS}"; exit 0;;
esac
When problems are solved with bonding, replace the authorized_keys
command command="/bin/unlock"
with command="/bin/sh"
.
After connecting via SSH, you will be provided with a shell, which you can use for debugging.