123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #!/usr/bin/env bash
- # Author: samba
- # Date: 2018-02-19
- # Desc: unlock the root partition via initrd
- PRIVATE_KEY=$HOME/.ssh/id_ed25519
- KNOWN_HOSTS_FILE=$HOME/.ssh/boot/known_hosts
- KNOWN_HOSTS_TMPFILE=/tmp/unlockboot.known_hosts
- LOGFILE=/tmp/unlockboot.log
- SSHKEY=0
- DEBUG=0
- trap ctrl_c INT
- usage() {
- cat <<EOF
- Unlock an encrypted root disk remotely.
- Usage: $0
- -a|--address Specify the ipaddress of the host to unlock (required)
- -p|--password Specify the password to unlock the encrypted disk (required)
- -i|--idssh) Specify the ssh private key file (default: $PRIVATE_KEY)
- -s|--sshkey Connect via ssh and print the ssh fingerprint (useful to add new trusted hosts)
- -k|--known-host Specify the known_hosts file to use when connecting to (default: $KNOWN_HOSTS_FILE)
- -d|--debug) Print debug information
- -h|--help) Print this help and exit
- Example:
- $0 -a 192.168.97.2 -p \$(pass sys/vm/MYSERVERNAME/luks)
- $0 -a 192.168.97.2 -i $HOME/.ssh/id_rsa -p \$(pass sys/vm/MYSERVERNAME/luks)
- $0 -a 192.168.97.2 -i $HOME/.ssh/id_rsa -p \$(pass sys/vm/MYSERVERNAME/luks) -i $HOME/.ssh/id_rsa
- EOF
- exit 2
- }
- info(){
- TIMESTAMP=$(date '+%F %T')
- echo "$TIMESTAMP - INFO: $*" | tee -a $LOGFILE
- }
- warning(){
- TIMESTAMP=$(date '+%F %T')
- echo "$TIMESTAMP - WARNING: $*" | tee -a $LOGFILE
- }
- debug(){
- [ $DEBUG -ne 1 ] && return
- TIMESTAMP=$(date '+%F %T')
- echo "$TIMESTAMP - DEBUG: $*" | tee -a $LOGFILE
- }
- error(){
- TIMESTAMP=$(date '+%F %T')
- echo "$TIMESTAMP - ERROR: $*" | tee -a $LOGFILE
- exit 1
- }
- ctrl_c(){
- error "Force exit"
- }
- wait_host_up(){
- # Wait until the host is up.
- TIMEOUT=300 #seconds = 5m
- debug "Waiting for the host to back online, TIMEOUT: $TIMEOUT sec"
- COUNT=0
- echo " [*] waiting ${TIMEOUT}s for the host respond to ping"
- while true ; do
- ping -n -w 1 -q -c1 "$IP" >/dev/null 2>&1 && break
- [ $[$TIMEOUT % 60] -eq 0 ] && echo -en "\n [*] " || echo -n "."
- TIMEOUT=$[$TIMEOUT-1]
- [ $TIMEOUT -eq 0 ] && echo -e "\n" && error "host $IP reach timeout ${TIMEOUT}s" && exit 1
- done
- echo -e "\n [*] host is alive"
- }
- ssh_getsshkey(){
- info "Getting ssh key fingerprint"
- info "WARNING: the use of this tool works ONLY when is running dropbear-initramfs"
- OUT=$(ssh-keyscan -t ecdsa-sha2-nistp521 $IP)
- info "Host ssh key:"
- echo
- echo "----------- SSH-KEY ---------"
- echo "$OUT"
- echo "----------- *** *** *** ---------"
- echo
- echo "To add a TRUSTED HOST you can copy the SSH-KEY and paste it into the script \"$0\" "
- exit 0
- }
- # Add here your SSH pubkey (use -s option)
- cat <<EOF > $KNOWN_HOSTS_TMPFILE
- antifa.tech ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDUB3sQqMpiuu+5vgsOia4iyOHA30UguQe2HdkWnbmfH0fFx5HbXkHWT5z5N4j8mcblt+WCAyDihl7gGl54X0UE=
- EOF
- [ $# -eq 0 ] && usage
- while [ $# -ne 0 ];do
- debug "ARGS: $*"
- case ${1} in
- -a|--address)
- shift
- IP=$1
- ;;
- -i|--idssh)
- shift
- PRIVATE_KEY=$1
- ;;
- -k|--known-hosts)
- shift
- KNOWN_HOSTS_FILE=$1
- ;;
- -p|--pass)
- shift
- PASSWORD=$(echo $1| head -n1)
- ;;
- -d|--debug)
- DEBUG=1
- ;;
- -s|--sshkey)
- SSHKEY=1
- ;;
- *)
- usage
- ;;
- esac
- shift
- done
- # check IP
- [ "$IP" == "" ] && error "IP Address not provided (required)"
- [ "$SSHKEY" -eq 1 ] && ssh_getsshkey
- # check priv key
- [ ! -e $PRIVATE_KEY ] && error "ssh private key not found in $PRIVATE_KEY"
- [ $(grep -c 'PRIVATE KEY' $PRIVATE_KEY) -eq 0 ] && error "unable to find SSH private key at $PRIVATE_KEY"
- # check password is valid
- if [ "$PASSWORD" == "" ];then
- error "No password provided (password is required)
- you did not provide a password provided to unlock the LUKS disk
- Please check usage (--help)"
- fi
- HASHNEW=$(sha1sum $KNOWN_HOSTS_TMPFILE | cut -f 1 -d ' ')
- HASHOLD=$(sha1sum $KNOWN_HOSTS_FILE | cut -f 1 -d ' ')
- # See if we have a dropbear_known_hosts file.
- if [ "$HASHNEW" != "$HASHOLD" ]; then
- debug "file differs ${KNOWN_HOSTS_FILE} $KNOWN_HOSTS_TMPFILE"
- info "The file ${KNOWN_HOSTS_FILE} has been automatically updated"
- #to ensure no-one will steal the LUKS passphrase we need to connect to known_hosts ONLY
- [ ! -e $(dirname $KNOWN_HOSTS_FILE) ] && mkdir -p $(dirname $KNOWN_HOSTS_FILE)
- debug "copyting $KNOWN_HOSTS_TMPFILE into $KNOWN_HOSTS_FILE"
- cp $KNOWN_HOSTS_TMPFILE $KNOWN_HOSTS_FILE
- debug "clean $KNOWN_HOSTS_TMPFILE"
- rm $KNOWN_HOSTS_TMPFILE
- fi
- wait_host_up
- # unlock boot using PASSWORD
- echo " [*] unlocking the boot"
- ssh \
- -4 \
- -o BatchMode=yes \
- -o MACs=hmac-sha1 \
- -o UserKnownHostsFile=/dev/null \
- -o GlobalKnownHostsFile=$KNOWN_HOSTS_FILE \
- -o VerifyHostKeyDNS=no \
- -i $PRIVATE_KEY \
- -F /dev/null \
- root@$IP \
- "echo -n '$PASSWORD' > /lib/cryptsetup/passfifo" 2>&1 >/dev/null
- if [ $? -gt 0 ]; then
- error "FAILED to unlock, reason: HOST UNKNOWN"
- fi
- debug "Host unlocked"
- echo " [*] Boot unlock successful, waiting for the machine to complete the boot"
- sleep 10s
- wait_host_up
- debug "host unlocked back online"
- echo " [!] Host started successfully! You can now try to connect via ssh to $IP"
- exit 0
|