diff --git a/README.rst b/README.rst index a4f6b08..f56db8f 100644 --- a/README.rst +++ b/README.rst @@ -73,6 +73,7 @@ similar to those passed via commandline. Consider following example: ip = '192.168.0.1' gateway = '192.168.0.254' netmask = '24' + user = 'gryf' authorized_keys = "/full/path/to/the/.ssh/authorized_keys" This will inform mkinitramfs script, that dropbear and yubikey features are @@ -88,6 +89,7 @@ The complete list of supported options is listed below: - ``sdcard`` - ``yubikey`` - ``dropbear`` +- ``user`` Using key devices ----------------- @@ -104,7 +106,34 @@ There is possibility for using key which is encrypted using response from challenge response using `ykchalresp`_ command. The challenge here could be any string, so the name of the device from config is used. +Dropbear +-------- + +To unlock LUKS root filesystem remotely `dropbear`_ is used. There are expected +configuration options in ``mkinitramfs.toml`` file: + +- ``dropbear`` - true or false, false by default +- ``iface`` interface name - ``eth0`` by default +- ``ip`` - static IP address +- ``netmask`` - netmask for the network +- ``gateway`` - gateway for the network +- ``user`` - username used for logging in, ``root`` by default. Note, whatever + username will be placed here, it will be ``root`` effectively anyway +- ``authorized_keys`` - path to ssh ``authorized_keys`` file. If there is no + user set - which mens root username is used, by default it will look for the + ``/root/.ssh/authorized_keys`` + +You'll need to put at least ``ip``, ``netmask``, ``gateway`` to make this work +with defaults, with assumption that interface is ``eth0`` and ``root`` user +have needed ``authorized_keys`` file. + +Then execute script with flag ``-b`` which include dropbear part.: + +.. code:: shell-session + + # mkinitramfs.py -b laptop .. _ccrypt: https://sourceforge.net/projects/ccrypt/ .. _cryptsetup: https://gitlab.com/cryptsetup/cryptsetup/blob/master/README.md .. _ykchalresp: https://github.com/Yubico/yubikey-personalization +.. _dropbear: https://matt.ucc.asn.au/dropbear/dropbear.html diff --git a/mkinitramfs.py b/mkinitramfs.py index 853a2bd..8a74759 100755 --- a/mkinitramfs.py +++ b/mkinitramfs.py @@ -272,7 +272,7 @@ if [ ! -b /dev/mapper/root ]; then done fi if [ ! -b /dev/mapper/root ]; then - echo "Failed to open encrypted device. Reboot in 5 seconds." + echo "Failed to open encrypted device. Rebooting in 5 seconds." reboot -f -d 5 fi """ @@ -336,6 +336,14 @@ class Config: self.ip = toml_.get('ip') self.gateway = toml_.get('gateway') self.netmask = toml_.get('netmask') + self.iface = toml_.get('iface', 'eth0') + self.user = toml_.get('user', 'root') + if self.user != 'root' and not toml_.get('authorized_keys'): + sys.stderr.write(f'User {self.user} is not authorized for ' + f'utilizing root .ssh/authorized_keys file. ' + f'Set authorized_keys file path in' + f' configuration.') + sys.exit(7) self.authorized_keys = toml_.get('authorized_keys', ROOT_AK) @@ -412,6 +420,8 @@ class Initramfs(object): if (self.conf.authorized_keys and os.path.exists(self.conf.authorized_keys)): shutil.copy(self.conf.authorized_keys, 'root/.ssh') + else: + sys.stderr.write(f'Warning {self.conf.authorized_keys} not found!') # Copy OpenSSH's host keys to keep both initramfs' and regular ssh # signed the same otherwise openssh clients will see different host @@ -424,11 +434,11 @@ class Initramfs(object): # Basic system defaults with open('etc/passwd', 'w') as fobj: - fobj.write("root:x:0:0:root:/root:/bin/sh\n") + fobj.write(f"{self.conf.user}:x:0:0:root:/root:/bin/sh\n") with open('etc/shadow', 'w') as fobj: - fobj.write("root:*:::::::\n") + fobj.write(f"{self.conf.user}:*:::::::\n") with open('etc/group', 'w') as fobj: - fobj.write("root:x:0:root\n") + fobj.write(f"{self.conf.user}:x:0:{self.conf.user}\n") with open('etc/shells', 'w') as fobj: fobj.write("/bin/sh\n") os.chmod('etc/shadow', 0b110100000) @@ -469,9 +479,7 @@ class Initramfs(object): os.symlink('busybox', command) def _copy_key(self, suffix=''): - key_path = self.conf.key_path - if not os.path.exists(key_path): - key_path = os.path.join(self.conf.key_path + suffix) + key_path = self.conf.key_path + suffix if not os.path.exists(key_path): self._cleanup()