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 present 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.
Since, in 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 modules in initramfs, which are used for network operation. This is done by the following command:
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
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 $1 in prereqs) echo "${PREREQS}"; 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
Second, to deactivate the bonding interface while continuing to download:
#!/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
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 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 join 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 bonding in Dracut is made much easier, because there are already scripts in the delivery .
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
key to the machine with which the unlock will be performed. I will assume that it will be copied to the ~/.ssh/dropbear
.
The /etc/dropbear-initramfs/authorized_keys
key fingerprints and parameters for each key must be specified.
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
is a 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, the console will constantly receive an error about the absence of an argument ( ash: -gt: argument expected
), but the unlock will go. This is an error in the system unlock script, which does not affect anything (the error is corrected easily, but wrappers do not cure it).
More details can be found in these articles:
For debugging, you can insert the /bin/sh
call into the 00_bonding_init
script after:
case $1 in prereqs) echo "${PREREQS}"; exit 0;; esac
When the problems with bonding are resolved, 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.
Source: https://habr.com/ru/post/419915/