Historia nisi shumĂ« kohĂ« mĂ« parĂ«, qĂ« me daljen e CentOS 7 (RHEL 7). NĂ«se pĂ«rdornit enkriptim nĂ« disqe me CentOS 6, nuk kishte asnjĂ« problem me zhbllokimin automatik tĂ« disqeve kur lidhej njĂ« USB flash me çelĂ«sat e duhur. MegjithatĂ«, me daljen e versionit 7, papritur gjithçka pushoi sĂ« funksionuari siç ishit mĂ«suar. AtĂ«herĂ« zgjidhja mund tĂ« gjendej duke rikthyer dracut te sysvinit me njĂ« rresht tĂ« thjeshtĂ« nĂ« konfigurim: echo âomit_dracutmodules+=" systemd "â > /etc/dracut.conf.d/luks-workaround.conf
Kjo na privonte menjĂ«herĂ« nga tĂ« gjitha avantazhet e systemd â nisja e shpejtĂ« dhe paralele e shĂ«rbimeve tĂ« sistemit, qĂ« e shkurton ndjeshĂ«m kohĂ«n e nisjes sĂ« sistemit.
Dhe situata mbetet po ajo:
Pa pritur më për një zgjidhje, e bëra vetë për vete, dhe tani po e ndaj edhe me të tjerët. Nëse ju intereson, vazhdoni leximin.

Hyrje
Kur fillova tĂ« punoja me CentOS 7, Systemd nuk mĂ« ngjalli ndonjĂ« emocion tĂ« veçantĂ«, sepse pĂ«rveç njĂ« ndryshimi tĂ« vogĂ«l nĂ« sintaksĂ«n e menaxhimit tĂ« shĂ«rbimeve, fillimisht nuk vura re ndonjĂ« dallim tĂ« madh. MĂ« vonĂ« systemd filloi tĂ« mĂ« pĂ«lqente, por pĂ«rshtypja e parĂ« mbeti disi e zbehur, sepse zhvilluesit e dracut nuk i kushtonin shumĂ« vĂ«mendje mbĂ«shtetjes sĂ« procesit tĂ« nisjes me systemd nĂ« kombinim me enkriptimin e disqeve. NĂ« pĂ«rgjithĂ«si funksiononte, por tĂ« fusje fjalĂ«kalimin e diskut nĂ« çdo nisje serverĂ« â nuk Ă«shtĂ« aspak aktiviteti mĂ« tĂ«rheqĂ«s.
Pasi provova një mori rekomandimesh dhe lexova me kujdes manualin, kuptova se në regjimin systemd është i mundur konfigurimi me USB, por vetëm me asociim manual të çdo disku me çelësin në diskun USB; për më tepër, vetë disku USB mund të lidhej vetëm përmes UUID-së së tij, ndërsa LABEL nuk funksiononte. Mirëmbajtja e një konfigurimi të tillë nuk ishte fort praktike, prandaj në fund mbeta në pritje dhe, pasi prita gati 7 vjet, e kuptova: askush nuk kishte ndërmend ta zgjidhte problemin.
Problemet
Sigurisht, pothuajse kushdo mund të shkruajë një plugin të vetin për dracut, por ta bësh realisht funksional nuk është aq e thjeshtë. Doli se, për shkak të natyrës paralele të nisjes së systemd, nuk është edhe aq e lehtë të përfshish kodin tënd dhe të ndryshosh rrjedhën e nisjes. Dokumentacioni i dracut nuk i shpjegonte të gjitha. Megjithatë, falë eksperimenteve të gjata, arrita ta zgjidh problemin.
Si funksionon
Në bazë janë tre njësi:
- luks-auto-key.service â kĂ«rkon pajisje ruajtĂ«se me çelĂ«sa pĂ«r LUKS
- luks-auto.target â shĂ«rben si varĂ«si pĂ«r njĂ«sitĂ« e integruara systemd-cryptsetup
- luks-auto-clean.service â pastron skedarĂ«t e pĂ«rkohshĂ«m tĂ« krijuar nga luks-auto-key.service
Dhe luks-auto-generator.sh është një skript që niset nga systemd dhe gjeneron unit-e bazuar në parametrat e kernelit. Gjeneratorë të ngjashëm krijojnë unit-e për fstab etj.
luks-auto-generator.sh
Me drop-in.conf ndryshohet sjellja e systemd-cryptsetup standard, duke u shtuar si varësi luks-auto.target.
luks-auto-key.service dhe luks-auto-key.sh
Ky unit nis skriptin luks-auto-key.sh, i cili, duke u bazuar në çelësat rd.luks.*, gjen pajisjet që përmbajnë çelësa dhe i kopjon ato në një direktori të përkohshme për përdorim të mëtejshëm. Pas përfundimit të procesit, çelësat nga direktoria e përkohshme fshihen nga luks-auto-clean.service.
Kodi burimor:
/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=Kërkuesi i çelësave LUKS AUTO
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=Objektivi LUKS AUTO
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=Pastruesi i çelësave LUKS AUTO
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 "Instalimi
mkdir -p /usr/lib/dracut/modules.d/99luks-auto/
# këtu vendosim pothuajse të gjithë skedarët
chmod +x /usr/lib/dracut/modules.d/99luks-auto/*.sh
# krijojmë skedarin /etc/dracut.conf.d/luks-auto.conf
# Dhe gjenerojmë initramfs të ri
dracut -f
Përfundim
Për lehtësi, kam ruajtur përputhshmërinë me parametrat e rreshtit të komandës së kernelit edhe për mënyrën sysvinit, gjë që e lehtëson përdorimin në instalimet e vjetra.
Burimi: habr.com
