dracut + systemd + LUKS + usbflash = desblokeo automatikoa

Istorioa aspaldi hasi zen, Centos 7 (RHEL 7) kaleratu zenean. Centos 6-rekin unitateetan enkriptatzea erabili bazenuen, ez zen arazorik izan diskoen desblokeo automatikoarekin USB flash unitate bat beharrezko gakoekin konektatzean. Hala ere, 7 kaleratu zenean, bat-batean dena ez zen funtzionatu ohituta zauden bezala. Orduan, dracut sysvinit-era itzultzeko konponbide bat aurkitzea posible zen konfigurazioko lerro soil bat erabiliz: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
Horrek berehala kendu zigun systemd-ren edertasun guztia - sistema-zerbitzuen abiarazte azkarra eta paraleloa, eta horrek nabarmen murriztu zuen sistema abiarazteko denbora.
Gauzak oraindik hor daude: 905683
Irtenbidearen zain egon gabe, nik neuk egin nuen, eta orain, interesa duen publikoarekin partekatzen ari naiz, irakurtzen jarraitu.
dracut + systemd + LUKS + usbflash = desblokeo automatikoa

Sarrera

Systemd-ek, Centos 7-rekin lanean hasi nintzenean, ez zuen emoziorik sortu, zerbitzuen kudeaketaren sintaxian aldaketa txiki bat izan ezik, hasieran ez nuen alde handirik sumatu. Gerora, systemd gustatu zitzaidan, baina lehen inpresioa apur bat hondatu zen, dracut-eko garatzaileek ez baitzuten denbora asko eman abio-prozesua onartzen systemd erabiliz disko enkriptatzearekin batera. Oro har, funtzionatu zuen, baina zerbitzaria abiarazten den bakoitzean diskoko pasahitza sartzea ez da interesgarriena.
Gomendio mordoa probatu eta eskuliburua aztertuta, konturatu nintzen systemd moduan USB bidez konfiguratzea posible dela, baina disko bakoitza USB disko batean giltza batekin eskuz elkartzearekin soilik, eta USB diskoa bera bere bidez soilik lotu daitekeela. UUID, LABEL ez zuten funtzionatu. Etxean hori mantentzea ez zen oso erosoa, beraz, azkenean itxaroten murgildu nintzen eta, ia 7 urtez itxaron ondoren, konturatu nintzen inork ez zuela arazoa konponduko.

Problems

Noski, ia edonork idatz dezake bere plugina dracut-erako, baina funtzionatzea ez da hain erraza. Agertu zen systemd abiaraztearen izaera paraleloa dela eta, ez dela hain erraza zure kodea sartzea eta kargaren aurrerapena aldatzea. Dracut-erako dokumentazioak ez zuen guztia azaltzen. Hala ere, esperimentu luzeen ostean, arazoa konpondu ahal izan nuen.

Nola dabil

Hiru unitatetan oinarritzen da:

  1. luks-auto-key.service - LUKSentzako giltzak dituzten unitateak bilatzen ditu
  2. luks-auto.target - integratutako systemd-cryptsetup unitateen menpekotasun gisa jokatzen du
  3. luks-auto-clean.service - luks-auto-key.service-k sortutako aldi baterako fitxategiak garbitzen ditu

Eta luks-auto-generator.sh systemd-ek abiarazten duen script bat da eta nukleoaren parametroetan oinarritutako unitateak sortzen ditu. Antzeko sorgailuak fstab unitateek sortzen dituzte, etab.

luks-auto-generator.sh

Drop-in.conf erabiliz, systemd-cryptsetup estandarraren portaera aldatzen da haien menpekotasunari luks-auto.target gehituz.

luks-auto-key.service eta luks-auto-key.sh

Unitate honek luks-auto-key.sh script-a exekutatzen du, zeinak, rd.luks.* gakoetan oinarrituta, gakoak dituzten euskarriak aurkitzen ditu eta behin-behineko direktorio batean kopiatzen ditu gehiago erabiltzeko. Prozesua amaitu ondoren, gakoak aldi baterako direktoriotik ezabatzen ditu luks-auto-clean.service-k.

Iturriak:

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

Instalazio-


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

Ondorioa

Erosotasunerako, nukleoko komando-lerroko aukerekin bateragarritasuna mantendu dut sysvinit modurako, eta horrek errazagoa egiten du instalazio zaharretan erabiltzeko.

Iturria: www.habr.com

Gehitu iruzkin berria