Hekayə çoxdan, filmin yayımlandığı vaxtdan başlayıb. Centos 7 (RHEL 7). Əgər disklərdə şifrələmədən istifadə etmisinizsə Centos 6-cı versiyada, düzgün düymələrlə USB flash sürücüsünü qoşarkən disklərin avtomatik kilidini açmaqda heç bir problem yox idi. Lakin, 7-ci versiyanın buraxılması ilə hər şey gözlənildiyi kimi birdən işləməyi dayandırdı. Konfiqurasiyadakı sadə bir sətirdən istifadə edərək dracut-u sysvinit-ə qaytarmaqla həll yolu tapıldı: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
Bu bizi dərhal systemd-in bütün gözəlliyindən məhrum etdi - sistemin işə salınma vaxtını əhəmiyyətli dərəcədə azaldan sistem xidmətlərinin sürətli və paralel işə salınması.
İşlər hələ də var:
Həllini gözləmədən özüm üçün hazırladım və indi bunu ictimaiyyətlə bölüşürəm, maraqlananlar oxusunlar.

Giriş
İlk dəfə işləməyə başladığım zaman Systemd Centos 7 heç bir həyəcan doğurmadı, çünki xidmət idarəetmə sintaksisindəki kiçik bir dəyişiklikdən başqa, əvvəlcə çox fərq hiss etmədim. Nəticədə systemd-i bəyənməyə başladım, amma ilkin təəssüratım bir az dəyişdi, çünki dracut tərtibatçıları systemd açılış prosesini disk şifrələməsi ilə birlikdə dəstəkləmək üçün çox vaxt sərf etmədilər. Ümumiyyətlə işləyirdi, amma hər dəfə işə salanda disk parolumu daxil etməli oldum. server — ən maraqlı fəaliyyət deyil.
Bir sıra tövsiyələri sınadıqdan və təlimatı öyrəndikdən sonra başa düşdüm ki, sistem rejimində USB ilə konfiqurasiya mümkündür, ancaq hər bir diskin USB diskindəki açarla əl ilə əlaqələndirilməsi ilə və USB diskin özü yalnız onunla əlaqələndirilə bilər. UUID, LABEL işləmədi. Bunu evdə saxlamaq çox rahat deyildi, buna görə də sonda gözləməyə başladım və təxminən 7 il gözlədikdən sonra heç kimin problemi həll etməyəcəyini başa düşdüm.
Problemləri
Əlbəttə ki, demək olar ki, hər kəs dracut üçün öz plaginini yaza bilər, lakin onu işləmək artıq o qədər də asan deyil. Məlum oldu ki, sistem başlanğıcının paralel xarakterinə görə kodunuzu daxil etmək və yükləmə prosesini dəyişdirmək o qədər də asan deyil. Dracut üçün sənədlər hər şeyi izah etmədi. Ancaq uzun təcrübələrdən sonra problemi həll edə bildim.
Bu necə işləyir
Üç vahidə əsaslanır:
- luks-auto-key.service - LUKS üçün açarları olan sürücüləri axtarır
- luks-auto.target - daxili systemd-cryptsetup vahidləri üçün asılılıq kimi çıxış edir
- luks-auto-clean.service - luks-auto-key.service tərəfindən yaradılmış müvəqqəti faylları təmizləyir
Və luks-auto-generator.sh systemd tərəfindən işə salınan və nüvə parametrləri əsasında vahidlər yaradan bir skriptdir. Oxşar generatorlar fstab vahidləri tərəfindən yaradılır və s.
luks-auto-generator.sh
Drop-in.conf istifadə edərək, standart systemd-cryptsetup-un davranışı onların asılılığına luks-auto.target əlavə etməklə dəyişdirilir.
luks-auto-key.service və luks-auto-key.sh
Bu bölmə rd.luks.* düymələrinə əsaslanaraq, düymələri olan medianı tapıb sonrakı istifadə üçün onları müvəqqəti kataloqa köçürən luks-auto-key.sh skriptini idarə edir. Proses başa çatdıqdan sonra açarlar luks-auto-clean.service tərəfindən müvəqqəti kataloqdan silinir.
Mənbələr:
/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 "Quraşdırma
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
Nəticə
Rahatlıq üçün sysvinit rejimində olduğu kimi kernel əmr satırı seçimləri ilə də uyğunluğu qorudum ki, bu da köhnə quraşdırmalarda istifadəni asanlaşdırır.
Mənbə: www.habr.com
