#! /bin/bash # # Script by Jaco Kroon # to setup an initrd for an encrypted # hard drive. # # You are hereby given rights to reproduce # this script in any way you see fit, # permitting that give credit to the original # author, and provide a link to the original # material, and make any changes available # under similar conditions. set -o errexit boot="${DESTDIR-/boot}" rdname="${RDNAME-cryptrd}" rdsize="${RDSIZE-8}" encdev="${ENCDEV-sda2}" lvmroot="${LVMROOT-lvm-root}" # Takes multiple params, the first # parameter is a description of the # action, the remainder is used as # the command. function action() { echo -n "$1: " shift outp="$("$@" 2>&1)" res=$? [[ $res -eq 0 ]] && echo "Success." && return 0 echo "Failed:" echo "$outp" exit $res } # Create a temporary file which we can # use to construct the initrd in, as well # as a temporary directory where we can # loopback mount the file. # Also make sure things gets cleaned up # properly. rd="$(mktemp /tmp/cryptrd-XXXXXX)" mp="$(mktemp -d /tmp/cryptrd-XXXXXX)" trap "rm -rf '$rd' '$mp'" EXIT # Create the initrd disk image. action "Creating ${rdsize}MB file for loopback" \ dd if=/dev/zero of="$rd" bs=1M count="$rdsize" action "Creating ext2 filesystem" \ mke2fs -F "$rd" action "Mounting loop device" mount -o loop "$rd" "$mp" # Update trap to first umount $mp trap "umount -fl '$mp'; rm -rf '$rd' '$mp'" EXIT # A list of all the required binaries. binaries=( /bin/busybox /sbin/cryptsetup /sbin/lvm ) # busybox can make use of symlinks for # application names - this makes scripts # more readable, and allows us to replace # parts of it with the real tools. bbsyms=( awk bb mkdir mknod mount pivot_root umount ) # Determine the ld-linux.so location. # The path needs to be exact, this is # the only hard-coded so path in most # binaries. ld=$(ldd $SHELL | awk '/ld-linux/ { print $1 }') [[ ! -f "$ld" ]] && \ echo "Unable to determine location of ld-linux.so" && \ exit -1 lib=$(dirname "$ld") action "Creating bin" mkdir "$mp/bin" action "Creating $lib" mkdir "$mp/$lib" action "Creating proc" mkdir "$mp/proc" action "Creating etc" mkdir "$mp/etc" action "Copying ld-linux" cp "$ld" "$mp/$ld" echo "Copying required binaries and their libraries:" for b in "${binaries[@]}"; do action " $b" install --strip "$b" "$mp/bin/" for l in $(ldd "$b" | awk '$2=="=>" && $3 ~ "^/" { print $3 }'); do action " -> $l" install --strip "$l" "$mp/$lib/" done done echo "Creating busybox symlinks:" for bb in "${bbsyms[@]}"; do action " $bb" ln -s busybox "$mp/bin/$bb" done action "Creating /dev" mkdir "$mp/dev" echo "Setting up minimal /dev:" action " console" mknod "$mp/dev/console" c 5 1 action " tty" mknod "$mp/dev/tty" c 5 0 action " null" mknod "$mp/dev/null" c 1 3 action " $encdev" mknod "$mp/dev/$encdev" b $(awk '$NF=="'"$encdev"'" { print $1 " " $2 }' /proc/partitions) echo -n "Creating linuxrc file: " cat > "$mp/linuxrc" < .params echo "${cmdline}" > .cmdline exec chroot . /bin/sh <<- EOF >/dev/console 2>&1 umount initrd rmdir initrd /sbin/blockdev --flushbufs /dev/ram0 exec /sbin/init \${cmdline} EOF LINUXRC echo "Success." action "Fixing permissions on linuxrc" chmod 755 "$mp/linuxrc" echo "Ramdisk usage stats:" df -h $mp | sed -nre 's/[^ ]* +([^ ].*%)[^%]+/\1/p' trap - EXIT action "Unmounting the loop device" umount "$mp" rmdir "$mp" action "Installing the initrd to ${boot}/${rdname}" \ mv "$rd" "${boot}/${rdname}"