Utility for unattended remote unlock of LUKS encrypted LVM/root disk partition using SSH and cryptsetup.
Periodically polls defined servers for open SSH port, then tries to unlock the server using cryptsetup.
Requires dropbear
or any other SSH server which could be run from initial ramdisk.
This utility should run from independent server (possibly VPS), thus separating all passphrases and SSH
keys from the servers being unlocked. Server authentication is performed during the connection process
against a known_hosts
file.
Server will be unlocked only when SSH is available on the specified IP address and port and if
the fingerprint in the known_hosts
file matches. You should always use IP addresses in the
host configuration rather than domain names to limit the attack possibility after
compromising a DNS server.
Please also note that the server host keys are always stored on an unencrypted partition, so this script won't protect you against an attack with both physical access to the server and the IP address used for unlocking. To further limit the attack possibility, you should use monitoring and possibly disable SSH unlocker in the case of unexpected behavior.
Other possible security implications and solutions how to prevent them are beyond the scope of this documentation.
Python 3.5 and higher is required for the installation, because the async/await syntax is used.
$ pip install ssh-unlocker
You should be able to run the utility by using ssh-unlocker
. Run ssh-unlocker -h
for the list of available options.
$ ssh-unlocker -h
usage: ssh-unlocker [-h] [-c CONFIG] [-v] [--logfile LOGFILE]
Cryptsetup SSH server unlocker. This utility is repeatedly polling configured
servers and tries to unlock the encrypted root partition using cryptsetup once
the SSH connection is available.
optional arguments:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Path to config file - defaults to config.ini
-v, --verbose Increase verbosity level to DEBUG
--logfile LOGFILE Path to log file. By default the log messages are
printed to stderr
By default the configuration is read from config.ini
configuration file, but this can be specified as a parameter.
Server configuration should be specified using respective [server-identifier]
sections.
Unspecified parameters are inherited from the [DEFAULT]
section.
host
– SSH server domain or IP addressport
– SSH server port. It's recommended to run the dropbear SSH daemon for unlocking on a port that is closed on a running (unlocked) server. This way the connection will be closed before attempting SSH authentication and you'll avoid spamming logs.username
– username of a remote userssh_private_key
– private SSH key used for authentication (password authentication is not supported for security reasons and should be avoided)ssh_private_key_passphrase
– passphrase for encrypted SSH private key (unused when blank)cryptsetup_passphrase
– passphrase for unlocking encrypted disk using cryptsetup
known_hosts
– file with DSA host keys of SSH servers (used for server authentication and MITM attack prevention). This file cannot be empty - you should always provide server keys beforehand for security reasonsconnect_timeout
– connection timeout for TCP handshake during port scanningssh_connect_timeout
– timeout for connection and SSH authsleep_interval
– time between port scanning checks
Example configuration file:
; [server-identifier]
; host = 127.0.0.1
; port = 22
; username = default
; cryptsetup_passphrase = securePassword13!
[DEFAULT]
connect_timeout = 5
ssh_connect_timeout = 5
sleep_interval = 2
port = 22
username = root
ssh_private_key = unlock_key.rsa
ssh_private_key_passphrase =
known_hosts = known_hosts
In most scenarios ssh-unlocker should probably start automatically at system startup. You should also make sure, that the unlocker would be restarted in case of any unexpected exceptions. This can be done by a simple shell script or you can use one of more sophisticated solutions described below.
Systemd is already pre-installed in most modern distribution, so using it should be only a matter of adding new configuration file.
Example configuration:
[Unit]
Description=Utility for unattended remote unlock of LUKS encrypted LVM
After=network.target
[Service]
ExecStart=/root/ssh-unlocker/venv/bin/ssh-unlocker
WorkingDirectory=/root/ssh-unlocker/
Restart=always
TimeoutStopSec=60
# try to restart the service indefinitely (RestartSec * StartLimitBurst > StartLimitIntervalSec)
RestartSec=1
StartLimitBurst=20
StartLimitIntervalSec=1
[Install]
WantedBy=multi-user.target
If you're used to Supervisor or you don't want to use Systemd for some reason, here is a sample configuration file:
[program:cryptsetup-ssh-unlocker]
command=/root/ssh-unlocker/venv/bin/ssh-unlocker --logfile /var/log/ssh-unlocker
directory=/root/ssh-unlocker/
autostart=true
autorestart=true
startsecs=5
stopwaitsecs=60
In order for this utility to work correctly, SSH daemon has to be installed into initial ramdisk. There are some tutorials, how to do that, such as this one for Ubuntu.
$ apt update
$ apt install dropbear
Edit /etc/initramfs-tools/initramfs.conf
and add or replace the following configuration:
DEVICE=eth0
IP=192.168.1.100::192.168.1.1:255.255.255.0::eth0:off
DROPBEAR_OPTIONS="-p 1022"
The format for IP
is the following: [host ip]::[gateway ip]:[netmask]:[hostname]::[device]:[autoconf]
(please notice double colons ::
). SSH port is specified using DROPBEAR_OPTIONS
. I strongly recommend using another port than 22
.
Update /etc/default/dropbear
and
change NO_START=1
to NO_START=0
# disabled because OpenSSH is installed
# change to NO_START=0 to enable Dropbear
NO_START=0
DROPBEAR_PORT
in the same configuration file is ignored in initial ramdisk phase and has to be specified in initramfs.conf
.
Add all public keys you would like to use for authentication during the unlock phase to /etc/initramfs-tools/root/.ssh/authorized_keys
.
Create the file and/or folder(s) if they don't exist already.
Don't forget to add public key of the RSA key that will be used by this utility.
You can easily generate new RSA keypair by running ssh-keygen -t rsa -b 4096
.
$ dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
$ dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key
$ sudo update-initramfs -u
This software is licensed under MIT license.