dracut + systemd + LUKS + usbflash = ಸ್ವಯಂ ಅನ್‌ಲಾಕ್

ಕಥೆಯು ಬಹಳ ಹಿಂದೆಯೇ ಪ್ರಾರಂಭವಾಯಿತು, ಸೆಂಟೋಸ್ 7 (RHEL 7) ಬಿಡುಗಡೆಯಾದಾಗ. ನೀವು ಸೆಂಟೋಸ್ 6 ನೊಂದಿಗೆ ಡ್ರೈವ್‌ಗಳಲ್ಲಿ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಅನ್ನು ಬಳಸಿದ್ದರೆ, ನೀವು ಯುಎಸ್‌ಬಿ ಫ್ಲ್ಯಾಷ್ ಡ್ರೈವ್ ಅನ್ನು ಅಗತ್ಯ ಕೀಗಳೊಂದಿಗೆ ಸಂಪರ್ಕಿಸಿದಾಗ ಡ್ರೈವ್‌ಗಳ ಸ್ವಯಂಚಾಲಿತ ಅನ್‌ಲಾಕಿಂಗ್‌ನಲ್ಲಿ ಯಾವುದೇ ಸಮಸ್ಯೆಗಳಿಲ್ಲ. ಆದಾಗ್ಯೂ, 7 ಬಿಡುಗಡೆಯಾದಾಗ, ಇದ್ದಕ್ಕಿದ್ದಂತೆ ಎಲ್ಲವೂ ನೀವು ಬಳಸಿದಂತೆ ಕೆಲಸ ಮಾಡಲಿಲ್ಲ. ನಂತರ ಸಂರಚನೆಯಲ್ಲಿನ ಸರಳ ರೇಖೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಡ್ರಾಕಟ್ ಅನ್ನು sysvinit ಗೆ ಹಿಂತಿರುಗಿಸುವಲ್ಲಿ ಪರಿಹಾರವನ್ನು ಕಂಡುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಯಿತು: echo ‘omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
ಇದು systemd ನ ಎಲ್ಲಾ ಸೌಂದರ್ಯವನ್ನು ತಕ್ಷಣವೇ ನಮಗೆ ವಂಚಿತಗೊಳಿಸಿತು - ಸಿಸ್ಟಮ್ ಸೇವೆಗಳ ವೇಗದ ಮತ್ತು ಸಮಾನಾಂತರ ಉಡಾವಣೆ, ಇದು ಸಿಸ್ಟಮ್ ಪ್ರಾರಂಭದ ಸಮಯವನ್ನು ಗಮನಾರ್ಹವಾಗಿ ಕಡಿಮೆ ಮಾಡುತ್ತದೆ.
ವಿಷಯಗಳು ಇನ್ನೂ ಇವೆ: 905683
ಪರಿಹಾರಕ್ಕಾಗಿ ಕಾಯದೆ, ನಾನು ಅದನ್ನು ನನಗಾಗಿ ಮಾಡಿದ್ದೇನೆ ಮತ್ತು ಈಗ ನಾನು ಅದನ್ನು ಸಾರ್ವಜನಿಕರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೇನೆ, ಆಸಕ್ತರು, ಓದಿ.
dracut + systemd + LUKS + usbflash = ಸ್ವಯಂ ಅನ್‌ಲಾಕ್

ಪರಿಚಯ

Systemd, ನಾನು ಮೊದಲು Centos 7 ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿದಾಗ, ಯಾವುದೇ ಭಾವನೆಗಳನ್ನು ಉಂಟುಮಾಡಲಿಲ್ಲ, ಏಕೆಂದರೆ ಸೇವಾ ನಿರ್ವಹಣಾ ಸಿಂಟ್ಯಾಕ್ಸ್‌ನಲ್ಲಿ ಸಣ್ಣ ಬದಲಾವಣೆಯನ್ನು ಹೊರತುಪಡಿಸಿ, ನಾನು ಮೊದಲಿಗೆ ಹೆಚ್ಚಿನ ವ್ಯತ್ಯಾಸವನ್ನು ಅನುಭವಿಸಲಿಲ್ಲ. ತರುವಾಯ, ನಾನು systemd ಅನ್ನು ಇಷ್ಟಪಟ್ಟೆ, ಆದರೆ ಮೊದಲ ಅನಿಸಿಕೆ ಸ್ವಲ್ಪ ಹಾಳಾಗಿದೆ, ಏಕೆಂದರೆ ಡ್ರಾಕಟ್ ಡೆವಲಪರ್‌ಗಳು ಡಿಸ್ಕ್ ಎನ್‌ಕ್ರಿಪ್ಶನ್‌ನೊಂದಿಗೆ systemd ಅನ್ನು ಬಳಸಿಕೊಂಡು ಬೂಟ್ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಬೆಂಬಲಿಸಲು ಹೆಚ್ಚು ಸಮಯವನ್ನು ಕಳೆಯಲಿಲ್ಲ. ಸಾಮಾನ್ಯವಾಗಿ, ಇದು ಕೆಲಸ ಮಾಡಿದೆ, ಆದರೆ ಸರ್ವರ್ ಪ್ರಾರಂಭವಾದಾಗಲೆಲ್ಲಾ ಡಿಸ್ಕ್ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸುವುದು ಅತ್ಯಂತ ಆಸಕ್ತಿದಾಯಕ ವಿಷಯವಲ್ಲ.
ಹಲವಾರು ಶಿಫಾರಸುಗಳನ್ನು ಪ್ರಯತ್ನಿಸಿದ ನಂತರ ಮತ್ತು ಕೈಪಿಡಿಯನ್ನು ಅಧ್ಯಯನ ಮಾಡಿದ ನಂತರ, ಸಿಸ್ಟಮ್‌ಡ್ ಮೋಡ್‌ನಲ್ಲಿ ಯುಎಸ್‌ಬಿಯೊಂದಿಗೆ ಕಾನ್ಫಿಗರೇಶನ್ ಸಾಧ್ಯ ಎಂದು ನಾನು ಅರಿತುಕೊಂಡೆ, ಆದರೆ ಯುಎಸ್‌ಬಿ ಡಿಸ್ಕ್‌ನಲ್ಲಿನ ಕೀಲಿಯೊಂದಿಗೆ ಪ್ರತಿ ಡಿಸ್ಕ್‌ನ ಹಸ್ತಚಾಲಿತ ಸಂಯೋಜನೆಯೊಂದಿಗೆ ಮಾತ್ರ, ಮತ್ತು ಯುಎಸ್‌ಬಿ ಡಿಸ್ಕ್ ಅನ್ನು ಅದರ ಮೂಲಕ ಮಾತ್ರ ಸಂಯೋಜಿಸಬಹುದು UUID, LABEL ಕೆಲಸ ಮಾಡಲಿಲ್ಲ. ಮನೆಯಲ್ಲಿ ಇದನ್ನು ನಿರ್ವಹಿಸುವುದು ತುಂಬಾ ಅನುಕೂಲಕರವಾಗಿಲ್ಲ, ಆದ್ದರಿಂದ ಕೊನೆಯಲ್ಲಿ ನಾನು ಕಾಯುವಲ್ಲಿ ಮುಳುಗಿದೆ ಮತ್ತು ಸುಮಾರು 7 ವರ್ಷಗಳ ಕಾಲ ಕಾಯುವ ನಂತರ, ಯಾರೂ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಹೋಗುತ್ತಿಲ್ಲ ಎಂದು ನಾನು ಅರಿತುಕೊಂಡೆ.

ತೊಂದರೆಗಳು

ಸಹಜವಾಗಿ, ಡ್ರಾಕಟ್‌ಗಾಗಿ ಬಹುತೇಕ ಯಾರಾದರೂ ತಮ್ಮದೇ ಆದ ಪ್ಲಗಿನ್ ಅನ್ನು ಬರೆಯಬಹುದು, ಆದರೆ ಅದನ್ನು ಕೆಲಸ ಮಾಡುವುದು ಇನ್ನು ಮುಂದೆ ಅಷ್ಟು ಸುಲಭವಲ್ಲ. systemd ಸ್ಟಾರ್ಟ್‌ಅಪ್‌ನ ಸಮಾನಾಂತರ ಸ್ವಭಾವದಿಂದಾಗಿ, ನಿಮ್ಮ ಕೋಡ್ ಅನ್ನು ಸೇರಿಸುವುದು ಮತ್ತು ಲೋಡಿಂಗ್ ಪ್ರಗತಿಯನ್ನು ಬದಲಾಯಿಸುವುದು ಅಷ್ಟು ಸುಲಭವಲ್ಲ ಎಂದು ಅದು ಬದಲಾಯಿತು. ಡ್ರಾಕಟ್‌ಗಾಗಿ ದಸ್ತಾವೇಜನ್ನು ಎಲ್ಲವನ್ನೂ ವಿವರಿಸಲಿಲ್ಲ. ಆದಾಗ್ಯೂ, ಸುದೀರ್ಘ ಪ್ರಯೋಗಗಳ ನಂತರ, ನಾನು ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಸಾಧ್ಯವಾಯಿತು.

ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ

ಇದು ಮೂರು ಘಟಕಗಳನ್ನು ಆಧರಿಸಿದೆ:

  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 ಎನ್ನುವುದು systemd ನಿಂದ ಪ್ರಾರಂಭಿಸಲಾದ ಸ್ಕ್ರಿಪ್ಟ್ ಆಗಿದೆ ಮತ್ತು ಕರ್ನಲ್ ನಿಯತಾಂಕಗಳನ್ನು ಆಧರಿಸಿ ಘಟಕಗಳನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ. ಇದೇ ರೀತಿಯ ಜನರೇಟರ್‌ಗಳನ್ನು 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.* ಕೀಗಳನ್ನು ಆಧರಿಸಿ, ಕೀಗಳೊಂದಿಗೆ ಮಾಧ್ಯಮವನ್ನು ಹುಡುಕುತ್ತದೆ ಮತ್ತು ಹೆಚ್ಚಿನ ಬಳಕೆಗಾಗಿ ಅವುಗಳನ್ನು ತಾತ್ಕಾಲಿಕ ಡೈರೆಕ್ಟರಿಗೆ ನಕಲಿಸುತ್ತದೆ. ಪ್ರಕ್ರಿಯೆಯು ಪೂರ್ಣಗೊಂಡ ನಂತರ, 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

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ