dracut + systemd + LUKS + usbflash = kufungua kiotomatiki

Hadithi ilianza muda mrefu uliopita, wakati ilipotolewa. Centos 7 (RHEL 7). Kama ulitumia usimbaji fiche kwenye diski zenye Centos 6, hakukuwa na matatizo ya kufungua diski kiotomatiki wakati wa kuunganisha kiendeshi cha USB flash kwa kutumia funguo sahihi. Hata hivyo, baada ya kutolewa kwa 7, kila kitu kiliacha kufanya kazi ghafla kama ilivyotarajiwa. Suluhisho lilipatikana kwa kurudisha dracut kwenye sysvinit kwa kutumia mstari rahisi katika usanidi: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
Ambayo mara moja ilitunyima uzuri wote wa systemd - uzinduzi wa haraka na sambamba wa huduma za mfumo, ambayo ilipunguza kwa kiasi kikubwa wakati wa kuanzisha mfumo.
Mambo bado yapo: 905683
Bila kungoja suluhisho, nilijifanyia mwenyewe, na sasa ninashiriki na umma, ambao wana nia, soma.
dracut + systemd + LUKS + usbflash = kufungua kiotomatiki

Utangulizi

Systemd nilipoanza kufanya kazi na Centos 7 haikuamsha msisimko wowote, kwani mbali na mabadiliko madogo katika sintaksia ya usimamizi wa huduma, sikugundua tofauti kubwa mwanzoni. Hatimaye nilianza kupenda systemd, lakini hisia yangu ya awali ilichafuliwa kidogo na ukweli kwamba watengenezaji wa dracut hawakutumia muda mwingi kusaidia mchakato wa kuwasha systemd pamoja na usimbaji fiche wa diski. Ilifanya kazi kwa ujumla, lakini ilinibidi kuingiza nenosiri langu la diski kila nilipoianzisha. seva β€” si shughuli ya kuvutia zaidi.
Baada ya kujaribu rundo la mapendekezo na kusoma mwongozo, niligundua kuwa katika usanidi wa hali ya mfumo na USB inawezekana, lakini tu kwa ushirika wa mwongozo wa kila diski na ufunguo kwenye diski ya USB, na diski ya USB yenyewe inaweza tu kuhusishwa na yake. UUID, LABEL haikufanya kazi. Haikuwa rahisi sana kudumisha hii nyumbani, kwa hivyo mwishowe niliingia kwenye kungojea na, baada ya kungoja kwa karibu miaka 7, niligundua kuwa hakuna mtu ambaye angesuluhisha shida hiyo.

Shida

Kwa kweli, karibu mtu yeyote anaweza kuandika programu-jalizi yake mwenyewe kwa dracut, lakini kuifanya ifanye kazi sio rahisi tena. Ilibadilika kuwa kwa sababu ya asili sambamba ya uanzishaji wa mfumo, sio rahisi sana kujumuisha nambari yako na kubadilisha maendeleo ya upakiaji. Nyaraka za rasimu hazikuelezea kila kitu. Hata hivyo, baada ya majaribio ya muda mrefu, niliweza kutatua tatizo.

Inafanyaje kazi

Ni kwa msingi wa vitengo vitatu:

  1. luks-auto-key.service - hutafuta viendeshi vilivyo na funguo za LUKS
  2. luks-auto.target - hufanya kama tegemezi kwa vitengo vya kusanidi vya mfumo wa ndani
  3. luks-auto-clean.service - husafisha faili za muda iliyoundwa na luks-auto-key.service

Na luks-auto-generator.sh ni hati ambayo imezinduliwa na systemd na hutoa vitengo kulingana na vigezo vya kernel. Jenereta zinazofanana zinaundwa na vitengo vya fstab, nk.

luks-auto-generator.sh

Kwa kutumia drop-in.conf, tabia ya usanidi wa kawaida wa systemd-cryptset hubadilishwa kwa kuongeza luks-auto.target kwa utegemezi wao.

luks-auto-key.service na luks-auto-key.sh

Kitengo hiki huendesha hati ya luks-auto-key.sh, ambayo, kulingana na vitufe vya rd.luks.*, hupata midia yenye funguo na kuinakili kwenye saraka ya muda kwa matumizi zaidi. Baada ya mchakato kukamilika, funguo zinafutwa kutoka kwa saraka ya muda na luks-auto-clean.service.

Vyanzo:

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

Ufungaji


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

Hitimisho

Kwa urahisi, nimedumisha utangamano na chaguzi za mstari wa amri ya kernel kama hali ya sysvinit, ambayo hurahisisha kutumia katika usakinishaji wa zamani.

Chanzo: mapenzi.com

Nunua upangishaji wa kuaminika wa tovuti zilizo na ulinzi wa DDoS, seva za VPS VDS πŸ”₯ Nunua upangishaji wa tovuti unaoaminika kwa ulinzi wa DDoS, seva za VPS VDS | ProHoster