dracut + systemd + LUKS + usbflash = ื‘ื™ื˜ื•ืœ ื ืขื™ืœื” ืื•ื˜ื•ืžื˜ื™

ื”ืกื™ืคื•ืจ ื”ืชื—ื™ืœ ืœืคื ื™ ื–ืžืŸ ืจื‘, ืขื•ื“ ื›ืืฉืจ Centos 7 (RHEL 7) ืฉื•ื—ืจืจ. ืื ื”ืฉืชืžืฉืช ื‘ื”ืฆืคื ื” ื‘ื›ื•ื ื ื™ื ืขื Centos 6, ืื– ืœื ื”ื™ื• ื‘ืขื™ื•ืช ืขื ื‘ื™ื˜ื•ืœ ื ืขื™ืœื” ืื•ื˜ื•ืžื˜ื™ ืฉืœ ื›ื•ื ื ื™ื ื›ืืฉืจ ื—ื™ื‘ืจืช ื›ื•ื ืŸ ื”ื‘ื–ืง ืžืกื•ื’ USB ืขื ื”ืžืคืชื—ื•ืช ื”ื“ืจื•ืฉื™ื. ืขื ื–ืืช, ื›ืืฉืจ 7 ืฉื•ื—ืจืจ, ืคืชืื•ื ื”ื›ืœ ืœื ืขื‘ื“ ื›ืคื™ ืฉื”ื™ื™ืช ืจื’ื™ืœ. ืœืื—ืจ ืžื›ืŸ ื ื™ืชืŸ ื”ื™ื” ืœืžืฆื•ื ืคืชืจื•ืŸ ื‘ื”ื—ื–ืจืช dracut ืœ-sysvinit ื‘ืืžืฆืขื•ืช ืฉื•ืจื” ืคืฉื•ื˜ื” ื‘ืชืฆื•ืจื”: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
ืžื” ืฉืžื™ื“ ืฉืœืœ ืžืื™ืชื ื• ืืช ื›ืœ ื”ื™ื•ืคื™ ืฉื‘-systemd - ื”ืฉืงื” ืžื”ื™ืจื” ื•ืžืงื‘ื™ืœื” ืฉืœ ืฉื™ืจื•ืชื™ ืžืขืจื›ืช, ืฉื”ืคื—ื™ืชื” ืžืฉืžืขื•ืชื™ืช ืืช ื–ืžืŸ ื”ืืชื—ื•ืœ ืฉืœ ื”ืžืขืจื›ืช.
ื”ื“ื‘ืจื™ื ืขื“ื™ื™ืŸ ืฉื: 905683
ื‘ืœื™ ืœื—ื›ื•ืช ืœืคืชืจื•ืŸ, ื”ื›ื ืชื™ ืืช ื–ื” ืœืขืฆืžื™, ื•ืขื›ืฉื™ื• ืื ื™ ืžืฉืชืฃ ืื•ืชื• ืขื ื”ืฆื™ื‘ื•ืจ ื”ืžืขื•ื ื™ื™ืŸ, ื”ืžืฉืš ืœืงืจื•ื.
dracut + systemd + LUKS + usbflash = ื‘ื™ื˜ื•ืœ ื ืขื™ืœื” ืื•ื˜ื•ืžื˜ื™

ืžื‘ื•ื

Systemd, ื›ืฉื”ืชื—ืœืชื™ ืœืขื‘ื•ื“ ืขื Centos 7, ืœื ืขื•ืจืจื” ืฉื•ื ืจื’ืฉื•ืช, ืฉื›ืŸ ืžืœื‘ื“ ืฉื™ื ื•ื™ ืžื™ื ื•ืจื™ ื‘ืชื—ื‘ื™ืจ ื ื™ื”ื•ืœ ื”ืฉื™ืจื•ืช, ืœื ื”ืจื’ืฉืชื™ ื”ืจื‘ื” ื”ื‘ื“ืœ ื‘ื”ืชื—ืœื”. ืœืื—ืจ ืžื›ืŸ, ืื”ื‘ืชื™ ืืช systemd, ืื‘ืœ ื”ืจื•ืฉื ื”ืจืืฉื•ื ื™ ื”ื™ื” ืžืขื˜ ืžืงื•ืœืงืœ, ืžื›ื™ื•ื•ืŸ ืฉืžืคืชื—ื™ dracut ืœื ื”ืฉืงื™ืขื• ื–ืžืŸ ืจื‘ ื‘ืชืžื™ื›ื” ื‘ืชื”ืœื™ืš ื”ืืชื—ื•ืœ ื‘ืืžืฆืขื•ืช systemd ื‘ืฉื™ืœื•ื‘ ืขื ื”ืฆืคื ืช ื“ื™ืกืง. ื‘ืื•ืคืŸ ื›ืœืœื™ ื–ื” ืขื‘ื“, ืื‘ืœ ื”ื–ื ืช ืกื™ืกืžืช ื”ื“ื™ืกืง ื‘ื›ืœ ืคืขื ืฉื”ืฉืจืช ืžื•ืคืขืœ ื–ื” ืœื ื”ื“ื‘ืจ ื”ื›ื™ ืžืขื ื™ื™ืŸ.
ืœืื—ืจ ืฉื ื™ืกื™ืชื™ ืฉืœืœ ื”ืžืœืฆื•ืช ื•ืœืžื“ืชื™ ืืช ื”ืžื“ืจื™ืš, ื”ื‘ื ืชื™ ืฉื‘ืžืฆื‘ ืžืขืจื›ืช ืงื•ื ืคื™ื’ื•ืจืฆื™ื” ืขื USB ืืคืฉืจื™ืช, ืื‘ืœ ืจืง ืขื ืฉื™ื•ืš ื™ื“ื ื™ ืฉืœ ื›ืœ ื“ื™ืกืง ืขื ืžืคืชื— ื‘ื“ื™ืกืง USB, ื•ืืช ื“ื™ืกืง ื”-USB ืขืฆืžื• ื ื™ืชืŸ ืœืฉื™ื™ืš ืจืง ืขืœ ื™ื“ื™ UUID, LABEL ืœื ืขื‘ื“. ื–ื” ืœื ื”ื™ื” ืžืื•ื“ ื ื•ื— ืœืชื—ื–ืง ืืช ื–ื” ื‘ื‘ื™ืช, ืื– ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ืฆืœืœืชื™ ืœื—ื›ื•ืช ื•ืœืื—ืจ ื”ืžืชื ื” ืฉืœ ื›ืžืขื˜ 7 ืฉื ื™ื, ื”ื‘ื ืชื™ ืฉืืฃ ืื—ื“ ืœื ืขื•ืžื“ ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื”.

ื‘ืขื™ื•ืช

ื›ืžื•ื‘ืŸ, ื›ืžืขื˜ ื›ืœ ืื—ื“ ื™ื›ื•ืœ ืœื›ืชื•ื‘ ืชื•ืกืฃ ืžืฉืœื• ืœ-dracut, ืื‘ืœ ืœื’ืจื•ื ืœื–ื” ืœืขื‘ื•ื“ ื›ื‘ืจ ืœื ื›ืœ ื›ืš ืงืœ. ื”ืชื‘ืจืจ ืฉื‘ื’ืœืœ ื”ืื•ืคื™ ื”ืžืงื‘ื™ืœ ืฉืœ ื”ื”ืคืขืœื” ืฉืœ systemd, ืœื ื›ืœ ื›ืš ืงืœ ืœื›ืœื•ืœ ืืช ื”ืงื•ื“ ืฉืœืš ื•ืœืฉื ื•ืช ืืช ื”ืชืงื“ืžื•ืช ื”ื˜ืขื™ื ื”. ื”ืชื™ืขื•ื“ ืœ-dracut ืœื ื”ืกื‘ื™ืจ ื”ื›ืœ. ืขื ื–ืืช, ืœืื—ืจ ื ื™ืกื•ื™ื™ื ืžืžื•ืฉื›ื™ื, ื”ืฆืœื—ืชื™ ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื”.

ืื™ืš ื–ื” ืขื•ื‘ื“

ื”ื•ื ืžื‘ื•ืกืก ืขืœ ืฉืœื•ืฉ ื™ื—ื™ื“ื•ืช:

  1. luks-auto-key.service - ืžื—ืคืฉ ื›ื•ื ื ื™ื ืขื ืžืคืชื—ื•ืช ืขื‘ื•ืจ LUKS
  2. luks-auto.target - ืคื•ืขืœ ื›ืชืœื•ืช ืขื‘ื•ืจ ื™ื—ื™ื“ื•ืช systemd-cryptsetup ืžื•ื‘ื ื•ืช
  3. luks-auto-clean.service - ืžื ืงื” ืงื‘ืฆื™ื ื–ืžื ื™ื™ื ืฉื ื•ืฆืจื• ืขืœ ื™ื“ื™ luks-auto-key.service

ื•-luks-auto-generator.sh ื”ื•ื ืกืงืจื™ืคื˜ ืฉืžื•ืคืขืœ ืขืœ ื™ื“ื™ systemd ื•ืžื™ื™ืฆืจ ื™ื—ื™ื“ื•ืช ื”ืžื‘ื•ืกืกื•ืช ืขืœ ืคืจืžื˜ืจื™ ืœื™ื‘ื”. ื’ื ืจื˜ื•ืจื™ื ื“ื•ืžื™ื ื ื•ืฆืจื™ื ืขืœ ื™ื“ื™ ื™ื—ื™ื“ื•ืช fstab ื•ื›ื•'.

luks-auto-generator.sh

ื‘ืืžืฆืขื•ืช drop-in.conf, ื”ื”ืชื ื”ื’ื•ืช ืฉืœ systemd-cryptsetup ื”ืกื˜ื ื“ืจื˜ื™ืช ืžืฉืชื ื” ืขืœ ื™ื“ื™ ื”ื•ืกืคืช luks-auto.target ืœืชืœื•ืช ืฉืœื”ื.

luks-auto-key.service ื•-luks-auto-key.sh

ื™ื—ื™ื“ื” ื–ื• ืžืจื™ืฆื” ืืช ื”ืกืงืจื™ืคื˜ luks-auto-key.sh, ืืฉืจ, ื‘ื”ืชื‘ืกืก ืขืœ ืžืคืชื—ื•ืช rd.luks.*, ืžื•ืฆื ืžื“ื™ื” ืขื ื”ืžืคืชื—ื•ืช ื•ืžืขืชื™ืง ืื•ืชื ืœืกืคืจื™ื™ื” ื–ืžื ื™ืช ืœืฉื™ืžื•ืฉ ื ื•ืกืฃ. ืœืื—ืจ ื”ืฉืœืžืช ื”ืชื”ืœื™ืš, ื”ืžืคืชื—ื•ืช ื ืžื—ืงื™ื ืžื”ืกืคืจื™ื™ื” ื”ื–ืžื ื™ืช ืขืœ ื™ื“ื™ luks-auto-clean.service.

ืžืงื•ืจื•ืช:

/usr/lib/dracut/modules.d/99luks-auto/module-setup.sh

#!/bin/bash

check () {
        if ! dracut_module_included "systemd"; then
                "luks-auto needs systemd in the initramfs"
                return 1
        fi
        return 255
}

depends () {
        echo "systemd"
        return 0
}

install () {
        inst "$systemdutildir/systemd-cryptsetup"
		inst_script "$moddir/luks-auto-generator.sh" "$systemdutildir/system-generators/luks-auto-generator.sh"
		inst_script "$moddir/luks-auto-key.sh" "/etc/systemd/system/luks-auto-key.sh"
		inst_script "$moddir/luks-auto.sh" "/etc/systemd/system/luks-auto.sh"
		inst "$moddir/luks-auto.target" "${systemdsystemunitdir}/luks-auto.target"
		inst "$moddir/luks-auto-key.service" "${systemdsystemunitdir}/luks-auto-key.service"
		inst "$moddir/luks-auto-clean.service" "${systemdsystemunitdir}/luks-auto-clean.service"
		ln_r "${systemdsystemunitdir}/luks-auto.target" "${systemdsystemunitdir}/initrd.target.wants/luks-auto.target"
		ln_r "${systemdsystemunitdir}/luks-auto-key.service" "${systemdsystemunitdir}/initrd.target.wants/luks-auto-key.service"
		ln_r "${systemdsystemunitdir}/luks-auto-clean.service" "${systemdsystemunitdir}/initrd.target.wants/luks-auto-clean.service"
}

/usr/lib/dracut/modules.d/99luks-auto/luks-auto-generator.sh


#!/bin/sh
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

. /lib/dracut-lib.sh

SYSTEMD_RUN='/run/systemd/system'
CRYPTSETUP='/usr/lib/systemd/systemd-cryptsetup'
TOUT=$(getargs rd.luks.key.tout)
if [ ! -z "$TOUT" ]; then
	mkdir -p "${SYSTEMD_RUN}/luks-auto-key.service.d"
	cat > "${SYSTEMD_RUN}/luks-auto-key.service.d/drop-in.conf"  <<EOF
[Service]
Type=oneshot
ExecStartPre=/usr/bin/sleep $TOUT

EOF
fi
mkdir -p "$SYSTEMD_RUN/luks-auto.target.wants"
for argv in $(getargs rd.luks.uuid -d rd_LUKS_UUID); do
	_UUID=${argv#luks-}
	_UUID_ESC=$(systemd-escape -p $_UUID)
	mkdir -p "${SYSTEMD_RUN}/systemd-cryptsetup@luksx2d${_UUID_ESC}.service.d"
	cat > "${SYSTEMD_RUN}/systemd-cryptsetup@luksx2d${_UUID_ESC}.service.d/drop-in.conf"  <<EOF
[Unit]
After=luks-auto.target
ConditionPathExists=!/dev/mapper/luks-${_UUID}

EOF
	cat > "${SYSTEMD_RUN}/luks-auto@${_UUID_ESC}.service"  <<EOF
[Unit]
Description=luks-auto Cryptography Setup for %I
DefaultDependencies=no
Conflicts=umount.target
IgnoreOnIsolate=true
Before=luks-auto.target
BindsTo=dev-disk-byx2duuid-${_UUID_ESC}.device
After=dev-disk-byx2duuid-${_UUID_ESC}.device luks-auto-key.service
Before=umount.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=0
ExecStart=/etc/systemd/system/luks-auto.sh ${_UUID}
ExecStop=$CRYPTSETUP detach 'luks-${_UUID}'
Environment=DRACUT_SYSTEMD=1
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console

EOF
ln -fs ${SYSTEMD_RUN}/luks-auto@${_UUID_ESC}.service $SYSTEMD_RUN/luks-auto.target.wants/luks-auto@${_UUID_ESC}.service
done

/usr/lib/dracut/modules.d/99luks-auto/luks-auto-key.service


[Unit]
Description=LUKS AUTO key searcher
After=cryptsetup-pre.target
Before=luks-auto.target
DefaultDependencies=no

[Service]
Environment=DRACUT_SYSTEMD=1
Type=oneshot
ExecStartPre=/usr/bin/sleep 1
ExecStart=/etc/systemd/system/luks-auto-key.sh
RemainAfterExit=true
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console

/usr/lib/dracut/modules.d/99luks-auto/luks-auto-key.sh


#!/bin/sh
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
export DRACUT_SYSTEMD=1

. /lib/dracut-lib.sh
MNT_B="/tmp/luks-auto"
ARG=$(getargs rd.luks.key)
IFS=$':' _t=(${ARG})
KEY=${_t[0]}
F_FIELD=''
F_VALUE=''
if [ ! -z $KEY ] && [ ! -z ${_t[1]} ];then
	IFS=$'=' _t=(${_t[1]})
	F_FIELD=${_t[0]}
	F_VALUE=${_t[1]}
	F_VALUE="${F_VALUE%"}"
	F_VALUE="${F_VALUE#"}"
fi
mkdir -p $MNT_B

finding_luks_keys(){
	local _DEVNAME=''
	local _UUID=''
	local _TYPE=''
	local _LABEL=''
	local _MNT=''
	local _KEY="$1"
	local _F_FIELD="$2"
	local _F_VALUE="$3"
	local _RET=0	
	blkid -s TYPE -s UUID -s LABEL -u filesystem | grep -v -E -e "TYPE=".*_member"" -e "TYPE="crypto_.*"" -e "TYPE="swap"" | while IFS=$'' read -r _line; do
		IFS=$':' _t=($_line);
		_DEVNAME=${_t[0]}
		_UUID=''
		_TYPE=''
		_LABEL=''
		_MNT=''
		IFS=$' ' _t=(${_t[1]});
		for _a in "${_t[@]}"; do
			IFS=$'=' _v=(${_a});
			temp="${_v[1]%"}"
			temp="${temp#"}"
			case ${_v[0]} in
				'UUID')
					_UUID=$temp
				;;
				'TYPE')
					_TYPE=$temp
				;;
				'LABEL')
					_LABEL=$temp
				;;
			esac
		done
		if [ ! -z "$_F_FIELD" ];then
			case $_F_FIELD in
				'UUID')
					[ ! -z "$_F_VALUE" ] && [ "$_UUID" != "$_F_VALUE" ] && continue
				;;
				'LABEL')
					[ ! -z "$_F_VALUE" ] && [ "$_LABEL" != "$_F_VALUE" ] && continue
				;;
				*)
					[ "$_DEVNAME" != "$_F_FIELD" ] && continue
				;;
			esac
		fi
		_MNT=$(findmnt -n -o TARGET $_DEVNAME)
		if [ -z "$_MNT" ]; then
			_MNT=${MNT_B}/KEY-${_UUID}
			mkdir -p "$_MNT" && mount -o ro "$_DEVNAME" "$_MNT"
			_RET=$?
		else
			_RET=0
		fi
		if [ "${_RET}" -eq 0 ] && [ -f "${_MNT}/${_KEY}" ]; then
			cp "${_MNT}/${_KEY}" "$MNT_B/${_UUID}.key"
			info "Found ${_MNT}/${_KEY} on ${_UUID}"
		fi
		if [[ "${_MNT}" =~ "${MNT_B}" ]]; then
			umount "$_MNT" && rm -rfd --one-file-system "$_MNT"						
		fi
	done
	return 0
}
finding_luks_keys $KEY $F_FIELD $F_VALUE

/usr/lib/dracut/modules.d/99luks-auto/luks-auto.target


[Unit]
Description=LUKS AUTO target
After=systemd-readahead-collect.service systemd-readahead-replay.service
After=cryptsetup-pre.target luks-auto-key.service
Before=cryptsetup.target

/usr/lib/dracut/modules.d/99luks-auto/luks-auto.sh


#!/bin/sh
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
export DRACUT_SYSTEMD=1
. /lib/dracut-lib.sh

MNT_B="/tmp/luks-auto"
CRYPTSETUP='/usr/lib/systemd/systemd-cryptsetup'

for i in $(ls -p $MNT_B | grep -v /);do
	info "Trying $i on $1..."
	$CRYPTSETUP attach "luks-$1" "/dev/disk/by-uuid/$1" $MNT_B/$i 'tries=1'
	if [ "$?" -eq "0" ]; then
		info "Found $i for $1"
		exit 0
	fi
done
warn "No key found for $1.  Fallback to passphrase mode."

/usr/lib/dracut/modules.d/99luks-auto/luks-auto-clean.service

[Unit]
Description=LUKS AUTO key cleaner
After=cryptsetup.target
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/usr/bin/rm -rfd --one-file-system /tmp/luks-auto

/etc/dracut.conf.d/luks-auto.conf

add_dracutmodules+=" luks-auto "

ื”ืชืงื ื”


mkdir -p /usr/lib/dracut/modules.d/99luks-auto/
# ั€ะฐะทะผะตั‰ะฐะตะผ ั‚ัƒั‚ ะฟะพั‡ั‚ะธ ะฒัะต ั„ะฐะนะปั‹
chmod +x /usr/lib/dracut/modules.d/99luks-auto/*.sh
# ัะพะทะดะฐะตะผ ั„ะฐะนะป /etc/dracut.conf.d/luks-auto.conf
# ะ˜ ะณะตะฝะตั€ะธั€ัƒะตะผ ะฝะพะฒั‹ะน initramfs
dracut -f

ืžืกืงื ื”

ืžื˜ืขืžื™ ื ื•ื—ื•ืช, ืฉืžืจืชื™ ืขืœ ืชืื™ืžื•ืช ืขื ืืคืฉืจื•ื™ื•ืช ืฉื•ืจืช ื”ืคืงื•ื“ื” ืฉืœ ื”ืงืจื ืœ ื›ืžื• ืœืžืฆื‘ sysvinit, ืžื” ืฉืžืงืœ ืขืœ ื”ืฉื™ืžื•ืฉ ื‘ื”ืชืงื ื•ืช ื™ืฉื ื•ืช ื™ื•ืชืจ.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”