ceremcem / unlock-luks-partition

Unlock a LUKS partition via SSH
40 stars 3 forks source link

Logic is still being executed after successful decryption, displaying unnecessary errors #12

Open ralienpp opened 2 years ago

ralienpp commented 2 years ago

Hi, I followed the documented steps on a Debian 11 and I noticed a cosmetic problem.

After the system was decrypted and the boot process is successful, one sees the authentication prompt. However, as the watchdog is still running, it fails to execute some actions that worked well before, when the / partition was still not decrypted and mounted.

Here's what I mean: image

This happens because the watchdog is invoking check_internet(), which in turn attempts to call ping -c 1 google.com > /dev/null 2>&1.

It seems that after the decryption process takes place, the environment changes, and basic file system resources and commands are not available anymore. For example, if I make changes in the script to run ls - then it will say that this is an unknown command.

In your original script, the || exit part is supposed to take care of that - you either run the command, or terminate the script. But on my system the exit part is never reached, because failure occurs when I attempt to run the first command.

My workaround is to do a printf "\033c" somewhere in link-with-server.sh, which clears the screen and removes the errors, so they don't stress the user. However, that doesn't address the root cause of the problem.

p.s. thank you for sharing this recipe, I found it very useful in my projects. You made it very easy to integrate remote unlocking.

ceremcem commented 2 years ago

Interesting.

However, as the watchdog is still running, it fails to execute some actions that worked well before,

Correct. watchdog (link-with-server.sh) should have exited after successful decryption. Actually the || exit command was a kind of workaround to detect the success status of decryption. If the file system is decrypted, then the basic filesystem resources becomes unavailable (as you mentioned). So, for example, /bin/reboot becomes unreachable and exit command is executed.

Can you please test below script:

#!/bin/sh
set -e

PREREQ="dropbear"

prereqs()
{
     echo "$PREREQ"
}

case $1 in
prereqs)
     prereqs
     exit 0
     ;;
esac

. /scripts/functions

LINK_UP_PORT=1234
LINK_UP_SERVER="example.com"
LINK_UP_SERVER_PORT=22
LINK_UP_USER="myuser"
LOCAL_SSHD_PORT=22  # see README.md#run-dropbear-on-additional-ports

check_internet(){
        ping -V 2>&1 > /dev/null || exit
        if ping -c 1 example.com > /dev/null 2>&1; then
        echo "online"
    else
        echo "offline"
    fi
}

create_link(){
    echo "LINK UP: Waiting for the network config"
    while :; do
                status=$(check_internet) || exit
        if [[ "$status" == "online" ]]; then 
            break
        fi
        sleep 2 || exit
    done
    echo "Creating link with server..."
    /sbin/ifconfig lo up
    dbclient -R ${LINK_UP_PORT}:127.0.0.1:${LOCAL_SSHD_PORT} ${LINK_UP_USER}@${LINK_UP_SERVER} -p ${LINK_UP_SERVER_PORT} -i /root/.ssh/id_rsa -N -f -y -y
}

watchdog(){
    echo "Watchdog started for network config"
    sleep 60

        status=$(check_internet) || exit
    if [[ "$status" == "online" ]]; then
        echo "Internet connection OK: stopping the short watchdog,"
        echo "...setting long watchdog (10 minutes)."
        sleep 600
    else
        echo "No internet connection, rebooting..."
        sleep 3
    fi
    /bin/reboot || exit
}

create_link &
watchdog &

I added set -e, ping -V 2>&1 > /dev/null || exit and status=$(check_internet) || exit to exit before displaying "not found" errors.

Correct approach might be killing whole link-with-server.sh script after successful decryption. This should be added to crypt_unlock.sh (after kill -9 ... line). However, I can't test it right now.

ralienpp commented 2 years ago

Unfortunately, the set -e trick didn't work, though I can see that -e is exactly what is needed, according to the documentation. I still see the "not found" errors.

Another remark, in case someone else is trying to replicate this, the version of ping that comes with busybox in Debian 11.2 does not support -V. I replaced that with a call to uname, since the point here is not to do an actual ping, but to run anything at all and see if it runs.

I'll try the "kill it nicely" approach and write back later.

ralienpp commented 2 years ago

Here's how it worked out for me - terminate the bash process after the OS loads. I did it via a cronjob for the root user:

@reboot  kill -9 `pgrep link-with-ssh-server.sh`

For the benefit of future archaeologists, the root cause is that my set-up is a bit different. I had the "unlock over SSH" functionality working beforehand, and I only relied on your guide to add reverse SSH to the mix, but without taking the logic in crypt_unlock.sh and cleanup.sh with it.

I use an @reboot cronjob to nicely close dbclient, and as of now - to stop the watchdog :-) However, if others follow your guide to the letter, they shouldn't run into the same problem.

So, this was a false alarm. Nevertheless, I greatly appreciate your quick reaction and support.

ceremcem commented 2 years ago

I'm glad to hear that you solved the problem. I also thank you for sharing your results.

I'm going to mark this issue as "enhancement" and keep it open until I find the proper way to remove the || exit workaround.