HOWTO: Unlock A LUKS Encrypted Root Partition Via SSH On Ubuntu

Want to support HowtoForge? Become a subscriber!
 
Submitted by sjau (Contact Author) (Forums) on Thu, 2008-06-19 13:26. :: Ubuntu

HOWTO: Unlock A LUKS Encrypted Root Partition Via SSH On Ubuntu

Author: Stephan Jau
Revision: v1.0
Last Change: June 15 2008

Introduction

Fully encrypted systems prevent others from getting your data from physical access. The rationale behind the encryption of a complete system is that you don't have worry about what you encrypt and what not, because everything (except for the /boot) partition will be encrypted.

However the problem I have encountered so far is, how could I reboot my computer from afar? I would be required to be in front of the computer and enter the password. I have wondered this far how I could reboot the computer remotely.

On Debian Administrator I found then an article written by Wulf (Wolfram Coulmann) in which he creates an initrd with dropbear as lightweight ssh server and an unlock script. However that script has still a few bugs and is not suited for Ubuntu. In the comments however, there are a few modifications (especially comment #31 and #29) which will make it also work on ubuntu.

 

The Script

Well, here's the script: dropbear

#!/bin/bash
# We add dropbear to the initrd to be able
# mount crypted partitions from remote
# copyright Wulf Coulmann
# GNU GPL
# http://www.gnu.org/licenses/gpl.html
#
# Download me here: http://gpl.coulmann.de/dropbear
# get infos about this script here:
# http://gpl.coulmann.de/ssh_luks_unlock.html
# Modified by Anonymous 2008
# Modified By Geoffroy RABOUIN 26/05/2008
# Modified by hyper_ch 15/06/2008
### INSTRUCTIONS FOR UBUNTU ###
# 0. Enable root login
# 1. Install killall, busybox and dropbear:
#    ~# sudo apt-get install psmisc busybox dropbear
# 2. Edit network configuration below and copy contents
#    of this file to /etc/initramfs-tools/hooks/dropbear
# 3. Save the script and make it executable:
#    ~# sudo chmod +x /etc/initramfs-tools/hooks/dropbear
# 4. Create new initrd:
#    ~# sudo mkinitramfs -o /boot/netboot
# 5. Edit /boot/grub/menu.lst and add your new initrd as the first entry
# 6. Delete the dropbear script the hooks folder
#    ~# sudo rm /etc/initramfs-tools/hooks/dropbear
# 7. Profit!
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
# Begin real processing below this line
# load the prepared functions of debians initramfs enviroment
source /usr/share/initramfs-tools/hook-functions
# build the directories
DIRS='/lib /bin /usr/bin /usr/sbin/ /proc/ /root/.ssh/ /var/ /var/run/ /etc/dropbear/'
for now in $DIRS ; do
if [ ! -e ${DESTDIR}$now ]
then
mkdir -p ${DESTDIR}$now
fi
done
# copy the ssh-daemon and librarys
copy_exec /usr/sbin/dropbear /usr/sbin/
copy_exec /usr/bin/passwd /usr/bin/
copy_exec /bin/login /bin/
copy_exec /usr/bin/killall /usr/bin/
copy_exec /sbin/route /sbin/
copy_exec /usr/bin/awk /usr/bin/
#copy_exec /usr/bin/strace /usr/bin/
#copy_exec /bin/nc /bin/
copy_exec /usr/bin/wc /usr/bin/
# some librarys are not autoincluded by copy_exec
copy_exec /lib/libnss_compat.so.2 /lib/
copy_exec /usr/lib/libz.so.1 /usr/lib/
copy_exec /etc/ld.so.cache /etc/
copy_exec /lib/libutil.so.1 /lib/
# we copy config and key files
cp -pr /etc/dropbear/dropbear_dss_host_key ${DESTDIR}/etc/dropbear/
cp -pr /etc/dropbear/dropbear_rsa_host_key ${DESTDIR}/etc/dropbear/
cp -pr /etc/passwd ${DESTDIR}/etc/
cp -pr /etc/shadow ${DESTDIR}/etc/
cp -pr /etc/group ${DESTDIR}/etc/
if [ -e /root/.ssh/authorized_keys ]
then
cp -pr /root/.ssh/authorized_keys ${DESTDIR}/root/.ssh/
fi
cp -pr /etc/nsswitch.conf ${DESTDIR}/etc/
cp -pr /etc/localtime ${DESTDIR}/etc/
cp -pr /lib/tls ${DESTDIR}/lib/
# we don't have bash in our initrd
# also we only add the root account
cat /etc/passwd | grep root | sed s/\\/bash/\\/sh/ > ${DESTDIR}/etc/passwd
cat /etc/shadow | grep root > ${DESTDIR}/etc/shadow
cat /etc/group | grep root > ${DESTDIR}/etc/group
cat >${DESTDIR}/scripts/local-top/network_ssh << 'EOF'
#!/bin/sh
# we start the network and ssh-server
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
# Begin real processing below this line
# build up helpful environment
[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir --mode=0700 /root
[ -d /tmp ] || mkdir /tmp
[ -d /sys ] || {
mkdir /sys
mount -t sysfs -o nodev,noexec,nosuid none /sys
}
[ -d /proc ] || {
mkdir /proc
mount -t proc -o nodev,noexec,nosuid none /proc
}
mkdir -p /var/lock
mkdir -p /var/log
touch /var/log/lastlog
mkdir /dev/pts
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
/bin/sleep 5
################# CHANGE THE LINES BELOW #################
# The network setup: edit ip address and gateway to match your needs
ifconfig eth0 172.16.2.128 netmask 255.255.255.0
route add default gw 172.16.2.2
################# CHANGE THE LINES ABOVE #################
# display the network settings for double check
ifconfig
# If you like to use dhcp make sure you include dhclient or pump in
# /etc/initramfs-tools/hooks/dropbear via
# copy_exec /sbin/dhclient
# for debugging ssh-server you may run it in forgound
# /usr/sbin/dropbear -E -F
# for more debugging you may run it with strace
# therfor you have to include strace and nc at top of
# /etc/initramfs-tools/hooks/dropbear via
# copy_exec /usr/bin/strace
# copy_exec /usr/bin/nc
# then start nc on an other host and run
# /usr/sbin/dropbear -E -F 2>&1 | /bin/nc -vv <ip of="" other="" host=""> <nc port="" of="" other="" host="">
# e.g.:
# /usr/sbin/dropbear -E -F 2>&1 | /bin/nc -vv 192.168.1.2 8888
# We will use /dev/urandom because /dev/random gets easily blocked
mv /dev/random /dev/random.old
ln -s /dev/urandom /dev/random
# /usr/sbin/dropbear -E -F -b /etc/dropbear/banner -d /etc/dropbear/dropbear_dss_host_key -r /etc/dropbear/dropbear_rsa_host_key -p 22
/usr/sbin/dropbear -b /etc/dropbear/banner -d /etc/dropbear/dropbear_dss_host_key -r /etc/dropbear/dropbear_rsa_host_key -p 22
#ls -al
rm -f /dev/random
mv /dev/random.old /dev/random
EOF
chmod 700 ${DESTDIR}/scripts/local-top/network_ssh
cat >${DESTDIR}/etc/dropbear/banner << 'EOF'
To unlock root-partition run
unlock
EOF
# script to unlock luks via ssh
# dirty but effektive
cat >${DESTDIR}/usr/bin/unlock << 'EOF'
#!/bin/sh
/bin/sh /scripts/local-top/cryptroot
# Kill processes locking boot process
[ `ls /dev/mapper/ | grep -v control| wc -l | awk '{print $1}'` -gt 0 ] && {
for i in `ps | grep -E "cryptroot|cryptsetup" | awk '{ print $1 }'`
do
kill $i
done
}
/bin/sh /scripts/local-bottom/rm_dropbear
EOF
chmod 700 ${DESTDIR}/usr/bin/unlock
# make sure we exit dropbear at the end of the startup process
cat >${DESTDIR}/scripts/local-bottom/rm_dropbear << 'EOF'
#!/bin/sh
PREREQ=""
prereqs()
{
echo ""
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
# Begin real processing below this line
# we kill dropbear ssh-server
/usr/bin/killall dropbear
EOF
chmod 700 ${DESTDIR}/scripts/local-bottom/rm_dropbear

 

Step 0: Enable root login

First, you have to enable the root account.

sudo passwd root

The reason why I say that root must be enabled is, because I couldn't work out how to get the whole sudo permission stuff into the initrd. I'm sure there must be a way and if someone is willing to take up the challenge, please go ahead. However you can enable root login only during the creation of the initrd. Once it's created then the according stuff is saved in there and you can remove root login from the actual installation again. The root login is only required to log into dropbear and then run the unlock script. It's not used for anything else.

 

Step 1: Install required packages

Install those packages:

sudo apt-get install psmisc busybox dropbear

 

Step 2: Configure network

In the script change the network configuration to your needs. I have sofar only used static ips. The script itself provides also option for dhcp - however I did not try those.

################# CHANGE THE LINES BELOW #################
# The network setup: edit ip address and gateway to match your needs
ifconfig eth0 172.16.2.128 netmask 255.255.255.0
route add default gw 172.16.2.2
################# CHANGE THE LINES ABOVE #################

The above settings are just the values from my vmware machine on where I tested it.

 

Step 3: Save the script and make it executable:

Save the altered script to [I]/etc/initramfs-tools/hooks/dropbear[/I] and make it then executable:

sudo chmod +x /etc/initramfs-tools/hooks/dropbear

 

Step 4: Create new initrd

Run this command to create a new initrd with the name of "netboot". Of course you can rename "netboot" to anything you like.

sudo mkinitramfs -o /boot/netboot

 

Step 5: Edit /boot/grub/menu.lst and add your new initrd as the first entry

Now you have to edit grub's menu list to add the new init.rd.

Run:

sudo nano /boot/grub/menu.lst

to edit the menu.lst in nano.

Go to the end (or almost) and copy an existing kernel entry e.g.

title           Ubuntu 8.04.1, kernel 2.6.24-19-generic
root            (hd0,1)
kernel          /vmlinuz-2.6.24-19-generic root=/dev/mapper/sda4_crypt ro quiet splash
initrd          /initrd.img-2.6.24-19-generic

Change it to something like:

title           Netboot
root            (hd0,1)
kernel          /vmlinuz-2.6.24-19-generic root=/dev/mapper/sda4_crypt ro quiet splash
initrd          /netboot

Don't copy my example directly but use yours. That way the root hd entry and the mapper name are correct.

Finally, at the top of the menu.lst also change the default boot entry accordingly. If you have 7 kernel entries, then you will put a "6" there because it starts with 0 and you add the netboot one at the bottom.

 

Step 6: Delete the dropbear script in the hooks folder

When I tried it on my machine, after a kernel upgrade there were some problems (which may have resulted from my earlier tries with a buggy script). Just to make sure, delete the dropbear script from the folder.

sudo rm /etc/initramfs-tools/hooks/dropbear

 

Step 7: Profit!

That's it... it should be working now.

 

A few things to mention

- Well, in the script I currently call a ifconfig after the network configuration. I did that for bugtracing. You can of course delete that from the script.

- After you have now created the netboot initrd you can either change the root password again or disable root login. As the initrd is not encrypted it is possible to get the hash of the root password and so you want to use a different one from remote unlocking the crypto drives. I highly recommend changing the password or disabling root login in the actual machine.

Change root password

sudo passwd root

or delete the root password (disable root)

sudo passwd -l root

- Although the system is fully encrypted, there are still two possible attacks left to gain access to the data:

  (1) ColdBoot Attack by reading the crypto password from the ram blocks (not much you can't do against that without special hardware, see here)

  (2) The created initrd can be manipulated so that it logs the crypto password somewhere. As /boot is not encrypted an attacker may gain this way the password for the LUKS-devices. You could, to prevent that, make a bootable cd with the according kernels and initrds and implement some kind of hash check... maybe there are other methods... feedback is welcomed here.

- Most of this tutorial is not from me, just a few adapations and explanations. So thanks goes to Wolfram Coulmann and the others who modified the original script.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by titocarni (registered user) on Tue, 2011-08-02 08:44.

I am  observing  problem with the script in the manual with latest ubuntu server (11.04). I am getting to the point that i can successfully login into the dropbear service, but the command unlock is giving me the error that in can not load modprobe.

I have tried to reboot and then enter :

echo -n "Passphrase" > /lib/cryptsetup/passfifo

but this is not returning enything.

Can someone post en example of unlocking the system. Or at least the procedure how it should look like so we can compare what is wrong.

Thanks in advance,

Tito

Submitted by infinity_dev (not registered) on Sat, 2010-11-06 21:11.

Since Ubuntu 10.04 the above script will no longer work. The feature to unlock a root partition via ssh has been integrated into the distribution. If there is a LUKS encrypted root partition, then there will automatically be a dropbear ssh server and a busybox running, and the network is set up using DHCP.

By default, you can connect to the SSH server as root using the private key in the file /etc/initramfs-tools/root/.ssh/id_rsa
The root partition can be unlocked by issuing the command:
echo -n "Passphrase" > /lib/cryptsetup/passfifo
... if there wasn't the new boot screen plymouth that was introduced with 10.04

The following script is a major modification of the above. Like the original, it will allow you to connect via ssh and unlock the filesystem by simply typing unlock. Additionally, you can use private key, password-based authentication or both. Just follow the instructions at the top (tested with Ubuntu 10.10 server, should work with 10.04 as well):

#!/bin/bash # We add dropbear to the initrd to be able # mount crypted partitions from remote # copyright Wulf Coulmann # GNU GPL # http://www.gnu.org/licenses/gpl.html # # Download me here: http://gpl.coulmann.de/dropbear # get infos about this script here: # http://gpl.coulmann.de/ssh_luks_unlock.html # Modified by Anonymous 2008 # Modified By Geoffroy RABOUIN 26/05/2008 # Modified by hyper_ch 15/06/2008 # Modified by infinity_dev 06/10/2010 ### INSTRUCTIONS FOR UBUNTU 10.04 AND ABOVE ### # Prerequisites: cryptsetup and an encrypted root disk # 0. Install dropbear: # ~# sudo apt-get install dropbear # 1. You can access the ssh server by private key and/or password # Private key: Copy the default ssh private key from # /etc/initramfs-tools/root/.ssh/id_rsa to your local computer, e.g.: # ~# scp user@server:/etc/initramfs-tools/root/.ssh/id_rsa ~/ # Or put your own key in /etc/initramfs-tools/root/.ssh/authorized_keys # Note: If you use PuTTY as ssh client, convert the key with PuTTYgen (snapshot) # Password: Alternatively, set a password for user root to allow password-based login # before updating your initrd image in step 5. # 2. Copy contents of this script to /etc/initramfs-tools/hooks/dropbear # 3. Save the script and make it executable: # ~# sudo chmod +x /etc/initramfs-tools/hooks/dropbear # 4. Comment the lines in /usr/share/initramfs-tools/scripts/local-top/cryptroot # like this to prevent the password prompt from going through plymouth: # # if [ -z "$cryptkeyscript" ]; then # cryptkey="Unlocking the disk $cryptsource ($crypttarget)\nEnter passphrase: " # #if [ -x /bin/plymouth ] && plymouth --ping; then # # cryptkeyscript="plymouth ask-for-password --prompt" # # cryptkey=$(echo -e "$cryptkey") # #else # cryptkeyscript="/lib/cryptsetup/askpass" # #fi # fi # 5. Create new default initrd: # ~# sudo update-initramfs -u # Alternatively, you can follow steps 4 and 5 of the original howto if you # don't want to override the initrd installed by Ubuntu. # You might also want to replace the boot parameter `splash` by `noplymouth` # in your /boot/grub/menu.lst boot menu entry # 6. Reboot, connect via SSH and use the `unlock` command PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac # Begin real processing below this line # load the prepared functions of debians initramfs enviroment source /usr/share/initramfs-tools/hook-functions # build the directories if not present DIRS='/lib /bin /usr/bin /usr/sbin/ /proc/ /root/.ssh/ /var/ /var/run/ /etc/dropbear/' for now in $DIRS ; do if [ ! -e ${DESTDIR}$now ] then mkdir -p ${DESTDIR}$now fi done # copy some used tools copy_exec /usr/bin/killall /usr/bin/ copy_exec /usr/bin/awk /usr/bin/ copy_exec /usr/bin/wc /usr/bin/ # copy authentication files cp -pr /etc/passwd ${DESTDIR}/etc/ cp -pr /etc/shadow ${DESTDIR}/etc/ cp -pr /etc/group ${DESTDIR}/etc/ # we don't have bash in our initrd # also we only want the root account cat /etc/passwd | grep root | sed s/\\/bash/\\/sh/ > ${DESTDIR}/etc/passwd cat /etc/shadow | grep root > ${DESTDIR}/etc/shadow cat /etc/group | grep root > ${DESTDIR}/etc/group # Set unlock help as MOTD cat >${DESTDIR}/etc/motd << 'EOF' To unlock root-partition run unlock EOF # script to unlock luks via ssh cat >${DESTDIR}/usr/bin/unlock << 'EOF' #!/bin/sh /lib/cryptsetup/askpass "Enter volume password: " > /lib/cryptsetup/passfifo EOF chmod 700 ${DESTDIR}/usr/bin/unlock # make sure we exit dropbear at the end of the startup process cat >${DESTDIR}/scripts/local-bottom/rm_dropbear << 'EOF' #!/bin/sh PREREQ="" prereqs() { echo "" } case $1 in prereqs) prereqs exit 0 ;; esac # Begin real processing below this line # we kill dropbear ssh-server /usr/bin/killall dropbear EOF chmod 700 ${DESTDIR}/scripts/local-bottom/rm_dropbear
Submitted by infinity_dev (not registered) on Fri, 2010-12-03 02:56.

#!/bin/bash # We add dropbear to the initrd to be able # mount crypted partitions from remote # copyright Wulf Coulmann # GNU GPL # http://www.gnu.org/licenses/gpl.html # # Download me here: http://gpl.coulmann.de/dropbear # get infos about this script here: # http://gpl.coulmann.de/ssh_luks_unlock.html # Modified by Anonymous 2008 # Modified By Geoffroy RABOUIN 26/05/2008 # Modified by hyper_ch 15/06/2008 # Modified by infinity_dev 06/10/2010 ### INSTRUCTIONS FOR UBUNTU 10.04 AND ABOVE ### # Prerequisites: cryptsetup and an encrypted root disk # 0. Install dropbear: # ~# sudo apt-get install dropbear # 1. You can access the ssh server by private key and/or password # Private key: Copy the default ssh private key from # /etc/initramfs-tools/root/.ssh/id_rsa to your local computer, e.g.: # ~# scp user@server:/etc/initramfs-tools/root/.ssh/id_rsa ~/ # Or put your own key in /etc/initramfs-tools/root/.ssh/authorized_keys # Note: If you use PuTTY as ssh client, convert the key with PuTTYgen (snapshot) # Password: Alternatively, set a password for user root to allow password-based login # before updating your initrd image in step 5. # 2. Copy contents of this script to /etc/initramfs-tools/hooks/dropbear # 3. Save the script and make it executable: # ~# sudo chmod +x /etc/initramfs-tools/hooks/dropbear # 4. Comment the lines in /usr/share/initramfs-tools/scripts/local-top/cryptroot # like this to prevent the password prompt to go through plymouth: # # if [ -z "$cryptkeyscript" ]; then # cryptkey="Unlocking the disk $cryptsource ($crypttarget)\nEnter passphrase: " # #if [ -x /bin/plymouth ] && plymouth --ping; then # # cryptkeyscript="plymouth ask-for-password --prompt" # # cryptkey=$(echo -e "$cryptkey") # #else # cryptkeyscript="/lib/cryptsetup/askpass" # #fi # fi # 5. Create new default initrd: # ~# sudo update-initramfs -u # Alternatively, you can follow steps 4 and 5 of the original howto if you # don't want to override the initrd installed by Ubuntu. # You might also want to replace the boot parameter `splash` by `noplymouth` # in your /boot/grub/menu.lst boot menu entry # 6. Reboot, connect via SSH and use the `unlock` command PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac # Begin real processing below this line # load the prepared functions of debians initramfs enviroment source /usr/share/initramfs-tools/hook-functions # build the directories if not present DIRS='/lib /bin /usr/bin /usr/sbin/ /proc/ /root/.ssh/ /var/ /var/run/ /etc/dropbear/' for now in $DIRS ; do if [ ! -e ${DESTDIR}$now ] then mkdir -p ${DESTDIR}$now fi done # copy some files copy_exec /usr/bin/killall /usr/bin/ copy_exec /usr/bin/awk /usr/bin/ copy_exec /usr/bin/wc /usr/bin/ # copy authentication files cp -pr /etc/passwd ${DESTDIR}/etc/ cp -pr /etc/shadow ${DESTDIR}/etc/ cp -pr /etc/group ${DESTDIR}/etc/ # we don't have bash in our initrd # also we only want the root account cat /etc/passwd | grep root | sed s/\\/bash/\\/sh/ > ${DESTDIR}/etc/passwd cat /etc/shadow | grep root > ${DESTDIR}/etc/shadow cat /etc/group | grep root > ${DESTDIR}/etc/group # Set unlock help as MOTD cat >${DESTDIR}/etc/motd << 'EOF' To unlock root-partition run unlock EOF # script to unlock luks via ssh cat >${DESTDIR}/usr/bin/unlock << 'EOF' #!/bin/sh /lib/cryptsetup/askpass "Enter volume password: " > /lib/cryptsetup/passfifo EOF chmod 700 ${DESTDIR}/usr/bin/unlock # make sure we exit dropbear at the end of the startup process cat >${DESTDIR}/scripts/local-bottom/rm_dropbear << 'EOF' #!/bin/sh PREREQ="" prereqs() { echo "" } case $1 in prereqs) prereqs exit 0 ;; esac # Begin real processing below this line # we kill dropbear ssh-server /usr/bin/killall dropbear EOF chmod 700 ${DESTDIR}/scripts/local-bottom/rm_dropbear

Submitted by Martin (not registered) on Sat, 2010-11-13 23:52.

infinity_dev, could you post the modified script in a readable form?
 Thanks, Martin

Submitted by maddes (registered user) on Tue, 2011-02-15 22:15.

I created a stripped-down versions of the script and separted the cryptsetup and dropbear part:


Extra stuff like copying user passwords has been removed, as this exposes valuable data. It is recommend to use public key authentication only.

Maddes

 

Submitted by Maddes (not registered) on Tue, 2011-02-15 20:31.

I created  a stripped down version of his hook script, and splitted the cryptsetup and dropbear part:

  1. hook script "cryptroot_unlock"
  2. local_bottom script "dropbear_kill_clients"

Submitted by zxd (not registered) on Thu, 2010-04-29 11:09.

This is a patch for mkinitrd that will let you ssh with your root account and unlock the box

I threw in some addition tools , like scp, ssh,  rsync, badblocks, shred 

you can remove/add more tools by editing the variable extratools=""  in the script ...

it will auto insert the libs dependency needed for running the tools in the initrd archive

 

 --- /sbin/mkinitrd    2009-09-03 19:58:30.000000000 -0400
+++ ./mkinitrd    2010-04-28 02:27:07.000000000 -0400
@@ -119,7 +119,7 @@
         cmd=error
     fi
 
-    $cmd "usage: `basename $0` [--version] [--help] [-v] [-f] [--preload <module>]"
+    $cmd "usage: `basename $0` [--version] [--help] [-v] [-f] [--preload <module>] [--with-dropbear]"
     $cmd "       [--force-ide-probe] [--force-scsi-probe | --omit-scsi-modules]"
     $cmd "       [--image-version] [--force-raid-probe | --omit-raid-modules]"
     $cmd "       [--with=<module>] [--force-lvm-probe | --omit-lvm-modules]"
@@ -921,6 +921,10 @@
             withfips=1
             ;;
 
+        --with-dropbear)
+            dropbear=1
+            ;;
+
         --with-usb*)
             if [ "$1" != "${1##--with-usb=}" ]; then
                 usbmodule=${1##--with-usb=}
@@ -1024,6 +1028,7 @@
         --net-dev*)
             if [ "$1" != "${1##--net-dev=}" ]; then
                 PREINTERFACES="$PREINTERFACES ${1##--net-dev=}"
+        dropbear_int=1
             else
                 PREINTERFACES="$PREINTERFACES $2"
                 shift
@@ -1133,6 +1138,12 @@
     exit 1
 fi
 
+if [ -n "$dropbear" -a -z "$dropbear_int" ]; then
+    error "Can't enable dropbear without specifying: [--net-dev=<interface>]"
+    exit 1
+fi
+
+
 if [ ! -d /lib/modules/$kernel ]; then
     error 'No modules available for kernel "'${kernel}'".'
     exit 1
@@ -1383,6 +1394,11 @@
     echo $NONL "$@" >> $RCFILE
 }
 
+emitdropbear()
+{
+    echo "$@" >> $MNTIMAGE/bin/unlock
+}
+
 use_multipath=0
 use_emc=0
 use_xdr=0
@@ -1714,6 +1730,7 @@
     set +e
 fi
 
+
 echo -n >| $RCFILE
 cemit << EOF
 #!/bin/nash
@@ -1827,37 +1844,128 @@
     emit "cryptsetup luksOpen $1 $2"
 }
 
+emitcryptodb()
+{
+    emitdropbear "echo Setting up disk encryption: $1"
+    emitdropbear "cryptsetup luksOpen $1 $2"
+}
+
+
 if [ -n "$KEYMAP" -a -n "$LOADKEYS" ]; then
     emit "echo Loading keymap."
     emit "$LOADKEYS $KEYMAP"
 fi
 
-for cryptdev in ${!cryptopart@} ; do
-    emitcrypto `eval echo '$'$cryptdev`
-done
-
-if [ -n "$raiddevices" ]; then
-    for dev in $raiddevices; do
-        cp -a /dev/${dev} $MNTIMAGE/dev
-        emit "raidautorun /dev/${dev}"
-    done
-fi
+cryptoblock()
+{
+   catfun1="$1"
+   catfun2="$2"
+   for cryptdev in ${!cryptopart@} ; do
+       "$catfun2" `eval echo '$'$cryptdev`
+   done
+
+   if [ -n "$raiddevices" ]; then
+       for dev in $raiddevices; do
+           cp -a /dev/${dev} $MNTIMAGE/dev
+           "$catfun1" "raidautorun /dev/${dev}"
+       done
+   fi
+
+   for cryptdev in ${!cryptoraid@} ; do
+      "$catfun2" `eval echo '$'$cryptdev`
+   done
+
+   if [ -n "$vg_list" ]; then
+       "$catfun1" "echo Scanning logical volumes"
+       "$catfun1" "lvm vgscan --ignorelockingfailure"
+       "$catfun1" "echo Activating logical volumes"
+       "$catfun1" "lvm vgchange -ay --ignorelockingfailure $vg_list"
+   fi
+
+   for cryptdev in ${!cryptolv@} ; do
+       "$catfun2" `eval echo '$'$cryptdev`
+   done
+}
 
-for cryptdev in ${!cryptoraid@} ; do
-    emitcrypto `eval echo '$'$cryptdev`
-done
+if [ "$dropbear" = 1 ]; then
+    set -e
+    echo "#!/bin/ash" > $MNTIMAGE/bin/unlock
+    chmod +x $MNTIMAGE/bin/unlock
+    cryptoblock "emitdropbear" "emitcryptodb"
+    dropbearconvert openssh dropbear /etc/ssh/ssh_host_rsa_key /etc/dropbear/dropbear_rsa_host_key 2>/dev/null
+    dropbearconvert openssh dropbear /etc/ssh/ssh_host_dsa_key /etc/dropbear/dropbear_dss_host_key 2>/dev/null
+    mkdir -p $MNTIMAGE/etc/dropbear
+    cat > $MNTIMAGE/etc/dropbear/banner << 'EOF'
+
+     To unlock root-partition run
+        unlock
+       'killall cryptopause' to resume loading the system...
 
-if [ -n "$vg_list" ]; then
-    emit "echo Scanning logical volumes"
-    emit "lvm vgscan --ignorelockingfailure"
-    emit "echo Activating logical volumes"
-    emit "lvm vgchange -ay --ignorelockingfailure $vg_list"
+EOF
+    cat > $MNTIMAGE/bin/cryptopause << 'EOF'
+#!/bin/ash
+echo Type "unlock" and press enter to put in passphrase:
+/bin/ash
+EOF
+    extratools="/usr/bin/shred /sbin/badblocks /usr/bin/rsync /usr/bin/scp /usr/bin/ssh"
+    chmod +x $MNTIMAGE/bin/cryptopause
+    inst /usr/sbin/dropbear $MNTIMAGE/bin/dropbear
+    inst /sbin/busybox $MNTIMAGE/bin/busybox
+    inst /bin/login $MNTIMAGE/bin/login
+    inst /usr/bin/passwd $MNTIMAGE/usr/bin/passwd
+    inst /sbin/rmmod $MNTIMAGE/bin/rmmod
+    inst /etc/dropbear/dropbear_dss_host_key $MNTIMAGE/etc/dropbear/dropbear_dss_host_key
+    inst /etc/dropbear/dropbear_rsa_host_key $MNTIMAGE/etc/dropbear/dropbear_rsa_host_key
+    inst /etc/nsswitch.conf $MNTIMAGE/etc/nsswitch.conf
+    inst /etc/localtime $MNTIMAGE/etc/localtime
+    inst /etc/resolv.conf $MNTIMAGE/etc/resolv.conf
+    inst /etc/host.conf $MNTIMAGE/etc/host.conf
+    inst /etc/hosts $MNTIMAGE/etc/hosts
+    cp -pr /etc/passwd $MNTIMAGE/etc/passwd
+    cp -pr /etc/shadow $MNTIMAGE/etc/shadow
+    cp -pr /etc/group $MNTIMAGE/etc/group
+    grep ^root /etc/passwd | sed s/\\/bash/\\/ash/ > $MNTIMAGE/etc/passwd
+    grep ^root /etc/shadow > $MNTIMAGE/etc/shadow
+    grep ^root /etc/group > $MNTIMAGE/etc/group
+    echo /bin/ash > $MNTIMAGE/etc/shells
+    [ -d /root ] || mkdir --mode=0700 /root
+    [ -f /root/.ssh/authorized_keys ] && inst /root/.ssh/authorized_keys $MNTIMAGE/root/.ssh/authorized_keys
+    for tools in ifconfig route killall ash hostname mv rm; do
+             ln -s /sbin/busybox $MNTIMAGE/sbin/$tools
+    done
+    for tool in $extratools; do
+         inst $tool ${MNTIMAGE}${tool}
+    done
+    for i in $(ldd /usr/sbin/dropbear $extratools| awk '{if (NF==4) print $3; if (NF==2) print $1}') ; do
+    grep -q $i <<<$libs && continue
+    libs="$libs $i"
+    done
+    if echo "$libs" | grep -q lib64; then
+            libdir="lib64"
+    else
+            libdir="lib"
+    fi
+    for i in /${libdir}/{libnss_compat.so.2,libnss_files.so.2,libnss_dns.so.2,libresolv.so.2,libtermcap.so.2,libdl.so.2} ; do
+    grep -q $i <<<$libs && continue
+        libs="$libs $i"    
+    done
+    for lib in $libs; do
+            basename=$(basename $lib)
+            while [ -L $lib ]; do
+                    lib=$(readlink $lib)
+            done
+            inst $lib $MNTIMAGE${lib%/*}/$basename
+    done
+    inst /etc/ld.so.cache $MNTIMAGE/etc/ld.so.cache
+    emit "echo Starting dropbear"
+    emit "/bin/dropbear -b /etc/dropbear/banner"
+    emit "/bin/cryptopause"
+    emit "killall dropbear"
+    set +e
+else
+    cryptoblock "emit" "emitcrypto"
 fi
 
-for cryptdev in ${!cryptolv@} ; do
-    emitcrypto `eval echo '$'$cryptdev`
-done
-
 if [ -z "$noresume" -a -n "$swsuspdev" ]; then
     emit "resume $swsuspdev"
 fi

Submitted by ph4r05 (not registered) on Mon, 2010-06-28 00:56.

Thanks for this great patch, I consider it very usefull for me.

 But during testing one error occured:
Lets have configuration:
 RAID ( LUKS_ENCRYPTED ( LVM ( /, /var, /home )))

Using patched mkinitrd won't boot because raidautorun is started from /bin/unlock script what is obviously wrong, because raidautorun is internal command for nash.

there are two obvious solutions for this:
1. edit script to emit raidautorun statement to /init script ( nash will interpret it ) - my solution


2. use busybox version where is raidautorun compiled in + add symlink to bin under raidautorun - this won't work, raidautodetect called from busybox is unable to detect raid volume. Calling raidautodetect as nash command will detect it. ( dont add any raidautorun to /bin - it will override nash internal command )

sometimes busybox is missing library, it is good idea to browse dependencies for busybox in mkinitrd as it does for other tools

patch for patched mkinitrd from above:

 <code>
--- mkinitrd    2010-06-28 01:51:10.137349671 +0200
+++ mkinitrd_new    2010-06-28 01:52:40.000000000 +0200
@@ -1906,7 +1906,7 @@
    if [ -n "$raiddevices" ]; then
        for dev in $raiddevices; do
            cp -a /dev/${dev} $MNTIMAGE/dev
-           "$catfun1" "raidautorun /dev/${dev}"
+           emit "raidautorun /dev/${dev}"
        done
    fi
 
@@ -1975,7 +1975,7 @@
     for tool in $extratools; do
          inst $tool ${MNTIMAGE}${tool}
     done
-    for i in $(ldd /usr/sbin/dropbear $extratools| awk '{if (NF==4) print $3; if (NF==2) print $1}') ; do
+    for i in $(ldd /usr/sbin/dropbear /sbin/busybox $extratools| awk '{if (NF==4) print $3; if (NF==2) print $1}') ; do
     grep -q $i <<<$libs && continue
     libs="$libs $i"
     done
</code>


Submitted by bastafidli (not registered) on Fri, 2011-01-21 00:19.

This portion of the patch

 <code>
--- mkinitrd    2010-06-28 01:51:10.137349671 +0200
+++ mkinitrd_new    2010-06-28 01:52:40.000000000 +0200

@@ -1975,7 +1975,7 @@
     for tool in $extratools; do
          inst $tool ${MNTIMAGE}${tool}
     done
-    for i in $(ldd /usr/sbin/dropbear $extratools| awk '{if (NF==4) print $3; if (NF==2) print $1}') ; do
+    for i in $(ldd /usr/sbin/dropbear /sbin/busybox $extratools| awk '{if (NF==4) print $3; if (NF==2) print $1}') ; do
     grep -q $i <<<$libs && continue
     libs="$libs $i"
     done
</code>

 fails if busybox is statically build

ldd /usr/sbin/dropbear /sbin/busybox
/usr/sbin/dropbear:

...

/sbin/busybox:
        not a dynamic executable

 This leads to

+ for i in '$(ldd /usr/sbin/dropbear /sbin/busybox $extratools| awk '\''{if (NF==4) print $3; if (NF==2) print $1}'\'')'
+ grep -q dynamic
+ libs=' /lib64/libutil.so.1 /usr/lib64/libz.so.1 /lib64/libcrypt.so.1 /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 dynamic'
 

which results in this error

+ for lib in '$libs'
basename $lib
++ basename dynamic
+ basename=dynamic
+ '[' -L dynamic ']'
+ inst dynamic /tmp/initrd.X15298dynamic/dynamic
+ '[' 2 '!=' 2 ']'
+ vecho 'dynamic -> /tmp/initrd.X15298dynamic/dynamic'
+ NONL=
+ '[' 'dynamic -> /tmp/initrd.X15298dynamic/dynamic' == -n ']'
+ '[' -n '' ']'
dirname $2
++ dirname /tmp/initrd.X15298dynamic/dynamic
+ mkdir -p /tmp/initrd.X15298dynamic
+ cp dynamic /tmp/initrd.X15298dynamic/dynamic
cp: cannot stat `dynamic': No such file or directory
 

and mkinitrd fails. The solution is to do not apply this portion patch if the busybox is statically build or correct it to account for it. Thanks for all the work you guys did!

Submitted by Kenneth Degel (not registered) on Fri, 2009-05-22 21:35.

You need to change the option in /boot/grub/menu.lst to disable the splash screen, otherwise it will not allow you to ssh to the server

kernel /vmlinuz-2.6.24-19-generic root=/dev/mapper/sda4_crypt ro quiet splash

remove the "quiet splash" after the file system, or I changed mine to "ro quiet nosplash vga=790" I assume removing it works too

 That one option cost me about 1 1/2 hours because the system just boots up normal and it seems like you did something wrong, when actually it is working but GDM (I think) has started before the ssh server can so you have to enter in the password locally.

 

 

 


 

Submitted by infinity_dev (not registered) on Mon, 2008-12-22 05:43.
Warning: If you issue the command

sudo passwd -l root

you will not be able run Cron jobs as user root or add new users.
You will see "Authentication failure" messages in your syslog because the root account is marked as expired.

To fix this you have to edit your shadow file manually:

sudo vi /etc/shadow


Change the line similar to:

root:!:13919:0:99999:7::1:

to

root:!:13919:0:99999:7:::

Submitted by Chris (not registered) on Wed, 2010-06-16 18:46.

I'm having issues getting this working on Ubuntu Lucid 10.04 Server. I get to the point where dropbear ssh runs and it asks for a password, but it does not accept it. I've tried my user and root. Can you write up a how to for Lucid Server?

-Chris