Monday, December 24, 2012

CentOS6 Disk encryption with remote password entering


Disk Encryption in CentOS6 with remote password entering

I played a bit with disk encryption in CentOS6. For this, I checked the "encryption" checkbox in the Anaconda installer during installation, which encrypts at the PV (Physical Volume) partition level. Therefore, all partitions except /boot are encrypted.
Disadvantage is, that you need to enter the decryption password on the local console during boot.

Inspired by RedHat Bug #524727 for Fedora, I setup a "Early-SSH" functionality which allows ssh login to the system at the earliest stage (before the decryption password is asked). With this, I'm able to ssh into a freshly started system and enter the decryption pw without local access.

Early-SSH is a initramfs hook which installs Dropbear SSH server into the initramfs image and starts it at an early stage during boot (before the disks are mounted), so you can perform many things there (Unlock encrypted disks, checking file systems, etc.). The hook gets installed as a Dracut module, therefore it is ensured that every time you update the kernel, the early-SSH module gets installed automatically.

(As usual, try at your own risk)

Remote password entering (early-SSH)

  • Normally you can only continue booting after you entered the decryption password on the local console. 
  • We will add support for early-ssh to be able to enter the decryption pw remotely.
  • There are some instructions available for Fedora Core and Debian, but not for RHEL/CentOS. So here I explain this feature on CentOS6 (tested on 6.3 x86_64)
  • See  https://bugzilla.redhat.com/show_bug.cgi?id=524727 for details on Fedora.

Backup your initrd file

First, backup your current initrd image file to be able to fall back to it in case something goes wrong:
cp /boot/initramfs-`uname -r`.img /boot/initramfs-`uname -r`.img_
If you need to fall back to the original inited file, simply add an "_" to the Grub line pressing "e" during Grub boot stage.

Create dracut module

Install EPEL repository (for Dropbear)

rpm -Uvh http://ftp-stud.hs-esslingen.de/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Install dropbear

yum install dropbear
Install compiler

yum install gcc
Create dracut module
cd /usr/share/dracut/modules.d/
mkdir 40earlyssh
cd 40earlyssh

# Generate public/private DSS and RSA host keys for the server.
dropbearkey -t dss -f dropbear_dss_host_key
dropbearkey -t rsa -f dropbear_rsa_host_key

# Create config files
echo 'multi on' > host.conf
echo -en '127.0.0.1\tlocalhost\n::1\tlocalhost\n' > hosts
echo 'root:x:0:0:root:/home/root:/bin/sh' > passwd
echo '/bin/sh' > shells

Create install file

  • CentOS uses an old Dracut utility (Version 004). Due to this, we must separate check, installkernel and install into separate scripts. But we keep them also together in the "install" script as functions if the upstream vendor switches to a newer Dracut version, later.
  • If on newer Dracult version (>= 008), this file is named "module-setup.sh"
  • Updated: 2014-10-20 (pkill and remote-ssh-delete.sh added)
    vi install
    
    #!/bin/bash
    # On newer Dracult versions, this file is named "module-setup.sh".
    # These functions are currently ignored by CentOS6 Dracut.
    check() { # do not add this module by default: return 255 return 0 } depends() { return 0 } installkernel() { instmods eth0
        instmods vmxnet3   # vmware ethernet driver in this example.
    }
    
    # CentOS6 uses an old version of Dracut.Therefore, install() is not called, so we comment the function definition out for now, so statements are always called.
    
    
    
    #install() {
        dracut_install -o ip
        
        # Need to use inst_library insead of dracut_install for libnsl as it is a symlink
        inst_library   /usr/lib64/libnsl.so
        dracut_install /lib64/libnss_compat.so.2
        dracut_install /lib64/libnss_files.so.2
        dracut_install /lib64/libnss_dns.so.2
        dracut_install -o dropbear
    
        inst_dir "/etc/dropbear"
        inst_simple "${moddir}/dropbear_dss_host_key" "/etc/dropbear/dropbear_dss_host_key"
        inst_simple "${moddir}/dropbear_rsa_host_key" "/etc/dropbear/dropbear_rsa_host_key"
    
        inst_dir "/home"
        inst_dir "/home/root"
        inst_dir "/home/root/.ssh"
        inst_simple "${moddir}/authorized_keys" "/home/root/.ssh/authorized_keys"
    
        inst_simple "/etc/localtime"
        inst_simple "${moddir}/nsswitch.conf" "/etc/nsswitch.conf"
        inst_simple "${moddir}/resolv.conf" "/etc/resolv.conf"
        inst_simple "${moddir}/host.conf" "/etc/host.conf"
        inst_simple "${moddir}/hosts" "/etc/hosts"
        inst_simple "${moddir}/passwd" "/etc/passwd"
        inst_simple "${moddir}/shells" "/etc/shells"
        inst_simple "${moddir}/local.conf" "/etc/modprobe.d/local.conf"
        inst_hook pre-trigger 01 "$moddir/remote-ssh.sh"
        inst_hook pre-trigger 01 "$moddir/remote-ssh-delete.sh"
    
    
        inst_binary "${moddir}/auth" "/bin/auth"
        inst_binary "${moddir}/tiocsti" "/bin/tiocsti"
    
        # Binaries
        dracut_install -o ps find lsof grep egrep sed less more cat tac head tail true false mkdir rmdir rm strace touch vi ip ping ping6 traceroute ssh scp pkill
        # fsck tools so you can check disks when logged in....
        # dracut_install -o fsck fsck.ext2 fsck.ext4 fsck.ext3 fsck.ext4dev fsck.vfat e2fsck
    #}
    


Create check file

vi check
#!/bin/sh

# add this module by default
exit 0

Create installkernel file


You must add the Network kernel module for your network card and place an alias to eth0. Use "ethtool -i eth0" to get the driver name (use your device name if other than eth0)
vi installkernel
#!/bin/bash

# install kernel module script for older dracut.
# Note: You must add your network module, here.
instmods eth0
instmods vmxnet3

Create local.conf (modprobe) file

vi local.conf
# /etc/modprobe.d/local.conf
# device to name mapping.
# Call "ethtool -i eth0" to get your driver name
# Note: You MUST add the network module to installkernel file in this dir, also!

alias eth0 vmxnet3

Alternatively, you can use the "biosdevname" utility, but I haven't done that.

Create nsswitch.conf file

vi nsswitch.conf
passwd:     files
shadow:     files
group:      files
initgroups: files

hosts:      files dns

bootparams: files

ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files

automount:  files
aliases:    files

Create resolv.conf file

vi resolv.conf 
search example
nameserver 192.168.3.100
nameserver 192.168.3.200

Create remote-ssh.sh file

This script is called during boot. It sets up the IP-Address, default gateway and starts the dropbear ssh daemon.
Note: When the system switches context, the initramfs and all processes are closed, therefore security is not harmed after successful boot. But it is absolutely necessary to keep your ssh private key for early-stage ssh secure!

vi remote-ssh.sh
#!/bin/sh
# Setup network card static IP and SSH server on port 222
# In this example 192.168.3.10/24 with gateway 192.168.3.1

/sbin/ip link set dev lo up
/sbin/modprobe eth0
/sbin/ip addr add 192.168.3.10/24 broadcast + dev eth0
/sbin/ip link set dev eth0 up
/sbin/ip route add default via 192.168.3.1

mkdir -p /var/log
> /var/log/lastlog

/usr/sbin/dropbear -E -m -s -p 222 -a -K 600

Create remote-ssh-delete.sh file

This script is called on exit of dracut after disk decryption key was entered. It clears the set IP-Address and frees the interface. (added 2014-10-20)
vi remote-ssh-delete.sh
#!/bin/sh
# Unsetup network card and kill SSH daemon
/sbin/ip link set dev lo down
/sbin/ip link set dev eth0 down
/sbin/ip addr delete 192.168.121.3.10/24 broadcast + dev eth0
/sbin/ip route del default via 192.168.3.1
[ -f /tmp/dropbear.pid ] || exit 0
read main_pid </tmp/dropbear.pid
kill -STOP ${main_pid} 2>/dev/null
pkill -P ${main_pid}
kill ${main_pid} 2>/dev/null
kill -CONT ${main_pid} 2>/dev/null

Create authorized_keys

vi authorized_keys
<Add all public ssh keys you want be able to login into this ssh server as you normally do in your regular authorized_keys file for ssh>

Compile some helper programs

auth

vi auth.c
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

int main (int argc, const char * argv[]) {
  char *passphrase;
  const char *prompt="Passphrase: ";
  int i;

  if (argc != 2) {
    printf("Usage: auth 'passwd'\n");
    return 1;
  }

  int fd = open("/dev/console", O_RDONLY);
  if (fd < 0) {
    return 2;
  }

  passphrase=getpass(prompt);

  for (const char * str = passphrase; *str; ++str){
    ioctl(fd, TIOCSTI, str);
  }
  ioctl(fd, TIOCSTI, "\r");
  // clear string immediately
  int len=strlen(passphrase);
  for (i=0;i<len;i++) { 
   passphrase[i]=0; 
  };
  return 0;
}

tiocsti

vi tiocsti.c
// gcc -std=gnu99 -O2 -Wall tiocsti.c -o tiocsti
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

void stuff(int fd, const char * str) {
  printf("stuff [%s]\n", str);
  for (; *str; ++str) {
    // printf("(%c)", *str);
    int rv = ioctl(fd, TIOCSTI, str);
    if (rv < 0) perror("ioctl(TIOCSTI)");
  }
}

int main (int argc, const char * argv[]) {
  if (argc < 3) {
    printf("Usage: tiocsti /dev/ttyX text string\n");
    return 1;
  }

  int fd = open(argv[1], O_RDONLY);
  if (fd < 0) {
    perror("open");
    return 2;
  }

  for (int i = 2; i < argc; ++i) {
    if (i != 2) stuff(fd, " ");
    stuff(fd, argv[i]);
  }

  close(fd);
  return 0;
}

Compile helper programs

gcc -std=gnu99 -O2 -Wall tiocsti.c -o tiocsti
gcc -std=gnu99 -O2 -Wall auth.c -o auth

Fix permissions

You need to ensure the permissions of the files are correct, otherwise dropbear and the helper files are not included in the initramfs (Thanks to Ben Curtis):


chmod 755 check install installkernel remote-ssh.sh
chmod 600 authorized_keys

Build new initramfs

So you end up with the following files in /usr/share/dracut/modules.d/40earlyssh:

authauth.c

authorized_keys

check

dropbear_dss_host_key

dropbear_rsa_host_key

host.conf

hosts

install

installkernel

local.conf

nsswitch.conf

passwd

README

remote-ssh.sh

resolv.conf

shells

tiocsti

tiocsti.c
Create new initrd image:
dracut --force

Reboot, test

  • Now reboot. 
  • Once the machine is booted and at it's waiting for the password, it should be pingable from the network.
  • Login remotely:
ssh -p 222 root@<machine_name_or_its_ip>
  • Enter the preboot password:
tiocsti /dev/console "$(echo -n '<your_decryption_password>\r')"
# example: tiocsti /dev/console "$(echo -n 'verySecurePw!\r')"

47 comments:

  1. Hallo Robert!
    vielen Dank für dieses Weihnachtsgeschenk, ich hatte das ganze ebenfalls erfolglos versucht und werde mich nun an diese Anleitung halten, mit der es dann hoffentlich klappt.
    LG, der andere Robert aus dem Bugthread. :)

    ReplyDelete
  2. Slight change: /usr/lib64/libnsl.so must be installed with inst_library, as it is a symlink.

    ReplyDelete
  3. Another slight change: You've got resolve.conf in a line instead of resolv.conf.

    Also, I can't seem to get this to work. How does this function when it doesn't seem like dropbear is included in the initramfs? If everything but /boot is encrypted, how is it accessed?

    ReplyDelete
  4. @Ben athanks for finding the typo. See Install file section. In the install file, dropbear gets included in the initramfs.

    In boot, the kernel and bootloader with the initramfs resides, therefore, it mustn't be encrypted. In the bootloading stage, the fs gets decrypted.

    ReplyDelete
  5. Thanks Bertl.

    I found a problem, and a step that for people like me who don't think things through would find useful :)

    chmod 755 check install installkernel remote-ssh.sh
    chmod 600 authorized_keys

    The lack of proper permissions (specifically execute) is what kept dropbear from being installed into the initramfs.

    ReplyDelete
  6. Hello Robert,

    I got to a stage where I'm able to ping my host, but I cannot telnet to port 222 (Connection refused - just like any other port).

    Is there any way to debug this process? By the way I'm trying to do this for non-root partition in case it makes any difference.

    ReplyDelete
  7. Jacobs,

    It seems dropbear was not included into your initramfs archive.

    Please check your file permissions. I updated the article with the permission fix right now. Then recreate the iniramfs and try again.

    ReplyDelete
  8. I already had those permission implemented (found them in the comments).

    Can I somehow check what ended up in my initramfs?

    This is all I get during initramfs creation (I'm running Centos 6.5 x86_64):
    40earlyssh # dracut --force
    W: Skipping program lsof as it cannot be found and is flagged to be optional
    W: Skipping program strace as it cannot be found and is flagged to be optional
    W: Skipping program traceroute as it cannot be found and is flagged to be optional
    40earlyssh #

    ReplyDelete
  9. Ah, here we go (should've googled first a bit :-))

    # lsinitrd | grep drop
    drwxr-xr-x 2 root root 0 Aug 19 16:48 etc/dropbear
    -r-------- 1 root root 458 Aug 19 14:15 etc/dropbear/dropbear_dss_host_key
    -r-------- 1 root root 803 Aug 19 14:15 etc/dropbear/dropbear_rsa_host_key
    -rwxr-xr-x 1 root root 205408 Aug 19 16:48 usr/sbin/dropbear

    ReplyDelete
  10. Hi,

    I have done these steps. However, for some reason, I con't login with the authentication key. Always returns Permission denied.I tried generating 1024,2048 and 4096 keys with puttygen and inserted into authorized_keys file. What am I doing wrong?

    Thanks.

    ReplyDelete
  11. Great tutorial, unfortunately i am not able to get it working :(

    -rwxr-xr-x 1 root root 210288 Sep 7 07:50 usr/sbin/dropbear
    drwxr-xr-x 2 root root 0 Sep 7 07:50 etc/dropbear
    -rw------- 1 root root 426 Sep 3 18:55 etc/dropbear/dropbear_rsa_host_key
    -rw------- 1 root root 458 Sep 3 18:55 etc/dropbear/dropbear_dss_host_key

    guess this is correct?

    i can not ping nor do anything else
    http://pastebin.com/53vcVQj6

    [root@trustserv 40earlyssh]# ethtool -i eth0
    driver: virtio_net
    version:
    firmware-version:
    bus-info: virtio3
    supports-statistics: no
    supports-test: no
    supports-eeprom-access: no
    supports-register-dump: no
    supports-priv-flags: no

    A nice way to somehow debug that would be great, e.g. use logger also in the initramfs and put some output to messages log... is that possible?

    any help would be really appreciated!

    ReplyDelete
  12. Have you added the virtio_net driver to the "installkernel" and "install" files?

    You cannot log anything to a logfile, as at this stage, all filesystems are unmounted, therefore there is no access to the logfiles possible.

    ReplyDelete
  13. Thanks for that fast answer.
    Yes i added the virtio driver:
    # install kernel module script for older dracut.
    # Note: You must add your network module, here.
    instmods eth0
    instmods virtio_net

    what exactly do you mean with "install" files?

    Regarding logging: the funny thing is that the stuff which happened before(!) entering the password is also logged in messages, so i am wondering how that works ;)

    ReplyDelete
  14. See section "Create install file".

    ReplyDelete
  15. thanks, you were right, one entry was still vmxnet3 in the file "install", but i replaced that and still cant ping the machine... :(
    any idea/hint?

    ReplyDelete
  16. at the weekend i am going to try to debug that with writing to /boot

    ReplyDelete
  17. Hi,
    I try this procedure with Fedora 19 and I successfull login with ssh and send password to unlock disk but after the system go to emergency shell and it doesn't make any other operation.
    The same behavior if I login and logout (with no other command send in ssh) and then type password in normal way.
    Have some suggestion?

    ReplyDelete
  18. short update: i was able to get that working with virtualbox and centos 6.4 with driver e1000. going to get that working next WE on my real server as i have no time atm :/
    But thanks for that great tutorial!

    ReplyDelete
  19. i am able to write to /boot in the .sh files so guess i should be able to figure out whats going wrong. i have seen that the check file and the instmods eth0, instmods virtio_net has been executed, but then it stops. can you tell me anything about the order in which the scripts are executed?

    ReplyDelete
  20. I suggest you add some print lines to remote-ssh.sh to see if it is called. Have you checked the permissions of all files? Thats very sensitive. See "Fix permissions".



    ReplyDelete
  21. @logocomune: Sorry, can't help here. This procedure is for CentOS 6, only. I think that Fedora uses a newer Dracut module. Maybe check the Upstream Bug Report (see link at the beginning of my artice). There I think they are talking about Fedora.

    ReplyDelete
  22. i added some lines to remote-ssh but it did not get executed. i will contact the server provider as i was able to get that working on a virtualbox image. so something must be wrong here... also, i am unable to ping that machine when the password prompt appears. but the ip is set (i did a: ip addr show > /boot/wtf.log) correctly..

    ReplyDelete
  23. Maybe a firewall in front of the machine?

    ReplyDelete
  24. Just got some new output:

    /pre-trigger/01remote-ssh.sh: 5: cannot create /boot/wtf.txt: Directory nonexistent
    udev: starting version 147
    Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-eth0 instead.
    Cannot find device "eth0"
    RTNETLINK: No such process

    Any idea?

    ReplyDelete
  25. changed the device to netdev-eth0 but its still not working. The message is gone. Thats really nucking me futs :E

    /boot/wtf.txt was somehow accidently created by myself when i probably tested the .sh scripts, also output with echo does not work.

    ReplyDelete
  26. Short update: debugging is working with echo only.
    Also, when using output pipes in the scripts, probably not such good idea as the scripts get executed when dracut --force is executed.

    http://www.imagebanana.com/view/w9o4jdm2/asdf2.png
    http://www.imagebanana.com/view/u1omk2bs/asdf.png

    only virtio modules have been loaded, i dont know if something like any net driver from the kernel must be loaded in this stage too?

    also, there is no such dev like eth(n) nor em(n) - now i am stuck.

    ReplyDelete
  27. Ethernet device was not loaded. Please check your configuration.

    ReplyDelete
  28. Thats what i know too, as it says "eth0 not found" on the screenshots. The quesiton is: why?
    Configuration is exactly as on the guide, except the drivers which are replaced by virtio drivers.

    ReplyDelete
  29. moving on.. for everybody who's nucking futs: add the parameter "rdshell" to the kernel params, hit ctrl+c when prompted for the password two times and et voila, get a interactive dracut shell, just like busybox. perfect for debugging. when i execute 01remote-ssh.sh in pre-trigger, i have network access and can authenticate against dropbear. when i find a solution i will post it here.

    ReplyDelete
  30. got it working after some time... the problem is that with kvm there is somehow problems with udev.

    the "workaround" at the moment is:
    in file install:
    - add somewhere:
    inst_simple "${moddir}/mysleep" "/bin/mysleep"

    now move the file "remote-ssh.sh" to "mysleep" and create a new "remote-ssh.sh" file with the content:
    #!/bin/sh
    /bin/mysleep &

    last but not least, add somewhere in the pretty beginning of /bin/mysleep the line:
    sleep 10 #should be enough

    dracut --force && reboot, thats it

    the problem is somehow based on how udev and kvm works together. the device is not up and cannot be accessed when 01remote-ssh.sh gets executed.

    thanks for that great tutorial!

    ReplyDelete
  31. I managed to get dropbear working thanks to kabustalek's workaround! So entering my passphrase via ssh is no problem anymore. But now openssh (sshd) is not starting correctly anymore. When I use the original initrd (with underscore), sshd works as expected (service running after boot), so I guess it isn't about the config files.
    When using the modified initrd, there is no error shown while startup, it even says "sshd starting: [OK]".
    But when I try to login via ssh I get the following error messages:
    client: ssh -p 2345 user@host
    client: ssh_exchange_identification: Connection closed by remote host
    server: Early exit: Failure reading random device /dev/urandom
    When I try again, the error changes:
    client: ssh: connect to host xpush port 2114: Connection refused
    server: (no output)
    After logging in directly, "sudo service sshd status" tells me the daemon isn't running. After restarting manually with "sudo service sshd restart" it's working.
    Any ideas?
    Thanks for the great tutorial and the helpful comments above!

    ReplyDelete
  32. edit: "sudo service sshd restart" is not working. sorry for the mistake.

    is it possible that dropbear and sshd are interfering somehow?
    maybe it's important: dropbear and sshd listen on the same port but have different users being able to login.

    any help greatly appreciated!

    ReplyDelete
  33. This comment has been removed by the author.

    ReplyDelete
  34. if anyone is having the same problem: it's about the port. just use different ports for the different services (dropbear and sshd). although they aren't running in parallel they still interfere somehow.
    this fixed my issue.

    ReplyDelete
  35. I am stuck on the following dracut error when building initramfs (last step really):


    E: Cannot install a hook (/remote-ssh.sh) that does not exist.
    E: Aborting initrd creation.


    The permissions are

    -rwxr-xr-x 1 root root 388 Apr 14 00:36 remote-ssh.sh

    and the file clearly exists. I checked the Dracut function source and it seems to fail on a simple, BASH-like [ -f FILE ], which makes even less sense. I am sure it is something very trivial that I am missing (or the error message is not reflecting the underlying problem).

    Anyone has seen this error and can point me in the right direction?

    ReplyDelete
  36. Wow, I had not heard of earlyssh before. I'll have to try it. I have been using a password keyfile in /etc/crypttab which already has its security issues, but at least it mounts automatically on reboot instead of waiting for a password. Trade-off I suppose of security vs automated mount on reboot.

    Great article!

    ReplyDelete
  37. I have installed centos 6, which I want to be fully encrypted. I have there /dev/sda1 - /boot partition, and /dev/sda2 - lvm partition with root, home and swap. I have created full copy of /dev/sda1 on /dev/sdb1, and created encrypted partition on /dev/sdb2, there created lvm with root, home, swap, then created dracut module like you write, but system at boot goes to kernel panic, it is looking for VolGroup, which is not activated yet because I can not encrypt it quickly ( I mean, dropbear is starting, but system goes to kernel panic to quickly). Sorry, can you help me?

    ReplyDelete
  38. Robert,

    Absolutely terrific blog post! This is exactly what I was looking for. However, I'm trying to automate the deployment of this to all of my servers (using Kickstart) and thus have to use DHCP/dhclient instead of hardcoding the addresses in. My DHCP server gives out the appropriate IP via static leases, but for some reason the changes I made don't seem to fire up dhclient (I've packet captured on dhcpd-hosted server and there's no DHCPDISCOVER from the machine running this setup).

    I tried replacing:
    /sbin/ip link set dev lo up
    /sbin/modprobe eth0
    /sbin/ip addr add 192.168.3.10/24 broadcast + dev eth0
    /sbin/ip link set dev eth0 up
    /sbin/ip route add default via 192.168.3.1

    with:
    /sbin/ip link set dev lo up
    /sbin/modprobe eth0
    /sbin/dhclient

    Additionally, I added "dhclient" to the end of the long string in installkernel() (i.e., the one that begins "dracut_install -o ps find ..."). Note that upon running dracut --force there were no (additional) errors reported.

    Any ideas what I'm missing? Thanks again!

    ReplyDelete
  39. Just to follow up, I figured out how to use DHCP and fixed-host, etc. The problem w/relying on dhclient to call dhclient-script is that the latter has LOADS of dependencies (e.g., /etc/sysconfig/network-scripts/network-functions, /etc/init.d/functions, etc.). It also required /bin/bash rather than /bin/sh so you have to grow the install file quite a bit.

    In case anyone also wants to use DHCP, here's my remote-ssh.sh:

    /sbin/modprobe eth0
    /sbin/ip link set dev eth0 up
    /sbin/dhclient -d -w eth0 -lf /dev/null -lf /tmp/leases &
    /bin/sleep 15

    mkdir -p /var/log
    > /var/log/lastlog

    IPADDR=`/bin/grep "fixed-address" /tmp/leases|awk '{print $2}'|sed -e 's/;//'`
    echo "ip address is $IPADDR"
    SUBNET=`/bin/grep "subnet-mask" /tmp/leases|/bin/awk '{print $3}'|/bin/sed -e 's/;//'`
    echo "subnet mask is $SUBNET"
    GATEWAY=`/bin/grep "option routers" /tmp/leases|/bin/awk '{print $3}'|/bin/sed -e 's/;//'`
    echo "gateway is $GATEWAY"

    /sbin/ip addr add $IPADDR/$SUBNET broadcast + dev eth0
    /sbin/ip link set dev eth0 up
    /sbin/ip route add default via $GATEWAY
    /bin/sleep 10

    /usr/sbin/dropbear -E -m -s -p 222 -a -K 600


    The sleeps were leftover from debugging but I'm too lazy to remove and check if they work without. Basically what this does is capture the inbound DHCP info to a file, grab the necessary info, and then call /sbin/ip as Robert did for a static setup.

    The only other change I needed to make was to 'install'; here is my updated dracut_install line:

    dracut_install -o ps find lsof grep egrep sed less more cat tac head tail true false mkdir rmdir rm strace touch vi ip ping ping6 traceroute ssh scp dhclient sleep awk

    Note that addition of dhclient, sleep, and awk.

    ReplyDelete
  40. Updated main post:

    Added forgotten pkill which is needed to kill ssh on port to get the IP address freed after decryption.

    ReplyDelete
  41. Note: If you get a corrupt RAMDISK message during boot, it might be that your ramdisk img file gets to big to fit the max ramdisk size.

    In this case, add "ramdisk_size=32768" to the kernel options (tab key in grub). When booting, add "ramdisk_size=32768" to /boot/grub/grub.conf kernel options, like

    kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/vg_root rd_LVM_LV= vg_root/lv_root ... rd_LVM_LV=vg_root/lv_swap rd_NO_DM rhgb quiet ramdisk_size=32768

    ReplyDelete
  42. Hi Robert,

    I couldn't find your email-address,
    I want to take https://github.com/mdcurtis/dracut-earlyssh , to cleanup it a bit and to create a merge request to the dracut upstream. There is one issue, there is no license so far(so its public domain). The auth.c you have in this post is included there as well,
    - are you the author of it?
    - if yes, is it ok to license it with GPL-2 like dracut?
    - if not, do you know the original author of this file?

    ReplyDelete
  43. I'm not the author. The original code is taken from the RH bug report on https://bugzilla.redhat.com/show_bug.cgi?id=524727
    as stated in the article.

    ReplyDelete
  44. I'm getting the "Cannot find device 'eth0'" error on boot (immediately following dracut --force). As I know this points to a misconfiguration, could someone clarify where I am to add/edit the driver name as taken from this line?

    > Use "ethtool -i eth0" to get the driver name

    Assuming this goes in installkernel, but do I add a new line or change the existing line(s)?

    instmods eth0
    instmods vmxnet3

    My output from "ethtool -i eth0" is "e0001".

    ReplyDelete
  45. I'm getting the "Cannot find device 'eth0'" error on boot (immediately following dracut --force). As I know this points to a misconfiguration, could someone clarify where I am to add/edit the driver name as taken from this line?

    > Use "ethtool -i eth0" to get the driver name

    Assuming this goes in installkernel, but do I add a new line or change the existing line(s)?

    instmods eth0
    instmods vmxnet3

    My output from "ethtool -i eth0" is "e0001".

    ReplyDelete
  46. Tried modifying installkernal to

    instmods eth0
    instmods e1000

    Rebooted, still getting "Cannot find device eth0".

    ethtool -i eth0 returns:

    driver: e1000
    version: 7.3.21-k8-NAPI
    firmware-version:
    bus-info: 0000:00:09.0
    supports-statistics: yes
    supports-test: yes
    supports-eeprom-access: yes
    supports-register-dump: yes
    supports-priv-flags: no

    ReplyDelete

Due to the high amount of Spam, you must solve a word verification.