clevis
clevis copied to clipboard
Dracut module issue detecting TANG for "rd.neednet" injection
I was configuring network based decryption on my system and noticed the system was not decrypting. I've set it up before and was pretty baffled. I narrowed it down to the lack of "rd.neednet" being present on the commandline. Why I asked, that should be automatic. Turns out there is some issue with the check. I'm /guessing/ it has to do with "hardware" (this is a VM, with a networked disk) speed.
This is the questionable line of code.
https://github.com/latchset/clevis/blob/2b34226c298f426bb1b69a178622e5884ba31b6d/src/luks/dracut/clevis-pin-tang/module-setup.sh.in#L30
I hacked up the module-setup.sh to figure out what was going on. I added these lines:
clevis luks list -d "${dev}" | grep tang >> "${initdir}/clevis.log"
echo $? >> "${initdir}/clevis.log"
echo "==" >> "${initdir}/clevis.log"
clevis luks list -d "${dev}" | grep -q tang >> "${initdir}/clevis.log"
echo $? >> "${initdir}/clevis.log"
This is what I got:
2: sss '{"t":1,"pins":{"tang":[{"url":"http://tang1.cos.gatech.edu"},{"url":"http://tang2.cos.gatech.edu"},{"url":"http://tang3.cos.gatech.edu"}]}}'
0
==
141
From a "quick google" it seems like the exit code 141 is because "pipefail" is set (dracut sets it??) and grep -q terminates as soon as a match is found but the previous command is still running / printing to the pipe.
Some solutions:
- Unset and set pipefail. This would need to check if pipefail was already set, you don't want to set pipefail on when it wasn't set.
- Use a subshell. Either for the full function or parts. This allows for more control over pipefail and not needing to worry about reset.
- Use process redirection
if grep -q tang <(clevis luks list -d "${dev}") - Don't use -q and just redirect the grep output to /dev/null
--
Just for some further clarity. I do believe that my having additional unlockers is partially to blame. But I think that should be a supported configuration.
Here is the full output of the list.
[root@cos-4x12752 60clevis-pin-tang]# clevis luks list -d /dev/sda3
2: sss '{"t":1,"pins":{"tang":[{"url":"http://tang1.cos.gatech.edu"},{"url":"http://tang2.cos.gatech.edu"},{"url":"http://tang3.cos.gatech.edu"}]}}'
3: tpm2 '{"hash":"sha256","key":"ecc","pcr_bank":"sha256","pcr_ids":"0,1,7"}'
Or my extension added in PR #462 could be used together with simple bash substring check:
pins=$(clevis_luks_used_pins "${dev}") || continue
[[ " $pins " == *" tang "* ]] && return 0
Anyway, I have not found any pipefail in my /usr/lib/dracut (standard installation). But because the module-setup.sh file is being sourced by Dracut, any changes inside this file might be propagated outside - from any module installed in your system.
$ grep -r pipefail
modules.d/99kdumpbase/kdump.sh:# POSIX doesn't have pipefail, only apply when using bash
modules.d/99kdumpbase/kdump.sh:[ -n "$BASH" ] && set -o pipefail
This is a RHEL9 system and I don't believe I have enable or disabled anything from install. I don't even know what kdump is.
Thanks, so it has to be enabled somewhere else. I have checked Dracut sources and it seems dracut.sh itself enables pipefail and sources dracut-init.sh to get support functions, like module_install, which sources module's module-setup.sh in order to call install, so this means that pipefail is still enabled.
According to https://unix.stackexchange.com/a/743266/239414 the solution could be:
if (clevis luks list -d "${dev}"; true) | grep -q tang; then
but that looks more like a workaround to me (but my opinion is not unbiased due to my script 😅).