Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I have a setup based on this, but I modified it to encrypt the SSH host key using the TPM. That way, I can detect a MiTM from an attacker who has stolen the drive or modified the boot policy because host key verification will fail.

/usr/lib/dracut/modules.d/46cryptssh:

    #!/bin/bash
    
    check() {
        require_binaries sshd || return 1
        return 0
    }
    
    depends() {
        return 0
    }
    
    install() {
        if [ ! -e /etc/ssh/dracut ]; then
            mkdir /etc/ssh/dracut &&
            tmp=$(mktemp -d) &&
            head -c128 /dev/random > $tmp/passphrase &&
            ssh-keygen -t ed25519 -f /etc/ssh/dracut/ssh_host_ed25519_key -N"$(base64 < $tmp/passphrase)" &&
            tpm2_createprimary -C o -c $tmp/primary.ctx &&
            tpm2_pcrread -o $tmp/pcr.bin sha256:0,7
            tpm2_createpolicy --policy-pcr -l sha256:0,7 -f $tmp/pcr.bin -L $tmp/pcr.policy
            tpm2_create -C $tmp/primary.ctx -L $tmp/pcr.policy -i $tmp/passphrase -c $tmp/seal.ctx &&
            tpm2_evictcontrol -C o -c $tmp/seal.ctx -o /etc/ssh/dracut/seal || {
                rm -r $tmp /etc/ssh/dracut
                exit 1
            }
            rm -r $tmp
        fi
        for file in /etc/ssh/dracut/*; do
            inst_simple "$file" "/etc/ssh/${file#/etc/ssh/dracut/}"
        done
    
        mkdir -p -m 0700 "$initdir"/root/.ssh
        /usr/bin/install -m 600 /etc/ssh/dracut_authorized_keys "$initdir"/root/.ssh/authorized_keys
    
        inst_binary /usr/sbin/sshd
        inst_binary /usr/sbin/ssh-keygen
        inst_binary /usr/bin/tpm2_unseal
        inst_binary /usr/bin/base64
        inst_simple /usr/lib/libtss2-tcti-device.so
        
        inst_simple "$moddir"/cryptsshd.service "$systemdsystemunitdir"/cryptsshd.service
        inst_simple "$moddir"/sshd_config /etc/ssh/sshd_config
    
        inst_binary /usr/lib/ssh/sshd-session
        inst_binary /usr/lib/ssh/sshd-auth
    
        mkdir -p -m 0755 "$initdir"/var/empty/sshd
        mkdir -p -m 0755 "$initdir"/usr/share/empty.sshd
        mkdir -p  -m 0755 "$initdir"/var/log
        touch "$initdir"/var/log/lastlog
    
        systemctl -q --root "$initdir" enable cryptsshd
    }
cryptsshd.service:

    [Unit]
    Description=OpenSSH Daemon for Disk Encryption Passphrase
    DefaultDependencies=no
    Before=cryptsetup.target
    After=network-online.target
    
    [Service]
    Type=notify-reload
    ExecStartPre=/bin/sh -c '/usr/bin/ssh-keygen -p -f /etc/ssh/ssh_host_ed25519_key \
        -N "" -P "$(/usr/bin/tpm2_unseal -c /etc/ssh/seal -p pcr:sha256:0,7 | base64)"'
    ExecStart=/usr/bin/sshd -D
    KillMode=process
    Restart=always
    
    [Install]
    WantedBy=sysinit.target
That encrypts the SSH host key using a password sealed with PCR7, which is invalidated if an attacker disables Secure Boot or tampers with the enrolled keys. Thus, an attacker can't extract the key from the drive or by modifying the kernel command line to boot to a shell (since that's not allowed without disabling secure boot).

It's still probably vulnerable to a cold boot attack, since the key is decrypted CPU-side. It would be interesting to perform the actual key operations on the TPM itself to prevent this.

 help



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: