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:


    / etc / initramfs-tools / scripts / init-premount / 00_bonding_init
    #!/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:


    / etc / initramfs-tools / scripts / init-bottom / iface_down
    #!/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 bond0while 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_rsaCopy 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_keysmust 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_keysin 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:



    Debugging


    For debugging, you can insert a call /bin/shinto the script 00_bonding_initafter:


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

    When problems are solved with bonding, replace the authorized_keyscommand command="/bin/unlock"with command="/bin/sh".


    After connecting via SSH, you will be provided with a shell, which you can use for debugging.


    Also popular now: