unlock-boot 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/usr/bin/env bash
  2. # Author: samba
  3. # Date: 2018-02-19
  4. # Desc: unlock the root partition via initrd
  5. PRIVATE_KEY=$HOME/.ssh/id_ed25519
  6. KNOWN_HOSTS_FILE=$HOME/.ssh/boot/known_hosts
  7. KNOWN_HOSTS_TMPFILE=/tmp/unlockboot.known_hosts
  8. LOGFILE=/tmp/unlockboot.log
  9. SSHKEY=0
  10. DEBUG=0
  11. trap ctrl_c INT
  12. usage() {
  13. cat <<EOF
  14. Unlock an encrypted root disk remotely.
  15. Usage: $0
  16. -a|--address Specify the ipaddress of the host to unlock (required)
  17. -p|--password Specify the password to unlock the encrypted disk (required)
  18. -i|--idssh) Specify the ssh private key file (default: $PRIVATE_KEY)
  19. -s|--sshkey Connect via ssh and print the ssh fingerprint (useful to add new trusted hosts)
  20. -k|--known-host Specify the known_hosts file to use when connecting to (default: $KNOWN_HOSTS_FILE)
  21. -d|--debug) Print debug information
  22. -h|--help) Print this help and exit
  23. Example:
  24. $0 -a 192.168.97.2 -p \$(pass sys/vm/MYSERVERNAME/luks)
  25. $0 -a 192.168.97.2 -i $HOME/.ssh/id_rsa -p \$(pass sys/vm/MYSERVERNAME/luks)
  26. $0 -a 192.168.97.2 -i $HOME/.ssh/id_rsa -p \$(pass sys/vm/MYSERVERNAME/luks) -i $HOME/.ssh/id_rsa
  27. EOF
  28. exit 2
  29. }
  30. info(){
  31. TIMESTAMP=$(date '+%F %T')
  32. echo "$TIMESTAMP - INFO: $*" | tee -a $LOGFILE
  33. }
  34. warning(){
  35. TIMESTAMP=$(date '+%F %T')
  36. echo "$TIMESTAMP - WARNING: $*" | tee -a $LOGFILE
  37. }
  38. debug(){
  39. [ $DEBUG -ne 1 ] && return
  40. TIMESTAMP=$(date '+%F %T')
  41. echo "$TIMESTAMP - DEBUG: $*" | tee -a $LOGFILE
  42. }
  43. error(){
  44. TIMESTAMP=$(date '+%F %T')
  45. echo "$TIMESTAMP - ERROR: $*" | tee -a $LOGFILE
  46. exit 1
  47. }
  48. ctrl_c(){
  49. error "Force exit"
  50. }
  51. wait_host_up(){
  52. # Wait until the host is up.
  53. TIMEOUT=300 #seconds = 5m
  54. debug "Waiting for the host to back online, TIMEOUT: $TIMEOUT sec"
  55. COUNT=0
  56. echo " [*] waiting ${TIMEOUT}s for the host respond to ping"
  57. while true ; do
  58. ping -n -w 1 -q -c1 "$IP" >/dev/null 2>&1 && break
  59. [ $[$TIMEOUT % 60] -eq 0 ] && echo -en "\n [*] " || echo -n "."
  60. TIMEOUT=$[$TIMEOUT-1]
  61. [ $TIMEOUT -eq 0 ] && echo -e "\n" && error "host $IP reach timeout ${TIMEOUT}s" && exit 1
  62. done
  63. echo -e "\n [*] host is alive"
  64. }
  65. ssh_getsshkey(){
  66. info "Getting ssh key fingerprint"
  67. info "WARNING: the use of this tool works ONLY when is running dropbear-initramfs"
  68. OUT=$(ssh-keyscan -t ecdsa-sha2-nistp521 $IP)
  69. info "Host ssh key:"
  70. echo
  71. echo "----------- SSH-KEY ---------"
  72. echo "$OUT"
  73. echo "----------- *** *** *** ---------"
  74. echo
  75. echo "To add a TRUSTED HOST you can copy the SSH-KEY and paste it into the script \"$0\" "
  76. exit 0
  77. }
  78. # Add here your SSH pubkey (use -s option)
  79. cat <<EOF > $KNOWN_HOSTS_TMPFILE
  80. antifa.tech ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDUB3sQqMpiuu+5vgsOia4iyOHA30UguQe2HdkWnbmfH0fFx5HbXkHWT5z5N4j8mcblt+WCAyDihl7gGl54X0UE=
  81. EOF
  82. [ $# -eq 0 ] && usage
  83. while [ $# -ne 0 ];do
  84. debug "ARGS: $*"
  85. case ${1} in
  86. -a|--address)
  87. shift
  88. IP=$1
  89. ;;
  90. -i|--idssh)
  91. shift
  92. PRIVATE_KEY=$1
  93. ;;
  94. -k|--known-hosts)
  95. shift
  96. KNOWN_HOSTS_FILE=$1
  97. ;;
  98. -p|--pass)
  99. shift
  100. PASSWORD=$(echo $1| head -n1)
  101. ;;
  102. -d|--debug)
  103. DEBUG=1
  104. ;;
  105. -s|--sshkey)
  106. SSHKEY=1
  107. ;;
  108. *)
  109. usage
  110. ;;
  111. esac
  112. shift
  113. done
  114. # check IP
  115. [ "$IP" == "" ] && error "IP Address not provided (required)"
  116. [ "$SSHKEY" -eq 1 ] && ssh_getsshkey
  117. # check priv key
  118. [ ! -e $PRIVATE_KEY ] && error "ssh private key not found in $PRIVATE_KEY"
  119. [ $(grep -c 'PRIVATE KEY' $PRIVATE_KEY) -eq 0 ] && error "unable to find SSH private key at $PRIVATE_KEY"
  120. # check password is valid
  121. if [ "$PASSWORD" == "" ];then
  122. error "No password provided (password is required)
  123. you did not provide a password provided to unlock the LUKS disk
  124. Please check usage (--help)"
  125. fi
  126. HASHNEW=$(sha1sum $KNOWN_HOSTS_TMPFILE | cut -f 1 -d ' ')
  127. HASHOLD=$(sha1sum $KNOWN_HOSTS_FILE | cut -f 1 -d ' ')
  128. # See if we have a dropbear_known_hosts file.
  129. if [ "$HASHNEW" != "$HASHOLD" ]; then
  130. debug "file differs ${KNOWN_HOSTS_FILE} $KNOWN_HOSTS_TMPFILE"
  131. info "The file ${KNOWN_HOSTS_FILE} has been automatically updated"
  132. #to ensure no-one will steal the LUKS passphrase we need to connect to known_hosts ONLY
  133. [ ! -e $(dirname $KNOWN_HOSTS_FILE) ] && mkdir -p $(dirname $KNOWN_HOSTS_FILE)
  134. debug "copyting $KNOWN_HOSTS_TMPFILE into $KNOWN_HOSTS_FILE"
  135. cp $KNOWN_HOSTS_TMPFILE $KNOWN_HOSTS_FILE
  136. debug "clean $KNOWN_HOSTS_TMPFILE"
  137. rm $KNOWN_HOSTS_TMPFILE
  138. fi
  139. wait_host_up
  140. # unlock boot using PASSWORD
  141. echo " [*] unlocking the boot"
  142. ssh \
  143. -4 \
  144. -o BatchMode=yes \
  145. -o MACs=hmac-sha1 \
  146. -o UserKnownHostsFile=/dev/null \
  147. -o GlobalKnownHostsFile=$KNOWN_HOSTS_FILE \
  148. -o VerifyHostKeyDNS=no \
  149. -i $PRIVATE_KEY \
  150. -F /dev/null \
  151. root@$IP \
  152. "echo -n '$PASSWORD' > /lib/cryptsetup/passfifo" 2>&1 >/dev/null
  153. if [ $? -gt 0 ]; then
  154. error "FAILED to unlock, reason: HOST UNKNOWN"
  155. fi
  156. debug "Host unlocked"
  157. echo " [*] Boot unlock successful, waiting for the machine to complete the boot"
  158. sleep 10s
  159. wait_host_up
  160. debug "host unlocked back online"
  161. echo " [!] Host started successfully! You can now try to connect via ssh to $IP"
  162. exit 0