dracut + systemd + LUKS + usbflash = vekirina otomatîk

Çîroka wê demek dirêj berê, dema ku ew derket holê, dest pê kir. Centos 7 (RHEL 7). Heke we şîfrekirin li ser dîskan bi kar anîbe Centos 6, dema ku ajokera flash a USB bi mifteyên rast ve tê girêdan, di vekirina otomatîk a dîskan de ti pirsgirêk tunebûn. Lêbelê, bi derketina 7-an re, her tişt ji nişkê ve wekî ku dihat hêvîkirin rawestiya. Çareseriyek bi vegerandina dracut bo sysvinit bi karanîna rêzek hêsan di mîhengê de hate dîtin: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
Ya ku tavilê me ji hemî bedewiya pergalê mehrûm kir - destpêkirina bilez û paralel a karûbarên pergalê, ku bi girîngî dema destpêkirina pergalê kêm kir.
Tişt hê jî hene: 905683
Bêyî ku li benda çareseriyê bisekinim, min ew ji xwe re çêkir, û naha ez wê bi raya giştî re parve dikim, yên ku eleqedar in, bixwînin.
dracut + systemd + LUKS + usbflash = vekirina otomatîk

Pîrozbahiyê

Systemd gava min dest bi xebatê kir Centos 7-an ti heyecan çênekir, ji ber ku ji bilî guhertinek piçûk di rêzimana rêveberiya xizmetê de, min di destpêkê de zêde ferqek nedît. Di dawiyê de ez ji systemd hez kirim, lê bandora min a destpêkê hinekî ji ber wê rastiyê xera bû ku pêşdebirên dracut pir dem ji bo piştgiriya pêvajoya bootkirina systemd bi şîfrekirina dîskê re derbas nekirin. Bi gelemperî ew dixebitî, lê her gava ku min ew dest pê dikir, diviyabû şîfreya dîska xwe binivîsim. server - ne çalakiya herî balkêş.
Piştî ku komek pêşniyar ceriband û destan lêkolîn kir, min fêm kir ku di moda pergalê de veavakirina bi USB-yê gengaz e, lê tenê bi girêdana destan a her dîskê bi mifteyek li ser dîskê USB-yê re, û dîska USB bixwe tenê dikare bi wê ve girêdayî be. UUID, LABEL nexebitî. Parastina vê yekê li malê ne pir rehet bû, ji ber vê yekê di dawiyê de ez ketim nav bendê û, piştî ku hema hema 7 sal li bendê bûm, min fêm kir ku kes dê pirsgirêkê çareser neke.

Pirsgirêkên

Bê guman, hema her kes dikare pêveka xwe ji bo dracut binivîse, lê çêkirina wê êdî ne ew qas hêsan e. Derket holê ku ji ber xwezaya paralel a destpêkirina pergalê, ne ew qas hêsan e ku hûn koda xwe têxin nav xwe û pêşkeftina barkirinê biguherînin. Belgekirina ji bo dracut her tişt rave nekir. Lêbelê, piştî ceribandinên dirêj, min karî pirsgirêk çareser bikim.

Çawa dixebite

Ew li ser sê yekîneyên bingehîn e:

  1. luks-auto-key.service - li ajokarên bi keys ji bo LUKS digere
  2. luks-auto.target - ji bo yekîneyên systemd-cryptsetup-ê yên çêkirî wekî pêwendiyek tevdigere
  3. luks-auto-clean.service - pelên demkî yên ku ji hêla luks-auto-key.service ve hatine afirandin paqij dike

Û luks-auto-generator.sh skrîptek e ku ji hêla systemd ve hatî destpêkirin û li gorî pîvanên kernel yekîneyan çêdike. Generatorên bi vî rengî ji hêla yekîneyên fstab ve têne çêkirin, hwd.

luks-auto-generator.sh

Bi karanîna drop-in.conf, tevgera standard systemd-cryptsetup bi lê zêdekirina luks-auto.target li pêwendiya wan tê guhertin.

luks-auto-key.service û luks-auto-key.sh

Ev yekîn skrîpta luks-auto-key.sh dimeşîne, ku, li ser bingeha bişkokên rd.luks.*, medyaya bi kilîtan dibîne û wan ji bo karanîna bêtir li pelrêçekek demkî kopî dike. Piştî ku pêvajo qediya, mifteyên ji pelrêça demkî ji hêla luks-auto-clean.service ve têne jêbirin.

Çavkanî:

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

mîhengê


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

encamê

Ji bo rehetiyê, min lihevhatina bi vebijarkên rêzika fermana kernel re wekî moda sysvinit parastiye, ku karanîna wê di sazkirinên kevn de hêsantir dike.

Source: www.habr.com

Ji bo malperên bi parastina DDoS, serverên VPS VDS mêvandariya pêbawer bikirin 🔥 Hostinga malperê ya pêbawer bi parastina DDoS, serverên VPS VDS bikirin | ProHoster