dracut + systemd + LUKS + usbflash = datgloi auto

Dechreuodd y stori amser maith yn ôl, yn ôl pan ryddhawyd Centos 7 (RHEL 7). Os gwnaethoch ddefnyddio amgryptio ar yriannau gyda Centos 6, yna nid oedd unrhyw broblemau gyda datgloi gyriannau'n awtomatig pan wnaethoch chi gysylltu gyriant fflach USB gyda'r allweddi angenrheidiol. Fodd bynnag, pan ryddhawyd 7, yn sydyn ni weithiodd popeth fel yr oeddech wedi arfer ag ef. Yna roedd yn bosibl dod o hyd i ateb wrth ddychwelyd dracut i sysvinit gan ddefnyddio llinell syml yn y ffurfwedd: adlais ‘omit_dracutmodules+=" systemd"> /etc/dracut.conf.d/luks-workaround.conf
Sydd ar unwaith yn ein hamddifadu o holl harddwch systemd - lansiad cyflym a chyfochrog o wasanaethau system, a oedd yn lleihau amser cychwyn system yn sylweddol.
Mae pethau dal yno: 905683
Heb aros am ateb, fe'i gwnes i mi fy hun, a nawr rydw i'n ei rannu gyda'r cyhoedd, sydd â diddordeb, darllenwch ymlaen.
dracut + systemd + LUKS + usbflash = datgloi auto

Cyflwyniad

Nid oedd Systemd, pan ddechreuais weithio gyda Centos 7 gyntaf, yn achosi unrhyw emosiynau, oherwydd ar wahân i fân newid yn y gystrawen rheoli gwasanaeth, nid oeddwn yn teimlo llawer o wahaniaeth ar y dechrau. Yn dilyn hynny, roeddwn i'n hoffi systemd, ond roedd yr argraff gyntaf wedi'i difetha ychydig, gan nad oedd y datblygwyr dracut yn treulio llawer o amser ar gefnogi'r broses gychwyn gan ddefnyddio systemd ar y cyd ag amgryptio disg. Yn gyffredinol, fe weithiodd, ond nid mynd i mewn i gyfrinair y ddisg bob tro y bydd y gweinydd yn cychwyn yw'r peth mwyaf diddorol.
Ar ôl rhoi cynnig ar griw o argymhellion ac astudio'r llawlyfr, sylweddolais fod cyfluniad modd systemd â USB yn bosibl, ond dim ond gyda chysylltiad â llaw o bob disg gydag allwedd ar ddisg USB, a dim ond trwy ei hun y gellir cysylltu'r ddisg USB ei hun. UUID, ni weithiodd LABEL. Nid oedd yn gyfleus iawn i gynnal hyn gartref, felly yn y diwedd blymiais i aros ac, ar ôl aros am bron i 7 mlynedd, sylweddolais nad oedd neb yn mynd i ddatrys y broblem.

Problemau

Wrth gwrs, gall bron unrhyw un ysgrifennu eu ategyn eu hunain ar gyfer dracut, ond nid yw gwneud iddo weithio mor hawdd mwyach. Daeth i'r amlwg, oherwydd natur gyfochrog cychwyn systemd, nad yw mor hawdd cynnwys eich cod a newid y cynnydd llwytho. Nid oedd y ddogfennaeth ar gyfer dracut yn esbonio popeth. Fodd bynnag, ar ôl arbrofion hir, llwyddais i ddatrys y broblem.

Sut mae'n gweithio

Mae'n seiliedig ar dair uned:

  1. luks-auto-key.service - yn chwilio am yriannau ag allweddi ar gyfer LUKS
  2. luks-auto.target - yn gweithredu fel dibyniaeth ar gyfer unedau systemd-cryptsetup adeiledig
  3. luks-auto-clean.service - glanhau ffeiliau dros dro a grëwyd gan luks-auto-key.service

Ac mae luks-auto-generator.sh yn sgript sy'n cael ei lansio gan systemd ac sy'n cynhyrchu unedau yn seiliedig ar baramedrau cnewyllyn. Mae generaduron tebyg yn cael eu creu gan unedau fstab, ac ati.

luks-auto-generator.sh

Gan ddefnyddio drop-in.conf, mae ymddygiad systemd-cryptsetup safonol yn cael ei newid trwy ychwanegu luks-auto.target at eu dibyniaeth.

luks-auto-key.service a luks-auto-key.sh

Mae'r uned hon yn rhedeg y sgript luks-auto-key.sh, sydd, yn seiliedig ar y bysellau rd.luks.*, yn dod o hyd i gyfryngau gyda'r allweddi ac yn eu copïo i gyfeiriadur dros dro i'w ddefnyddio ymhellach. Ar ôl i'r broses gael ei chwblhau, caiff yr allweddi eu dileu o'r cyfeiriadur dros dro gan luks-auto-clean.service.

Ffynonellau:

/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 "

Gosod


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

Casgliad

Er hwylustod, rwyf wedi cynnal cydnawsedd ag opsiynau llinell orchymyn cnewyllyn ag ar gyfer modd sysvinit, sy'n ei gwneud hi'n haws ei ddefnyddio mewn gosodiadau hŷn.

Ffynhonnell: hab.com

Ychwanegu sylw