dracut + systemd + LUKS + usbflash = auto unlock

Nanomboka hatry ny ela ny tantara, rehefa navoaka ny Centos 7 (RHEL 7). Raha mampiasa encryption amin'ny fiara miaraka amin'ny Centos 6 ianao, dia tsy nisy olana tamin'ny fanokafana fiara mandeha ho azy rehefa mampifandray USB flash drive miaraka amin'ny fanalahidy ilaina. Rehefa navotsotra anefa ny 7 dia tampoka teo dia tsy nandeha araka ny nahazatra anao ny zava-drehetra. Avy eo dia azo natao ny nahita vahaolana amin'ny famerenana ny dracut amin'ny sysvinit amin'ny fampiasana tsipika tsotra ao amin'ny config: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
Izay nanala antsika avy hatrany ny hatsaran'ny systemd - fandefasana haingana sy mifanitsy amin'ny serivisy rafitra, izay nampihena be ny fotoana fanombohana ny rafitra.
Mbola misy ny zavatra: 905683
Tsy niandry vahaolana, nataoko ho an'ny tenako izany, ary izao aho mizara izany amin'ny besinimaro, izay liana, vakio.
dracut + systemd + LUKS + usbflash = auto unlock

fampidirana

Systemd, fony aho nanomboka niasa tamin'ny Centos 7, dia tsy niteraka fihetseham-po, satria ankoatra ny fiovana kely amin'ny syntax fitantanana ny serivisy, dia tsy nahatsapa fiovana firy aho tamin'ny voalohany. Taorian'izay dia tiako ny systemd, saingy ny fahatsapana voalohany dia simba kely, satria tsy nandany fotoana firy ny mpamorona dracut tamin'ny fanohanana ny fizotry ny boot mampiasa systemd miaraka amin'ny encryption disk. Amin'ny ankapobeny dia niasa izany, fa ny fampidirana ny tenimiafina kapila isaky ny manomboka ny mpizara dia tsy ny zavatra mahaliana indrindra.
Rehefa avy nanandrana tolo-kevitra maromaro aho ary nandinika ny boky, dia tsapako fa amin'ny alΓ lan'ny fanamafisana ny mode systemd miaraka amin'ny USB dia azo atao, fa miaraka amin'ny fikambanan'ny kapila tsirairay misy lakile amin'ny kapila USB ihany, ary ny kapila USB dia tsy azo ampifandraisina amin'ny azy. UUID, LABEL dia tsy nandeha. Tsy dia nety loatra ny nitazona izany tao an-trano, ka tamin'ny farany dia niandry aho ary, rehefa niandry efa ho 7 taona, dia tsapako fa tsy misy olona hamaha ny olana.

olana

Mazava ho azy fa saika ny olona rehetra dia afaka manoratra ny plugin azy manokana ho an'ny dracut, fa ny fanaovana azy io dia tsy mora intsony. Hita fa noho ny toetra mitovy amin'ny fanombohana systemd dia tsy mora ny mampiditra ny kaody anao ary manova ny fivoaran'ny entana. Ny antontan-taratasy momba ny dracut dia tsy nanazava ny zava-drehetra. Na izany aza, taorian'ny fanandramana naharitra, dia afaka namaha ilay olana aho.

Ahoana ny fomba fiasa

Izy io dia mifototra amin'ny vondrona telo:

  1. luks-auto-key.service - mikaroka fiara misy fanalahidy ho an'ny LUKS
  2. luks-auto.target - miasa toy ny fiankinan-doha ho an'ny singa systemd-cryptsetup naorina
  3. luks-auto-clean.service - manadio rakitra vonjimaika noforonin'ny luks-auto-key.service

Ary ny luks-auto-generator.sh dia script izay navoakan'ny systemd ary mamokatra singa mifototra amin'ny mari-pamantarana kernel. Ny mpamokatra mitovy amin'izany dia noforonin'ny vondrona fstab, sns.

luks-auto-generator.sh

Amin'ny fampiasana drop-in.conf, miova ny fihetsiky ny systemd-cryptsetup mahazatra amin'ny fampidirana luks-auto.target amin'ny fiankinany.

luks-auto-key.service ary luks-auto-key.sh

Ity vondrona ity dia mitantana ny script luks-auto-key.sh, izay mifototra amin'ny fanalahidin'ny rd.luks.*, mahita haino aman-jery miaraka amin'ireo fanalahidy ary mandika azy ireo any amin'ny lahatahiry vonjimaika mba hampiasaina bebe kokoa. Rehefa vita ny dingana dia voafafan'ny luks-auto-clean.service ao amin'ny lahatahiry vonjimaika ny fanalahidy.

Loharano:

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

fametrahana


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

famaranana

Ho an'ny fanamorana dia nitazona ny fifanarahana amin'ny safidy baikon'ny kernel aho toy ny amin'ny mode sysvinit, izay manamora ny fampiasana azy amin'ny fametrahana taloha.

Source: www.habr.com

Add a comment