dracut + systemd + LUKS + usbflash = خودڪار کوليو

ڪهاڻي هڪ ڊگهو وقت اڳ شروع ٿيو، واپس جڏهن Centos 7 (RHEL 7) جاري ڪيو ويو. جيڪڏهن توهان Centos 6 سان ڊرائيو تي انڪرپشن استعمال ڪيو، ته پوءِ جڏهن توهان ضروري چاٻين سان USB فليش ڊرائيو کي ڳنڍيو ته ڊرائيو جي خودڪار انلاڪنگ سان ڪو مسئلو نه هو. بهرحال، جڏهن 7 جاري ڪيو ويو، اوچتو هر شيء ڪم نه ڪيو جيئن توهان استعمال ڪيو ويو. ان کان پوء اهو ممڪن هو ته ڊراڪٽ کي واپسي ۾ sysvinit ڏانهن واپسي ۾ هڪ سادي لائن استعمال ڪندي ترتيب ۾ هڪ حل ڳولڻ: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
جنهن اسان کي فوري طور تي سسٽم جي تمام خوبصورتي کان محروم ڪري ڇڏيو - سسٽم سروسز جي تيز ۽ متوازي لانچ، جنهن ۾ سسٽم جي شروعات جو وقت تمام گهڻو گهٽجي ويو.
شيون اڃا تائين موجود آهن: 905683
بغير ڪنهن حل جي انتظار جي، مون ان کي پنهنجي لاءِ ٺاهيو، ۽ هاڻي مان ان کي عوام سان شيئر ڪري رهيو آهيان، جيڪي دلچسپي رکن ٿا، پڙهو.
dracut + systemd + LUKS + usbflash = خودڪار کوليو

تعارف

سسٽمڊ، جڏهن مون پهريون ڀيرو Centos 7 سان ڪم ڪرڻ شروع ڪيو، ڪنهن به جذبات جو سبب نه بڻيو، ڇاڪاڻ ته سروس مئنيجمينٽ نحو ۾ هڪ معمولي تبديلي کان سواء، مون پهرين ۾ گهڻو فرق محسوس نه ڪيو. ان کان پوء، مون کي پسند ڪيو systemd، پر پهريون تاثر ٿورڙو خراب ٿي ويو، ڇاڪاڻ ته ڊراڪٽ ڊولپرز بوٽ پروسيس کي سپورٽ ڪرڻ تي گهڻو وقت نه گذاريو آهي سسٽم ڊي ڊسڪ انڪرپشن سان گڏ استعمال ڪندي. عام طور تي، اهو ڪم ڪيو، پر ڊسڪ پاسورڊ داخل ڪرڻ هر وقت سرور شروع ٿئي ٿو تمام دلچسپ شيء ناهي.
سفارشن جي هڪ گروپ جي ڪوشش ڪرڻ ۽ دستي جو مطالعو ڪرڻ بعد، مون محسوس ڪيو ته سسٽم موڊ ۾ يو ايس بي سان ترتيب ڏيڻ ممڪن آهي، پر صرف هر ڊسڪ جي دستي ايسوسيئيشن سان گڏ هڪ USB ڊسڪ تي چاٻي سان، ۽ USB ڊسڪ پاڻ کي صرف ان سان لاڳاپيل ڪري سگهجي ٿو. UUID، LABEL ڪم نه ڪيو. اهو گهر ۾ برقرار رکڻ بلڪل آسان نه هو، تنهنڪري آخر ۾ مون انتظار ۾ پئجي ويو ۽ تقريبا 7 سالن جي انتظار کان پوء، مون محسوس ڪيو ته ڪو به مسئلو حل ڪرڻ وارو نه هو.

پريشاني

يقينن، تقريبن هرڪو پنهنجو پلگ ان ڊراڪٽ لاءِ لکي سگهي ٿو، پر اهو ڪم ڪرڻ هاڻي ايترو آسان ناهي رهيو. اهو ظاهر ٿيو ته سسٽم جي شروعات جي متوازي نوعيت جي ڪري، توهان جو ڪوڊ شامل ڪرڻ ۽ لوڊشيڊنگ جي ترقي کي تبديل ڪرڻ ايترو آسان ناهي. dracut لاء دستاويز سڀڪنھن شيء کي بيان نه ڪيو. بهرحال، ڊگهي تجربن کان پوء، مون کي مسئلو حل ڪرڻ جي قابل ٿي ويو.

اهو ڪيئن ڪم ڪري ٿو

اهو ٽن يونٽن تي ٻڌل آهي:

  1. luks-auto-key.service - LUKS لاءِ چاٻين سان ڊرائيو ڳولي ٿو
  2. luks-auto.target - تعمير ٿيل systemd-cryptsetup يونٽن لاءِ انحصار جي طور تي ڪم ڪري ٿو
  3. luks-auto-clean.service- luks-auto-key.service پاران ٺاهيل عارضي فائلن کي صاف ڪري ٿو

۽ luks-auto-generator.sh هڪ اسڪرپٽ آهي جيڪو سسٽم ڊي پاران شروع ڪيو ويو آهي ۽ ڪنيل پيٽرولر جي بنياد تي يونٽ ٺاهي ٿو. ساڳيا جنريٽر ٺاهيا ويا آهن fstab يونٽ وغيره.

luks-auto-generator.sh

drop-in.conf استعمال ڪندي، معياري systemd-cryptsetup جو رويو تبديل ڪيو ويندو آهي luks-auto.target کي شامل ڪندي انهن جي انحصار ۾.

luks-auto-key.service ۽ luks-auto-key.sh

هي يونٽ هلندي آهي luks-auto-key.sh اسڪرپٽ، جيڪا rd.luks.* keys جي بنياد تي، ميڊيا کي چاٻين سان ڳولهي ٿي ۽ انهن کي وڌيڪ استعمال لاءِ عارضي ڊاريڪٽري ۾ نقل ڪري ٿي. عمل مڪمل ٿيڻ کان پوء، چابيون عارضي ڊاريڪٽري مان ڊهي وينديون آهن luks-auto-clean.service.

ذريعن:

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

تنصيب


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

ٿڪل

سهولت لاءِ، مون ڪنيل ڪمانڊ لائن آپشنز سان مطابقت برقرار رکي آهي جيئن sysvinit موڊ لاءِ، جيڪا پراڻن انسٽاليشن ۾ استعمال ڪرڻ آسان بڻائي ٿي.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو