dracut + systemd + LUKS + usbflash = díghlasáil uathoibríoch

Thosaigh an scéal i bhfad ó shin, ar ais nuair a scaoileadh Centos 7 (RHEL 7). Má d'úsáid tú criptiú ar thiomáineann le Centos 6, ní raibh aon fhadhbanna ann maidir le tiomántáin a dhíghlasáil go huathoibríoch nuair a cheangail tú tiomántán USB flash leis na heochracha riachtanacha. Mar sin féin, nuair a scaoileadh 7, go tobann níor oibrigh gach rud mar a bhí taithí agat. Ansin bhíothas in ann teacht ar réiteach maidir le dracut a chur ar ais chuig sysvinit ag baint úsáide as líne shimplí sa chumraíocht: macalla 'omit_dracutmodules+=" systemd"> /etc/dracut.conf.d/luks-workaround.conf
Rud a thug láithreach dúinn áilleacht na systemd - seoladh go tapa agus comhthreomhar seirbhísí córais, rud a laghdaigh go suntasach am tosaithe an chórais.
Tá rudaí fós ann: 905683
Gan fanacht le réiteach, rinne mé dom féin é, agus anois tá mé á roinnt leis an bpobal, a bhfuil suim acu, léigh ar aghaidh.
dracut + systemd + LUKS + usbflash = díghlasáil uathoibríoch

Réamhrá

Systemd, nuair a thosaigh mé ag obair le Centos 7 den chéad uair, níor thug sé faoi deara aon mhothúcháin, ós rud é seachas mionathrú ar chomhréir na bainistíochta seirbhíse, níor mhothaigh mé mórán difríochta ar dtús. Ina dhiaidh sin, thaitin systemd liom, ach bhí an chéad tuiscint beagán millte, ós rud é nár chaith na forbróirí dracut mórán ama ag tacú leis an bpróiseas tosaithe ag baint úsáide as systemd i gcomhar le criptiú diosca. Go ginearálta, d'oibrigh sé, ach ag dul isteach an focal faire diosca gach uair a thosaíonn an freastalaí suas nach bhfuil an rud is suimiúla.
Tar éis triail a bhaint as a lán moltaí agus staidéar a dhéanamh ar an lámhleabhar, thuig mé go bhfuil cumraíocht mód sistem le USB indéanta, ach amháin le comhlachas láimhe gach diosca le eochair ar dhiosca USB, agus ní féidir leis an diosca USB féin a bheith bainteach ach lena UUID, níor oibrigh LABEL. Ní raibh sé an-áisiúil é seo a choinneáil sa bhaile, agus mar sin sa deireadh chuaigh mé isteach ag fanacht agus, tar éis fanacht beagnach 7 mbliana, thuig mé nach raibh aon duine chun an fhadhb a réiteach.

Fadhbanna

Ar ndóigh, is féidir le beagnach duine ar bith a mbreiseán féin a scríobh le haghaidh dracut, ach níl sé chomh héasca sin é a oibriú. Iompaigh sé amach, mar gheall ar nádúr comhthreomhar tosaithe systemd, nach bhfuil sé chomh éasca a chur san áireamh do chód agus athrú ar an dul chun cinn luchtaithe. Níor mhínigh na doiciméid le haghaidh dracut gach rud. Mar sin féin, tar éis turgnaimh fhada, bhí mé in ann an fhadhb a réiteach.

Conas a oibríonn sé

Tá sé bunaithe ar thrí aonad:

  1. luks-auto-key.service - cuardaigh tiomántáin le heochracha do LUKS
  2. luks-auto.target - feidhmíonn sé mar spleáchas d'aonaid systemd-cryptsetup ionsuite
  3. luks-auto-clean.service - glanann comhaid shealadacha cruthaithe ag luks-auto-key.service

Agus is script é luks-auto-generator.sh a sheolann systemd agus a ghineann aonaid bunaithe ar pharaiméadair eithne. Cruthaítear gineadóirí cosúla le haonaid fstab, etc.

luks-auto-generator.sh

Ag baint úsáide as drop-in.conf, athraítear iompar córas caighdeánach-cryptsetup trí luks-auto.target a chur lena spleáchas.

luks-auto-key.service agus luks-auto-key.sh

Ritheann an t-aonad seo an script luks-auto-key.sh, a aimsíonn, bunaithe ar na heochracha rd.luks.*, meáin leis na heochracha agus déanann sé iad a chóipeáil chuig eolaire sealadach le haghaidh tuilleadh úsáide. Tar éis an próiseas a bheith críochnaithe, scriostar na heochracha ón eolaire sealadach ag luks-auto-clean.service.

Foinsí:

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

Suiteáil


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

Conclúid

Ar mhaithe le caoithiúlacht, choinnigh mé comhoiriúnacht le roghanna na n-orduithe eithne agus leis an modh sysvinit, rud a fhágann go bhfuil sé níos éasca é a úsáid i suiteálacha níos sine.

Foinse: will.com

Add a comment