📜 ⬆️ ⬇️

Remote unlock of encrypted luks volumes on CentOS6 via ssh

The material below is an adaptation and addition to the method of remote unlocking of volumes proposed by Michael Scherer in bagzilla redhat as applied to CentOS 6 x64. The essence of the method is to modify the initramfs .

Installing additional packages


In initramfs we will add a dropbear ssh server, it is not in the standard repositories, so you need to connect an external - epel:

rpm -Uhv http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm yum -y install dropbear 

')

Modifying initramfs


In CentOS 6, a rather convenient dracut system is used to generate initramfs, an additional module for which we will create. It is a folder in /usr/share/dracut/modules.d with installation scripts and necessary files.
 cd /usr/share/dracut/modules.d mkdir 40unlock cd 40unlock 

The main installation script for the module:
 cat > install << 'EOF' #!/bin/bash cat /etc/shadow|grep root > ${moddir}/shadow dracut_install /lib64/libnss_compat.so.2 dracut_install /lib64/libnss_files.so.2 dracut_install /lib64/libnss_dns.so.2 inst_dir "/etc/dropbear" inst "${moddir}/dropbear_rsa_host_key" "/etc/dropbear/dropbear_rsa_host_key" inst_dir "/home" inst_dir "/home/root" inst_dir "/home/root/.ssh" inst "${moddir}/.profile" "/home/root" [ -s "${moddir}/authorized_keys" ] && inst "${moddir}/authorized_keys" "/home/root/.ssh/authorized_keys" inst "/etc/localtime" inst "${moddir}/nsswitch.conf" "/etc/nsswitch.conf" inst "/etc/resolv.conf" inst "/etc/host.conf" inst "/etc/hosts" inst "${moddir}/shadow" "/etc/shadow" inst "${moddir}/passwd" "/etc/passwd" inst "${moddir}/shells" "/etc/shells" inst "${moddir}/unlock" "/bin/unlock" inst_hook pre-trigger 01 "$moddir/remote-ssh.sh" inst_hook pre-pivot 01 "$moddir/clean.sh" dracut_install sed awk dropbear ifconfig route blkid cut killall true mkdir dracut_install -o ps find grep less cat tac head tail false rmdir rm touch vi ping ssh scp lsmod EOF 

It takes the encrypted root password from the shadow, to enable remote login using a password, if you need authorization by key, then put the authorized_keys file with the public key inside and 600 access rights in the same folder. Also, all necessary configuration files, commands and dynamic settings are installed. libraries. Files hosts, resolv.conf and host.conf are taken system. Two hooks are put: the first (remote-ssh.sh) starts dropbear before the password is requested and the second (clean.sh) kills the dropbear process before changing the root fs. The "dracut_install -o" contains optional commands that can be installed in the initramfs if present on the main system.

Script "check":
 cat > check << 'EOF' #!/bin/sh exit 0 EOF 

If you do not want this module to be used by dracut by default, then change the exit code to 255, and when updating the kernel, the new initramfs will include this module.

The script for installing kernel modules:
 cat > installkernel << 'EOF' #!/bin/bash instmods e1000 EOF 

Include the necessary kernel modules in initramfs, in this case to support the intel e1000 network card, with your own (you can see it with the lspci -k command).

Now we will create all the necessary configuration files and our scripts.

 echo 'root:x:0:0:root:/home/root:/bin/sh' > passwd echo '/bin/sh' > shells echo 'export PATH=/sbin:/usr/sbin:$PATH' >.profile dropbearkey -t rsa -f dropbear_rsa_host_key 

“Create” the root user, specify the list of system shells, modify the PATH variable, and generate the rsa key for dropbear.

 cat >nsswitch.conf << 'EOF' passwd: files shadow: files group: files initgroups: files hosts: files dns bootparams: files ethers: files netmasks: files networks: files protocols: files rpc: files services: files automount: files aliases: files EOF 

Specify where to get users and how to convert dns names.

Script of rise of network interfaces and start of dropbear:
 cat >remote-ssh.sh << 'EOF' #!/bin/sh /sbin/modprobe e1000 /sbin/ifconfig lo 127.0.0.1/8 /sbin/ifconfig lo up /sbin/ifconfig eth0 192.168.100.203/24 /sbin/ifconfig eth0 up /sbin/route add default gw 192.168.100.1 /bin/mkdir -p /var/log /usr/sbin/dropbear -E -m -p 2222 -a -K 600 > /var/log/lastlog EOF 

After modprobe, substitute the module load required for your network card (the one specified in the installkernel script), also replace the network settings and the interface name with your own, it is assumed that the ip is statistical, if output occurs via dhcp - install the dhclient and all necessary libraries for it.

Dropbear stop script:
 cat > clean.sh << 'EOF' #!/bin/sh /usr/bin/killall dropbear EOF 


Script unlock all luks volumes that require a password:
 cat > unlock << 'EOF' if [ -f /etc/crypttab ] ; then sed '/^$/d;/^#/d' /etc/crypttab > /tmp/crypttab n=1 line="`sed -n "$n"p /tmp/crypttab`" while [ -n "$line" ]; do name="`echo $line|awk '{ print $1 }'`" dev="`echo $line|awk '{ print $2 }'`" key="`echo $line|awk '{ print $3 }'`" if [ "$key" = "none" ]; then luksname="$name" if [ "${dev%%=*}" = "UUID" ]; then device="`blkid -t $dev|cut -d: -f1`" else device=$dev fi echo "Password [$device ($luksname)]:" while :; do cryptsetup luksOpen $device $luksname && break done fi n=$((n+1)) line="`sed -n "$n"p /tmp/crypttab`" done sed -i /cryptsetup/c\ true /pre-pivot/* [ "$1" = "-noexit" ] && exit 0 killall plymouth killall cryptroot-ask fi exit 0 EOF 

Here we first create a “clean” crypttab without zakommentirovannyh and empty lines, then loop through and decrypt all volumes for which you need a password. Since the luks module from dracut removes all unused luks volumes before changing the root fs, we modify the scripts in / pre-pivot to prevent this from happening. If the -noexit parameter is -noexit to the -noexit , then the processes preventing the loading will not be killed and it will be possible to modify the primary system from initramfs by pre-mounting the necessary partitions. To continue the download, you need to unmount previously manually mounted partitions and execute the command:
killall cryptroot-ask

Unlocking is done this way, and not by the method proposed in bugzilla because all the other luks of the volume (other than root) will be connected only after changing the root fs, then the dropbear will still hang (if you remove the hook for its killing), but no command it is no longer complete.

As a result, you should have the following files in the /usr/share/dracut/modules.d/40unlock folder:
 [root@crypt 40unlock]# ls -al  56 drwxr-xr-x. 2 root root 4096  31 17:36 . drwxr-xr-x. 32 root root 4096  31 17:35 .. -rwxr-xr-x. 1 root root 17  31 17:35 check -rwxr-xr-x. 1 root root 36  31 17:36 clean.sh -rw-------. 1 root root 427  31 17:36 dropbear_rsa_host_key -rwxr-xr-x. 1 root root 1066  31 17:35 install -rwxr-xr-x. 1 root root 27  31 17:36 installkernel -rw-r--r--. 1 root root 222  31 17:36 nsswitch.conf -rw-r--r--. 1 root root 35  31 17:36 passwd -rw-r--r--. 1 root root 34  31 17:36 .profile -rwxr-xr-x. 1 root root 270  31 17:36 remote-ssh.sh -rw-r--r--. 1 root root 8  31 17:36 shells -rwxr-xr-x. 1 root root 740  31 17:36 unlock 

Now we give the execution rights for all scripts and reassemble the initramfs.
 chmod a+x check clean.sh install installkernel remote-ssh.sh unlock dracut -f 

With the next boot, you can log in remotely via ssh and unlock all luks volumes requiring manual password entry with the command:
 unlock 


Minuses:
This will not work if the system is running in a virtual interface and the network card is a virtio device. Probably before the launch of udev, it does not have time to be recognized. As a crawl option, you can try a pre-trigger hook to hang a script that will add udev rules that run before the luks rule (and unlocking is done by udev; when the luks volume is found, the corresponding command is run) and the remote-ssh.sh script that runs it.
Example:
 SUBSYSTEM!="block", GOTO="luks_end" ACTION!="add|change", GOTO="luks_end" ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/bin/remote-ssh.sh" LABEL="luks_end" 

I did not test this option.

Related Links:


Dracut + encrypted root + networking
Dracut manual

PS: The above script code is simply copied to the console and executed; everything will be written into the corresponding file.

Source: https://habr.com/ru/post/156989/


All Articles