dracut + systemd + LUKS + usbflash = muka konci otomatis

Carita dimimitian ti baheula, nalika Centos 7 (RHEL 7) dileupaskeun. Upami anjeun nganggo enkripsi dina drive sareng Centos 6, maka teu aya masalah sareng muka konci drive otomatis nalika anjeun nyambungkeun USB flash drive sareng konci anu diperyogikeun. Nanging, nalika 7 dileupaskeun, ujug-ujug sadayana henteu jalan sapertos anjeun biasa. Lajeng ieu mungkin pikeun manggihan solusi dina balik dracut mun sysvinit ngagunakeun garis basajan dina config: echo 'omit_dracutmodules+=" systemd "'> /etc/dracut.conf.d/luks-workaround.conf
Nu langsung dicabut kami tina sagala kaéndahan systemd - peluncuran saum sareng paralel tina jasa sistem, nu nyata ngurangan waktu ngamimitian sistem.
Hal-hal anu masih aya: 905683
Tanpa ngadagoan solusi, Kuring nyieun eta keur kuring sorangan, sarta ayeuna Kuring babagi deui ka publik, anu kabetot, baca on.
dracut + systemd + LUKS + usbflash = muka konci otomatis

perkenalan

Systemd, nalika kuring mimiti damel sareng Centos 7, henteu nyababkeun émosi, sabab sajaba ti parobahan minor dina sintaksis manajemén jasa, kuring henteu ngarasa bédana dina mimitina. Salajengna, kuring resep systemd, tapi gambaran kahiji éta saeutik manja, saprak pamekar dracut teu méakkeun loba waktu dina ngarojong prosés boot maké systemd ditéang jeung enkripsi disk. Sacara umum, éta digawé, tapi ngasupkeun sandi disk unggal waktos server dimimitian up teu hal paling metot.
Saatos nyobian sakumpulan rekomendasi sareng diajar manual, kuring sadar yén dina konfigurasi mode systemd sareng USB tiasa waé, tapi ngan ukur nganggo asosiasi manual unggal disk sareng konci dina disk USB, sareng disk USB nyalira ngan ukur tiasa dikaitkeun ku na. UUID, LABEL teu jalan. Henteu gampang pisan pikeun ngajaga ieu di bumi, janten tungtungna kuring ngantosan sareng, saatos ngantosan ampir 7 taun, kuring sadar yén teu aya anu bakal ngabéréskeun masalah éta.

Anu jadi masalah

Tangtosna, ampir saha waé tiasa nyerat plugins sorangan pikeun dracut, tapi ngajantenkeun éta henteu gampang pisan. Tétéla éta alatan sipat paralel tina ngamimitian systemd, teu jadi gampang pikeun ngawengku kode anjeun sarta ngarobah kamajuan loading. Dokuméntasi pikeun dracut henteu ngajelaskeun sadayana. Nanging, saatos ékspérimén anu panjang, kuring tiasa ngabéréskeun masalah éta.

Kumaha gawéna

Ieu dumasar kana tilu unit:

  1. luks-auto-key.service - milarian drive sareng konci pikeun LUKS
  2. luks-auto.target - tindakan minangka kagumantungan pikeun diwangun-di unit systemd-cryptsetup
  3. luks-auto-clean.service - ngabersihkeun file samentawis anu diciptakeun ku luks-auto-key.service

Sareng luks-auto-generator.sh mangrupikeun naskah anu diluncurkeun ku systemd sareng ngahasilkeun unit dumasar kana parameter kernel. Generators sarupa dijieun ku unit fstab, jsb.

luks-auto-generator.sh

Ngagunakeun drop-in.conf, paripolah systemd-cryptsetup standar dirobah ku nambahkeun luks-auto.target kana kagumantungan maranéhna.

luks-auto-key.service jeung luks-auto-key.sh

Unit ieu ngajalankeun naskah luks-auto-key.sh, nu dumasar kana rd.luks.* kenop, manggihan média jeung kenop na nyalin kana diréktori samentara pikeun pamakéan salajengna. Saatos prosés réngsé, konci dihapus tina diréktori samentawis ku luks-auto-clean.service.

Sumber:

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

setting


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

kacindekan

Pikeun genah, Kuring geus mertahankeun kasaluyuan jeung pilihan garis paréntah kernel sakumaha keur mode sysvinit, nu matak ngamudahkeun pikeun pamakéan dina pamasangan heubeul.

sumber: www.habr.com

Tambahkeun komentar