Bootscript zum Einbinden von dm-crypt/LUKS-Partitionen unter openSUSE

Aus Linupedia.org
Wechseln zu: Navigation, Suche

Shellscripte

Bootscript zum Einbinden von dm-crypt/LUKS-Partitionen unter openSUSE


Ein Bootscript um mit cryptsetup (inklusive LUKS-Erweiterung) verschlüsselte Partitionen beim Systemstart von openSUSE einzubinden.
Eine ausführliche Beschreibung findet sich hier: Verschlüsselung: dm-crypt/luks unter openSUSE

#!/bin/bash
#
# Author:  b3ll3roph0n <b3ll3roph0n@gmx.net>, 2007
#          based on SuSE10's boot.crypto script by Werner Fink <werner@suse.de>
#
# /etc/init.d/boot.cryptdisks
#
### BEGIN INIT INFO
# Provides:          boot.cryptdisks
# Required-Start:    boot.rootfsck
# Should-Start:      boot.md boot.lvm boot.evms $local_fs boot.klog
# Required-Stop:
# Default-Start:     B
# Default-Stop:
# Description:       Enable LUKS-encrypted file systems before leaving boot phase
### END INIT INFO

. /etc/rc.status

trap "echo" SIGINT SIGSEGV
set +e

# redirect to real device (e.g. in case of boot logging)
: ${CRYPTTAB:=/etc/crypttab}
: ${TIMEOUT:=120}
if test -z "$REDIRECT" ; then
  if (echo -n > /dev/tty) 2>/dev/null ; then
        REDIRECT=/dev/tty;
   else
         REDIRECT=/dev/console;
  fi;
fi;

test -s $CRYPTTAB || exit 0
type -p cryptsetup &> /dev/null || exit 0

splash="";
redirect () {
  if test -e /proc/splash ; then
    read splash  < /proc/splash;
    echo verbose > /proc/splash;
  fi;
  otty=$(stty -g);
  stty $otty < $REDIRECT;
  stty -nl -ixon ignbrk -brkint < $REDIRECT;
  if test -x /etc/init.d/kbd -a -n "$RUNLEVEL" ; then
    /etc/init.d/kbd start < $REDIRECT > $REDIRECT 2>&1;
  fi;
};

restore () {
  stty $otty < $REDIRECT;
  [[ "$splash" =~ silent ]] && echo silent > /proc/splash;
};

ppid=0;
prmt="";
setprompt () {
  if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1
    then
          (
           trap "exit 0" SIGTERM;
           trap "echo" SIGINT SIGSEGV;
           usleep 10000;
           while test $TIMEOUT -gt 0 ; do
         echo -en "\r${prmt}";
         sleep 2;
         : $((TIMEOUT-=2));
           done;
      ) & ppid=$!;
     else
       usleep 10000;
       echo -en "\r${prmt}";
       ppid=0;
  fi;
};

unsetprompt () {
  local ret=$?;
  test $ppid -gt 0 && kill -15 $ppid;
  ppid=0;
  return $ret;
};

rc_reset
main_status=0;

case "$1" in
  start|b)
    redirect;

    # loading modules
    modprobe -q aes;
    modprobe -q dm-crypt;
    rc_status
        test $? -ne 0 && continue;

    echo "Activating crypto devices using $CRYPTTAB ... ";
    while read cryptname physdev mountp filesys crypto copts keyfile ; do

      case "$cryptname" in
            \#*|"") continue ;;
          esac;
            
      rc_status
          if test $? -gt 0 ; then
        main_status=1;
          fi;
      rc_reset
      doskip=0;

      # does the device exit?
      test -b $physdev;
      if test $? -ne 0 ; then
        echo "${extd}${physdev}: No such device${norm}";
        continue;
      fi;

      # does the mount point exit?
      if [ $filesys != "swap" ]; then
        test -d $mountp;
        rc_status
        if test $? -ne 0 ; then
          echo "${extd}${mountp}: No such directory${norm}";
          continue;
            fi;
      fi;

      while true; do

        # restore virgin state
        if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
          cryptsetup luksClose $cryptname &> /dev/null || true
         else
           cryptsetup remove $cryptname &> /dev/null || true
        fi;

        # open encrypted device
        if [ $filesys == "swap" ]; then
          cryptsetup --cipher=$crypto -h $copts --key-file=$keyfile create $cryptname $physdev &>/dev/null;
          break;
         else
           if [ ${keyfile:0:1} = "/" -a -s $keyfile ]; then
             if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
               cryptsetup --key-file=$keyfile luksOpen $physdev $cryptname &>/dev/null;
              else
                cryptsetup --cipher=$crypto --key-file=$keyfile --key-size=$copts create $cryptname $physdev &>/dev/null;
             fi;
            else
                      prmt="${extd}Please enter passphrase for $physdev: ${norm}";
                      setprompt;
              if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
                cryptsetup --timeout=$TIMEOUT luksOpen $physdev $cryptname < $REDIRECT > $REDIRECT 2>&1
               else
                 cryptsetup --timeout=$TIMEOUT --cipher=$crypto --key-size=$copts create $cryptname $physdev < $REDIRECT > $REDIRECT 2>&1
              fi;
                      unsetprompt;
           fi;
           rc_status
           test $? -ne 0 && continue 2;
           # check if we've success
           if mount -t $filesys -n -o ro /dev/mapper/$cryptname $mountp &> /dev/null ; then
             umount -n $mountp &> /dev/null || true
             break
            else
              umount -n $mountp &> /dev/null || true
              echo    "${warn}An error occured.  Maybe the wrong passphrase was";
              echo    "entered or the file system on $physdev is corrupted.${norm}";
              while true ; do
                echo    "${extd}Do you want to retry entering the passphrase or${norm}";
                echo -n "${extd}do you want to continue with a file system check?${norm}";
                read -p " ([${extd}yes${norm}]/${extd}no${norm}/${extd}check${norm}/) " prolo < $REDIRECT
                case "$prolo" in
                  [yY][eE][sS]|[yY]|"")
                    continue 2 ;;
                  [nN][oO]|[nN])
                    doskip=1;
                    break 2 ;;
                  [Cc][hH][eE][Cc][kK]|[Cc])
                    break 2 ;;
                esac;
              done;
           fi;
           break;
        fi;
      done;

      # does the user have skipped this entry?
      if test $doskip -gt 0 ; then
        if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
          cryptsetup luksClose $cryptname &> /dev/null || true
         else
           cryptsetup remove $cryptname &> /dev/null || true
        fi;
        continue;
      fi;

      # check for valid super blocks
      case "$filesys" in
        ext2)     tune2fs -l /dev/mapper/$cryptname &> /dev/null ;;
        reiserfs) debugreiserfs /dev/mapper/$cryptname &> /dev/null ;;
        swap)     mkswap /dev/mapper/$cryptname &> /dev/null ;;
        *)        true ;;
          esac;
      rc_status
          if test $? -gt 0 ; then
        if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
          cryptsetup luksClose $cryptname &> /dev/null || true
         else
           cryptsetup remove $cryptname &> /dev/null || true
        fi;
            continue;
          fi;

      # checking the structure on the loop device
      if [ $filesys != "swap" ]; then
        fsck -a -t $filesys /dev/mapper/$cryptname;
        FSCK_RETURN=$?;
       else
         FSCK_RETURN=0;
      fi;
      test $FSCK_RETURN -lt 2;
      rc_status
      if test $FSCK_RETURN -gt 1; then
        echo "fsck of /dev/mapper/$cryptname failed.  Please repair manually.";
        echo "${warn}Warning: do never try to repair if you have entered the wrong passphrase.${norm}";
        PS1="(repair filesystem) # ";
        /sbin/sulogin $REDIRECT < $REDIRECT > $REDIRECT 2>&1
        sync;
      fi;

      # Mounting device to mount point
      if [ $filesys == "swap" ]; then
        swapon /dev/mapper/$cryptname;
       else
         mount -t $filesys /dev/mapper/$cryptname $mountp;
      fi;
      rc_status

    done < $CRYPTTAB
    test $main_status -gt 0 && rc_failed 1 || true
    rc_status -v1
    restore
  ;;
  stop)
    reverse () {
      local _line
          while read -r _line ; do
        case "$_line" in
          \#*|"") continue ;;
        esac;
        reverse;
        echo "$_line";
        break;
      done;
        };
        echo "Turning off crypto devices using $CRYPTTAB ... "
    while read cryptname physdev mountp filesys crypto copts keyfile ; do

      case "$cryptname" in
        \#*|"") continue ;;
      esac;

      rc_status
      if test $? -gt 0 ; then
        main_status=1;
      fi;
      rc_reset

      # umount device
      if [ $filesys == "swap" ]; then
        swapoff /dev/mapper/$cryptname;
       else
         if [ `cat /proc/mounts | grep /dev/mapper/$cryptname | wc -l` -gt 0 ]; then
           umount /dev/mapper/$cryptname;
         fi;
      fi;
      rc_status

      # close device 
      if [ -e /dev/mapper/$cryptname ]; then
        if $(/sbin/cryptsetup isLuks $physdev 2>/dev/null); then
          cryptsetup luksClose $cryptname &> /dev/null || true
         else
           cryptsetup remove $cryptname &> /dev/null || true
        fi;
        rc_status
      fi;

        done < <(reverse < $CRYPTTAB)
        test $main_status -gt 0 && rc_failed 1 || true
        rc_status -v1
  ;;
  status)
    rc_failed 4
    rc_status -v
  ;;
  restart)
    $0 stop
    $0 start
    rc_status
  ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
  ;;
esac;

rc_exit

# End of file



Zurück zu den Shellscripten
Zurück zu Security