dracut + systemd + LUKS + usbflash = ์ž๋™ ์ž ๊ธˆ ํ•ด์ œ

์ด์•ผ๊ธฐ๋Š” ์˜ค๋ž˜ ์ „, Centos 7(RHEL 7)์ด ์ถœ์‹œ๋˜์—ˆ์„ ๋•Œ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Centos 6์ด ์„ค์น˜๋œ ๋“œ๋ผ์ด๋ธŒ์—์„œ ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ ํ•„์š”ํ•œ ํ‚ค๊ฐ€ ์žˆ๋Š” USB ํ”Œ๋ž˜์‹œ ๋“œ๋ผ์ด๋ธŒ๋ฅผ ์—ฐ๊ฒฐํ•  ๋•Œ ๋“œ๋ผ์ด๋ธŒ ์ž๋™ ์ž ๊ธˆ ํ•ด์ œ์— ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ 7์ด ์ถœ์‹œ๋˜์ž ๊ฐ‘์ž๊ธฐ ๋ชจ๋“  ๊ฒƒ์ด ์˜ˆ์ „์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ตฌ์„ฑ์˜ ๊ฐ„๋‹จํ•œ ์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ sysvinit์— dracut์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์†”๋ฃจ์…˜์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค: echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
์ด๋กœ ์ธํ•ด systemd์˜ ๋ชจ๋“  ์žฅ์ ์ด ์ฆ‰์‹œ ๋ฐ•ํƒˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ์„œ๋น„์Šค์˜ ๋น ๋ฅด๊ณ  ๋ณ‘๋ ฌ ์‹คํ–‰์œผ๋กœ ์ธํ•ด ์‹œ์Šคํ…œ ์‹œ์ž‘ ์‹œ๊ฐ„์ด ํฌ๊ฒŒ ๋‹จ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ์ƒํ™ฉ์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. 905683
ํ•ด๊ฒฐ์ฑ…์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ๊ด€์‹ฌ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๋Œ€์ค‘๊ณผ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
dracut + systemd + LUKS + usbflash = ์ž๋™ ์ž ๊ธˆ ํ•ด์ œ

์†Œ๊ฐœ

Systemd๋Š” ์ฒ˜์Œ Centos 7์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ์„œ๋น„์Šค ๊ด€๋ฆฌ ๊ตฌ๋ฌธ์ด ์•ฝ๊ฐ„ ๋ณ€๊ฒฝ๋œ ๊ฒƒ ์™ธ์—๋Š” ํฐ ์ฐจ์ด๋ฅผ ๋Š๋ผ์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๋Ÿฐ ๊ฐ์ •์„ ๋Š๋ผ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ ๋‚˜๋Š” systemd๋ฅผ ์ข‹์•„ํ–ˆ์ง€๋งŒ dracut ๊ฐœ๋ฐœ์ž๊ฐ€ ๋””์Šคํฌ ์•”ํ˜ธํ™”์™€ ํ•จ๊ป˜ systemd๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€ํŒ… ํ”„๋กœ์„ธ์Šค๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ์ธ์ƒ์ด ์•ฝ๊ฐ„ ์†์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ž‘๋™ํ–ˆ์ง€๋งŒ ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ๋””์Šคํฌ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ์‹œ๋„ํ•˜๊ณ  ๋งค๋‰ด์–ผ์„ ์—ฐ๊ตฌํ•œ ๊ฒฐ๊ณผ USB๋ฅผ ์‚ฌ์šฉํ•œ ์‹œ์Šคํ…œ ๋ชจ๋“œ ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ฐ ๋””์Šคํฌ๋ฅผ USB ๋””์Šคํฌ์˜ ํ‚ค์™€ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•˜๋ฉฐ USB ๋””์Šคํฌ ์ž์ฒด๋Š” ํ•ด๋‹น ํ‚ค๋กœ๋งŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. UUID, LABEL์ด ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ง‘์—์„œ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋ณ„๋กœ ๋ถˆํŽธํ•ด์„œ ๊ฒฐ๊ตญ ๊ธฐ๋‹ค๋ฆฌ๋‹ค๊ฐ€ ๊ฑฐ์˜ 7๋…„์„ ๊ธฐ๋‹ค๋ฆฐ ๋์— ์•„๋ฌด๋„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์ฃผ์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฑธ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ

๋ฌผ๋ก  ๊ฑฐ์˜ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์ž์‹ ๋งŒ์˜ dracut์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฅผ ์ž‘๋™์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋” ์ด์ƒ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ์‹œ์ž‘์˜ ๋ณ‘๋ ฌ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ๋กœ๋”ฉ ์ง„ํ–‰๋ฅ ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์‰ฝ์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. dracut ๋ฌธ์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์„ค๋ช…ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜ค๋žœ ์‹คํ—˜ ๋์— ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ž‘๋™ ์›๋ฆฌ

์ด๋Š” ์„ธ ๊ฐ€์ง€ ๋‹จ์œ„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

  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๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข…์†์„ฑ์— luks-auto.target์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ‘œ์ค€ systemd-cryptsetup์˜ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

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 ๋ชจ๋“œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปค๋„ ๋ช…๋ น์ค„ ์˜ต์…˜๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜์—ฌ ์ด์ „ ์„ค์น˜์—์„œ๋„ ๋” ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€