From a80e32c53867cbc90870e024bcffc267ef9abbe2 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 28 Aug 2018 09:25:03 +0200 Subject: [PATCH] initial commit --- README.md | 37 +++++ clonedisk.sh | 78 ++++++++++ excludelist.txt | 10 ++ logo.bmp | Bin 0 -> 15482 bytes mkimage.sh | 171 ++++++++++++++++++++++ pkglist-min.txt | 19 +++ pkglist-sssd.txt | 76 ++++++++++ pkglist.txt | 65 +++++++++ pre-pivot.sh | 95 ++++++++++++ prepare-root.sh | 368 +++++++++++++++++++++++++++++++++++++++++++++++ quirks/nss_db.sh | 51 +++++++ quirks/passwd.sh | 31 ++++ quirks/sssd.sh | 24 ++++ 13 files changed, 1025 insertions(+) create mode 100644 README.md create mode 100755 clonedisk.sh create mode 100644 excludelist.txt create mode 100644 logo.bmp create mode 100755 mkimage.sh create mode 100644 pkglist-min.txt create mode 100644 pkglist-sssd.txt create mode 100644 pkglist.txt create mode 100644 pre-pivot.sh create mode 100755 prepare-root.sh create mode 100644 quirks/nss_db.sh create mode 100644 quirks/passwd.sh create mode 100644 quirks/sssd.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..2a2b558 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# FedoraBook + +WIP + +## Create + +```bash +$ sudo ./prepare-root.sh \ + --pkglist pkglist.txt \ + --excludelist excludelist.txt \ + --logo logo.bmp --name FEDORABOOK \ + --outdir +``` + +## QEMU disk image +```bash +$ sudo ./mkimage.sh image.raw +``` + +## USB stick +```bash +$ sudo ./mkimage.sh /dev/disk/by-path/pci-…-usb… +``` + +## Install from USB stick + +- Enter BIOS + - turn on UEFI boot + - turn on TPM2 +- Enter BIOS boot menu +- Select USB stick +- Login (user: admin, pw: admin) +- Start gnome-terminal +- sudo +- ```clonedisk ``` +- reboot +- remove stick diff --git a/clonedisk.sh b/clonedisk.sh new file mode 100755 index 0000000..4e97112 --- /dev/null +++ b/clonedisk.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +set -ex + +[[ $TMPDIR ]] || TMPDIR=/var/tmp +readonly TMPDIR="$(realpath -e "$TMPDIR")" +[ -d "$TMPDIR" ] || { + printf "%s\n" "${PROGNAME}: Invalid tmpdir '$tmpdir'." >&2 + exit 1 +} + +readonly MY_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t ${PROGNAME}.XXXXXX)" +[ -d "$MY_TMPDIR" ] || { + printf "%s\n" "${PROGNAME}: mktemp -p '$TMPDIR/' -d -t ${PROGNAME}.XXXXXX failed." >&2 + exit 1 +} + +# clean up after ourselves no matter how we die. +trap ' + ret=$?; + [[ $MY_TMPDIR ]] && mountpoint "$MY_TMPDIR"/data && umount "$MY_TMPDIR"/data + [[ $MY_TMPDIR ]] && rm -rf --one-file-system -- "$MY_TMPDIR" + exit $ret; + ' EXIT + +# clean up after ourselves no matter how we die. +trap 'exit 1;' SIGINT + +mem=$(cat /proc/meminfo | { read a b a; echo $b; } ) +mem=$(((mem-1)/1024/1024 + 1)) +mem=${3:-$mem} + +IN=$(readlink -e "$1") +OUT=$(readlink -e "$2") + +[[ -b ${IN} ]] +[[ -b ${OUT} ]] + +for i in ${OUT}*; do + umount "$i" || : +done + +if [[ ${IN#/dev/loop} != $IN ]]; then + IN="${IN}p" +fi + +wipefs --all "$OUT" + +sfdisk -W always -w always "$OUT" << EOF +label: gpt + size=512MiB, type=c12a7328-f81f-11d2-ba4b-00a0c93ec93b, name="ESP System Partition" + size=256M, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver1", uuid=$(blkid -o value -s PARTUUID ${IN}2) + size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root1", uuid=$(blkid -o value -s PARTUUID ${IN}3) + size=256M, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver2" + size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root2" + size=${mem}GiB, type=0657fd6d-a4ab-43c4-84e5-0933c84b4f4f, name="swap" + type=3b8f8425-20e0-4f3b-907f-1a25a76f98e9, name="data" +EOF + +if [[ ${OUT#/dev/loop} != $OUT ]]; then + OUT="${OUT}p" +fi +if [[ ${OUT#/dev/nvme} != $OUT ]]; then + OUT="${OUT}p" +fi + +for i in 1 2 3; do + dd if=${IN}${i} of=${OUT}${i} status=progress +done + +# ------------------------------------------------------------------------------ +# swap +mkswap -L swap ${OUT}6 + +# ------------------------------------------------------------------------------ +# data +echo -n "zero key" \ + | cryptsetup luksFormat --type luks2 ${OUT}7 /dev/stdin diff --git a/excludelist.txt b/excludelist.txt new file mode 100644 index 0000000..de0cbbc --- /dev/null +++ b/excludelist.txt @@ -0,0 +1,10 @@ +trousers +systemd-bootchart +grubby +grub* +plymouth +device-mapper-multipath +libvirt-daemon +selinux-policy-targeted +libselinux-utils + diff --git a/logo.bmp b/logo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b9177802aa117f2f2c78c5d45a9bb115cd2bdc21 GIT binary patch literal 15482 zcmeI3OOo3*5QZ677IIBVbDfkc3zs)ud6SxBWS31UC(?~_4Ie;@03h-B`-N_j%4~)< zrADLCAN~eNiBmJ*e*E+MQjRabF3X?E`g=QnSuVx@^|xjD_qv`xlP90wzW?!8=?uJl z5@PSmeR+F(EcbLi@_BzO%OkbZ`6%Z-Hee9oiyMD?= z_>M2P<#tPF{^xx!(TAp7V2QWuNcf${E*uWp1IG-zTS3vgIl{n*YGL>hmshpPxTeDl z5Ia3+abR{{UoQQ4jnU^|4SVg(YDLgH!JxHrFP8{;a!m_*(~^!Q?$~5S$fjn_&07gr z*x&=~ilF5)2t1s`W{Dq7%n=%=PY}gt15>c$| z>k(YB=DsSDBWo;zWvsoiGI<;~wS`iTW4heg&N>brxFa@!KbL~4FQL69l)8hFTUxbK zx_#9?-#aaJAH}e}D_O!F4Ekpcl}oWK5xa+l_B5?@OF!k_Zgj2NSdXCzCR`~Mt+f=R z`w(2?99Xu|U7?cJP+n&BZ&WJU7Ej!EP?>=&;_dII0&nmZ41Ps)7Zs zGGcSX0^6Zdufa8U=~2CHYps)VuP!q{`hB{l^ z<9gSfRd<0Ge3srQ_XNE~u*}sfeU{$(frOt(`pVOCK7)&b1u!QgHuf~yN}IX8A#w9njo&a}c}XKj-}qby#AYH_29w-o^Cgqh!AZme zddauDHHFDxouAi1Gc;`IJf$|Q8vY`$bExAcWTKaInWBlKRyy-ZZHFdVUqSH%!@CE; z2AS$*rRIqz9^h({+4?fY6AJG}t|nQ~i<^rlwmswemMILY+D&17OJ|?-f&IKC>9oNT z_2&LYw&l@YCO737aLv>N4``a&YD-uVtm<87mhQIc@YY(UN{TJHttP|(z5IbNPm~@c zLu$ss_(8}sCJ)8(N+<02K`3USPS8s`w>BlSusGMDH&G_wXX#~ND)?D?DVT7dr}uQQ zZ++Pkqu^)i#l6M3!3)W)7rA(s&U%B~!1EwnOrzj}4RZZ@Q84EQ!Jhlo3YqAQaZk{@ zmN~e(@vTfUpOY7mOaluK57h8@1cIK>|@<3-%bQ#?t|?W)>7ANnW-A-emh!dDJ5xB&Ku7-WD9qgk0RH~~?wu$f F_aAS@;n)BG literal 0 HcmV?d00001 diff --git a/mkimage.sh b/mkimage.sh new file mode 100755 index 0000000..19070b2 --- /dev/null +++ b/mkimage.sh @@ -0,0 +1,171 @@ +#!/bin/bash + +#=================================== +FEDORA_VERSION=${FEDORA_VERSION:-28} +#=================================== + +set -ex + +CURDIR=$(pwd) +PROGNAME=${0##*/} + +usage() { + cat << EOF +Usage: $PROGNAME [OPTION] + + -h, --help Display this help + --crypt Use Luks2 to encrypt the data partition (default PW: 1) + --crypttpm2 as --crypt, but additionally auto-open with the use of a TPM2 + --simple do not use dual-boot layout (e.g. for USB install media) +EOF +} + +TEMP=$( + getopt -o '' \ + --long crypt \ + --long crypttpm2 \ + --long help \ + -- "$@" + ) + +if (( $? != 0 )); then + usage >&2 + exit 1 +fi + +eval set -- "$TEMP" +unset TEMP +. /etc/os-release + +while true; do + case "$1" in + '--crypt') + USE_CRYPT="y" + shift 1; continue + ;; + '--crypttpm2') + USE_TPM="y" + shift 1; continue + ;; + '--help') + usage + exit 0 + ;; + '--') + shift + break + ;; + *) + echo 'Internal error!' >&2 + exit 1 + ;; + esac +done + +SOURCE=$(readlink -e "$1") +IMAGE=$(readlink -e "$2") + +if ! [[ -d $SOURCE ]] || ! [[ $IMAGE ]]; then + usage + exit 1 +fi + + +[[ $TMPDIR ]] || TMPDIR=/var/tmp +readonly TMPDIR="$(realpath -e "$TMPDIR")" +[ -d "$TMPDIR" ] || { + printf "%s\n" "${PROGNAME}: Invalid tmpdir '$tmpdir'." >&2 + exit 1 +} + +readonly MY_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t ${PROGNAME}.XXXXXX)" +[ -d "$MY_TMPDIR" ] || { + printf "%s\n" "${PROGNAME}: mktemp -p '$TMPDIR/' -d -t ${PROGNAME}.XXXXXX failed." >&2 + exit 1 +} + +# clean up after ourselves no matter how we die. +trap ' + ret=$?; + for i in "$MY_TMPDIR"/boot "$MY_TMPDIR"/data; do + [[ -d "$i" ]] && mountpoint -q "$i" && umount "$i" + done + [[ $DEV ]] && losetup -d $DEV 2>/dev/null || : + [[ $MY_TMPDIR ]] && rm -rf --one-file-system -- "$MY_TMPDIR" + exit $ret; + ' EXIT + +# clean up after ourselves no matter how we die. +trap 'exit 1;' SIGINT + +ROOT_HASH=$(<"$SOURCE"/root-hash.txt) + +ROOT_UUID=${ROOT_HASH:32:8}-${ROOT_HASH:40:4}-${ROOT_HASH:44:4}-${ROOT_HASH:48:4}-${ROOT_HASH:52:12} +HASH_UUID=${ROOT_HASH:0:8}-${ROOT_HASH:8:4}-${ROOT_HASH:12:4}-${ROOT_HASH:16:4}-${ROOT_HASH:20:12} + + +# ------------------------------------------------------------------------------ +# Testdisk + +# create GPT table with EFI System Partition +if ! [[ -b "${IMAGE}" ]]; then + rm -f "${IMAGE}" + dd if=/dev/null of="${IMAGE}" bs=1MiB seek=$((15*1024)) count=1 + readonly DEV=$(losetup --show -f -P "${IMAGE}") + readonly DEV_PART=${DEV}p +else + for i in ${IMAGE}*; do + umount "$i" || : + done + + wipefs --force --all "${IMAGE}" + readonly DEV="${IMAGE}" + readonly DEV_PART="${IMAGE}" +fi + +udevadm settle +sfdisk "${DEV}" << EOF +label: gpt + size=512MiB, type=c12a7328-f81f-11d2-ba4b-00a0c93ec93b, name="ESP System Partition" + size=64MiB, type=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5, name="ver1", uuid=$HASH_UUID + size=4GiB, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, name="root1", uuid=$ROOT_UUID + type=3b8f8425-20e0-4f3b-907f-1a25a76f98e9, name="data" +EOF + +udevadm settle +for i in 1 2 3 4; do + wipefs --force --all ${DEV_PART}${i} +done +udevadm settle + +# ------------------------------------------------------------------------------ +# ESP +mkfs.fat -nEFI -F32 ${DEV_PART}1 +mkdir "$MY_TMPDIR"/boot +mount ${DEV_PART}1 "$MY_TMPDIR"/boot + +mkdir -p "$MY_TMPDIR"/boot/EFI/Boot +cp "$SOURCE"/bootx64.efi "$MY_TMPDIR"/boot/EFI/Boot/bootx64.efi +umount "$MY_TMPDIR"/boot + +# ------------------------------------------------------------------------------ +# ver1 +dd if="$SOURCE"/root.verity.img of=${DEV_PART}2 status=progress + +# ------------------------------------------------------------------------------ +# root1 +dd if="$SOURCE"/root.squashfs.img of=${DEV_PART}3 status=progress + +# ------------------------------------------------------------------------------ +# data +echo -n "zero key" \ + | cryptsetup luksFormat --type luks2 ${DEV_PART}4 /dev/stdin + +# ------------------------------------------------------------------------------ +# DONE + +sync +losetup -d $DEV || : +eject "$DEV" || : +sync + diff --git a/pkglist-min.txt b/pkglist-min.txt new file mode 100644 index 0000000..13dc9f7 --- /dev/null +++ b/pkglist-min.txt @@ -0,0 +1,19 @@ +dracut +passwd +rootfiles +systemd +systemd-udev +kernel +kernel-core +bash +sudo +openssh-server +strace +xfsprogs +pciutils +microcode_ctl +nss_db +keyutils +make +less + diff --git a/pkglist-sssd.txt b/pkglist-sssd.txt new file mode 100644 index 0000000..eedd5e8 --- /dev/null +++ b/pkglist-sssd.txt @@ -0,0 +1,76 @@ +@GNOME +@Fonts +dracut +passwd +rootfiles +systemd +systemd-udev +kernel +kernel-core +bash +gnome-software +gdm +NetworkManager +NetworkManager-openvpn +NetworkManager-openvpn-gnome +NetworkManager-ssh +NetworkManager-ssh-gnome +NetworkManager-vpnc +NetworkManager-vpnc-gnome +NetworkManager-wifi +firefox +emacs +vim-enhanced +pigz +flatpak +virt-manager +gnome-desktop3 +less +bash-completion +sudo +openssh-server +gnome-terminal +strace +libselinux-utils +selinux-policy-targeted +xfsprogs +pciutils +alsa-firmware +alsa-tools-firmware.x86_64 +atmel-firmware +bfa-firmware +ipw2100-firmware +ipw2200-firmware +iscan-firmware +iwl1000-firmware +iwl100-firmware +iwl105-firmware +iwl135-firmware +iwl2000-firmware +iwl2030-firmware +iwl3160-firmware +iwl3945-firmware +iwl4965-firmware +iwl5000-firmware +iwl5150-firmware +iwl6000-firmware +iwl6000g2a-firmware +iwl6000g2b-firmware +iwl6050-firmware +iwl7260-firmware +libertas-sd8686-firmware +libertas-sd8787-firmware +libertas-usb8388-firmware +linux-firmware +midisport-firmware +microcode_ctl +nss_db +psmisc +authselect +keyutils +oddjob +oddjob-mkhomedir +sssd-client +sssd-ldap +sssd-krb5 +sssd-tools diff --git a/pkglist.txt b/pkglist.txt new file mode 100644 index 0000000..3875c16 --- /dev/null +++ b/pkglist.txt @@ -0,0 +1,65 @@ +@GNOME +gnome-initial-setup +@Fonts +NetworkManager +NetworkManager-openvpn +NetworkManager-openvpn-gnome +NetworkManager-ssh +NetworkManager-ssh-gnome +NetworkManager-vpnc +NetworkManager-vpnc-gnome +NetworkManager-wifi +firefox +emacs +vim-enhanced +pigz +flatpak +virt-manager +alsa-firmware +alsa-tools-firmware.x86_64 +atmel-firmware +bfa-firmware +ipw2100-firmware +ipw2200-firmware +iscan-firmware +iwl1000-firmware +iwl100-firmware +iwl105-firmware +iwl135-firmware +iwl2000-firmware +iwl2030-firmware +iwl3160-firmware +iwl3945-firmware +iwl4965-firmware +iwl5000-firmware +iwl5150-firmware +iwl6000-firmware +iwl6000g2a-firmware +iwl6000g2b-firmware +iwl6050-firmware +iwl7260-firmware +libertas-sd8686-firmware +libertas-sd8787-firmware +libertas-usb8388-firmware +linux-firmware +midisport-firmware +psmisc +authselect +openssh-server +b43-openfwwf +zd1211-firmware +gnome-remote-desktop +geolite2-country +geolite2-city +GeoIP-GeoLite-data +adwaita-cursor-theme +adwaita-icon-theme +adwaita-gtk2-theme +adwaita-qt5 +adwaita-qt +adwaita-qt4 +ca-certificates +fedora-gpg-keys +bind-utils +bash-completion + diff --git a/pre-pivot.sh b/pre-pivot.sh new file mode 100644 index 0000000..00780ab --- /dev/null +++ b/pre-pivot.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +root=$(getarg systemd.verity_root_hash) + +case "$root" in + block:LABEL=*|LABEL=*) + root="${root#block:}" + root="$(echo $root | sed 's,/,\\x2f,g')" + root="/dev/disk/by-label/${root#LABEL=}" + rootok=1 ;; + block:UUID=*|UUID=*) + root="${root#block:}" + root="${root#UUID=}" + root="$(echo $root | tr "[:upper:]" "[:lower:]")" + root="/dev/disk/by-uuid/${root#UUID=}" + rootok=1 ;; + block:PARTUUID=*|PARTUUID=*) + root="${root#block:}" + root="${root#PARTUUID=}" + root="$(echo $root | tr "[:upper:]" "[:lower:]")" + root="/dev/disk/by-partuuid/${root}" + rootok=1 ;; + block:PARTLABEL=*|PARTLABEL=*) + root="${root#block:}" + root="/dev/disk/by-partlabel/${root#PARTLABEL=}" + rootok=1 ;; + /dev/*) + rootok=1 ;; +esac + +udevadm settle --exit-if-exists=/dev/tpmrm0 +udevadm settle --exit-if-exists="$root" + +unset FOUND +for d in /dev/disk/by-path/*; do + [[ $d -ef $root ]] || continue + FOUND=1 + break +done + +[[ $FOUND ]] || die "No boot disk found" + +disk=${d%-part*} + +unset FOUND +for datadev in $disk*; do + [[ $(blkid -o value -s PARTLABEL "$datadev") == "data" ]] || continue + FOUND=1 + break +done + +if cryptsetup isLuks --type luks2 "$datadev"; then + export TPM2TOOLS_TCTI_NAME=device + export TPM2TOOLS_DEVICE_FILE=/dev/tpmrm0 + luksname=luks-$(blkid -o value -s UUID "$datadev") + mapdev=/dev/mapper/$luksname + + if ! [[ -b $mapdev ]]; then + if ! cryptsetup luksDump "$datadev" | grep -F -q clevis ; then + if echo -n "zero key" | clevis-luks-bind -f -k - -d "$datadev" tpm2 '{"pcr_ids":"7"}'; then + echo -n "zero key" | cryptsetup luksRemoveKey "$datadev" /dev/stdin || die "Failed to remove key from LUKS" + clevis-luks-unlock -d "$datadev" || die "Failed to unlock $datadev" + elif echo -n "zero key" | clevis-luks-bind -f -k - -d "$datadev" tpm2 '{"pcr_ids":"7","key":"rsa"}'; then + echo -n "zero key" | cryptsetup luksRemoveKey "$datadev" /dev/stdin || die "Failed to remove key from LUKS" + clevis-luks-unlock -d "$datadev" || die "Failed to unlock $datadev" + else + warn "Failed to bind disk to TPM2" + echo -n "zero key" | cryptsetup open --type luks2 "$datadev" $luksname --key-file /dev/stdin + fi + else + clevis-luks-unlock -d "$datadev" || die "Failed to unlock $datadev" + fi + fi +else + mapdev="$datadev" +fi + +if [[ $(blkid -o value -s TYPE "$mapdev") != "xfs" ]]; then + mkfs.xfs -f -L data "$mapdev" +fi + +mount $mapdev /sysroot/data || die "Failed to mount $mapdev" + +[[ -d /sysroot/data/var ]] || mkdir /sysroot/data/var +[[ -d /sysroot/data/home ]] || mkdir /sysroot/data/home + +mount -o bind /sysroot/data/var /sysroot/var +mount -o bind /sysroot/data/home /sysroot/home + +for i in passwd shadow group gshadow subuid subgid; do + [[ -f /sysroot/data/var/$i ]] && continue + cp -a /sysroot/usr/share/factory/data/var/$i /sysroot/data/var/$i +done + +chroot /sysroot /usr/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --exclude-prefix=/run --exclude-prefix=/tmp --exclude-prefix=/etc 2>&1 | vinfo diff --git a/prepare-root.sh b/prepare-root.sh new file mode 100755 index 0000000..dac0240 --- /dev/null +++ b/prepare-root.sh @@ -0,0 +1,368 @@ +#!/bin/bash +set -ex + +usage() { + cat << EOF +Usage: $PROGNAME [OPTION] + +Creates a directory with a readonly root on squashfs, a dm_verity file and an EFI executable + + -h, --help Display this help + -p, --pkglist FILE The packages to install read from FILE (default: pkglist.txt) + -e, --excludelist FILE The packages to install read from FILE (default: excludelist.txt) + -r, --releasever NUM Used Fedora release version NUM (default: $VERSION_ID) + -o, --outdir DIR Creates DIR and puts all files in there (default: NAME-NUM-DATE) + -n, --name NAME The NAME of the product (default: FedoraBook) + -l, --logo FILE Uses the .bmp FILE to display as a splash screen (default: logo.bmp) + --noupdate Do not install from Fedora Updates +EOF +} + +CURDIR=$(pwd) + +PROGNAME=${0##*/} +BASEDIR=${0%/*} +WITH_UPDATES=1 + +TEMP=$( + getopt -o 'p:o:n:r:l:e:' \ + --long pkglist: \ + --long excludelist: \ + --long outdir: \ + --long name: \ + --long releasever: \ + --long logo: \ + --long noupdates \ + -- "$@" + ) + +if (( $? != 0 )); then + usage >&2 + exit 1 +fi + +eval set -- "$TEMP" +unset TEMP +. /etc/os-release + +while true; do + case "$1" in + '-p'|'--pkglist') + if [[ -f $2 ]]; then + PKGLIST=$(<$2) + else + PKGLIST="$2" + fi + shift 2; continue + ;; + '-e'|'--excludelist') + if [[ -f $2 ]]; then + EXCLUDELIST=$(<$2) + else + EXCLUDELIST="$2" + fi + shift 2; continue + ;; + '-o'|'--outdir') + OUTDIR="$2" + shift 2; continue + ;; + '-n'|'--name') + NAME="$2" + shift 2; continue + ;; + '-r'|'--releasever') + RELEASEVER="$2" + shift 2; continue + ;; + '-l'|'--logo') + LOGO="$2" + shift 2; continue + ;; + '--noupdates') + unset WITH_UPDATES + shift 1; continue + ;; + '--') + shift + break + ;; + *) + echo 'Internal error!' >&2 + exit 1 + ;; + esac +done + +[[ $EXCLUDELIST ]] || [[ -f excludelist.txt ]] && EXCLUDELIST=$(&2 + exit 1 +} + +readonly MY_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t ${PROGNAME}.XXXXXX)" +[ -d "$MY_TMPDIR" ] || { + printf "%s\n" "${PROGNAME}: mktemp -p '$TMPDIR/' -d -t ${PROGNAME}.XXXXXX failed." >&2 + exit 1 +} + +# clean up after ourselves no matter how we die. +trap ' + ret=$?; + mountpoint -q "$sysroot"/var/cache/dnf && umount "$sysroot"/var/cache/dnf + for i in "$sysroot"/{dev,sys,proc,run}; do + [[ -d "$i" ]] && mountpoint -q "$i" && umount "$i" + done + [[ $MY_TMPDIR ]] && rm -rf --one-file-system -- "$MY_TMPDIR" + exit $ret; + ' EXIT + +# clean up after ourselves no matter how we die. +trap 'exit 1;' SIGINT + +readonly sysroot="${MY_TMPDIR}/sysroot" + +mkdir -p "$sysroot"/{dev,proc,sys,run} +mount --bind /proc "$sysroot/proc" +#mount --bind /run "$sysroot/run" +mount --bind /sys "$sysroot/sys" +mount -t devtmpfs devtmpfs "$sysroot/dev" + +mkdir -p "$sysroot"/var/cache/dnf +mount --bind /var/cache/dnf "$sysroot"/var/cache/dnf + +dnf -v --nogpgcheck --installroot "$sysroot"/ --releasever "$RELEASEVER" --disablerepo='*' \ + --enablerepo=fedora \ + ${WITH_UPDATES:+--enablerepo=updates} \ + --exclude="$EXCLUDELIST" \ + --setopt=keepcache=True \ + install -y \ + dracut \ + passwd \ + rootfiles \ + systemd \ + systemd-udev \ + kernel \ + bash \ + sudo \ + strace \ + xfsprogs \ + pciutils \ + microcode_ctl \ + nss_db \ + keyutils \ + make \ + less \ + polkit \ + util-linux \ + rng-tools \ + openssl \ + cryptsetup \ + clevis \ + clevis-luks \ + clevis-systemd \ + jose \ + tpm2-tools \ + coreutils \ + libpwquality \ + tpm2-tss \ + ncurses-base \ + dbus-broker \ + $PKGLIST + +cp "$CURDIR/clonedisk.sh" "$sysroot"/usr/bin/clonedisk + +rpm --root "$sysroot" -qa | sort > "$sysroot"/usr/rpm-list.txt +mkdir -p "$sysroot"/overlay/efi + +cp "${BASEDIR}"/pre-pivot.sh "$sysroot"/pre-pivot.sh +chmod 0755 "$sysroot"/pre-pivot.sh + +KVER=$(cd "$sysroot"/lib/modules/; ls -1d ??* | tail -1) + +sed -ie 's#\(tpm2_[^ ]*\) #\1 -T device:${TPM2TOOLS_DEVICE_FILE[0]} #g' "$sysroot"/usr/bin/clevis-*-tpm2 + +#--------------- +# rngd +ln -fsnr "$sysroot"/usr/lib/systemd/system/rngd.service "$sysroot"/usr/lib/systemd/system/basic.target.wants/rngd.service + +chroot "$sysroot" \ + dracut -N --kver $KVER --force \ + --filesystems "squashfs vfat xfs" \ + --add-drivers "=drivers/char/tpm" \ + -m "bash systemd systemd-initrd modsign crypt dm kernel-modules qemu rootfs-block udev-rules dracut-systemd base fs-lib shutdown terminfo" \ + --install /usr/lib/systemd/systemd-veritysetup \ + --install /usr/lib/systemd/system-generators/systemd-veritysetup-generator \ + --install "clonedisk wipefs sfdisk dd mkfs.xfs mkswap chroot mountpoint mkdir stat openssl" \ + --install "clevis clevis-luks-bind jose clevis-encrypt-tpm2 clevis-decrypt clevis-luks-unlock clevis-decrypt-tpm2" \ + --install "cryptsetup tail sort pwmake mktemp " \ + --install "tpm2_createprimary tpm2_pcrlist tpm2_createpolicy tpm2_create tpm2_load tpm2_unseal tpm2_takeownership" \ + --install "strace" \ + --include /pre-pivot.sh /lib/dracut/hooks/pre-pivot/pre-pivot.sh \ + --include /overlay / \ + --install /usr/lib/systemd/system/clevis-luks-askpass.path \ + --install /usr/lib/systemd/system/clevis-luks-askpass.service \ + --install /usr/libexec/clevis-luks-askpass \ + --include /usr/share/cracklib/ /usr/share/cracklib/ \ + --install /usr/lib64/libtss2-esys.so.0 \ + --install /usr/lib64/libtss2-tcti-device.so.0 \ + --install /sbin/rngd \ + --install /usr/lib/systemd/system/basic.target.wants/rngd.service + +rm "$sysroot"/pre-pivot.sh +#bash -i + +umount "$sysroot"/var/cache/dnf + +mkdir -p "$sysroot"/usr/share/factory/data/{var/etc,home} +ln -sfnr "$sysroot"/usr/share/factory/data/var "$sysroot"/usr/share/factory/var +ln -sfnr "$sysroot"/usr/share/factory/data/home "$sysroot"/usr/share/factory/home + +#--------------- +# timesync +ln -fsnr "$sysroot"/usr/lib/systemd/system/systemd-timesyncd.service "$sysroot"/usr/lib/systemd/system/sysinit.target.wants/systemd-timesyncd.service + +#--------------- +# dbus-broker +ln -fsnr "$sysroot"/usr/lib/systemd/system/dbus-broker.service "$sysroot"/etc/systemd/system/dbus.service + +#--------------- +# ssh +if [[ -d "$sysroot"/etc/ssh ]]; then + mv "$sysroot"/etc/ssh "$sysroot"/usr/share/factory/var/etc/ssh + ln -sfnr "$sysroot"/var/etc/ssh "$sysroot"/etc/ssh +fi + +#--------------- +# tpm2-tss +if [[ -f "$sysroot"/usr/lib/udev/rules.d/60-tpm-udev.rules ]]; then + echo 'tss:x:59:59:tpm user:/dev/null:/sbin/nologin' >> "$sysroot"/etc/passwd + echo 'tss:!!:15587::::::' >> "$sysroot"/etc/shadow + echo 'tss:x:59:' >> "$sysroot"/etc/group + echo 'tss:!::' >> "$sysroot"/etc/gshadow +fi + +#--------------- +# NetworkManager +if [[ -d "$sysroot"/etc/NetworkManager ]]; then + mv "$sysroot"/etc/NetworkManager "$sysroot"/usr/share/factory/var/etc/ + ln -fsnr "$sysroot"/var/etc/NetworkManager "$sysroot"/etc/NetworkManager + cat >> "$sysroot"/usr/lib/tmpfiles.d/NetworkManager.conf <> "$sysroot"/usr/lib/tmpfiles.d/resolv.conf +ln -sfrn "$sysroot"/var/etc/hostname "$sysroot"/etc/hostname +echo "FedoraBook" > "$sysroot"/usr/share/factory/var/etc/hostname + +#--------------- +# vconsole.conf +ln -fsnr "$sysroot"/var/etc/vconsole.conf "$sysroot"/etc/vconsole.conf +echo -e 'FONT=latarcyrheb-sun16\nKEYMAP=us' > "$sysroot"/usr/share/factory/var/etc/vconsole.conf + +#--------------- +# locale.conf +ln -fsnr "$sysroot"/var/etc/locale.conf "$sysroot"/etc/locale.conf +echo 'LANG=en_US.UTF-8' > "$sysroot"/usr/share/factory/var/etc/locale.conf + +#--------------- +# udev dri/card0 +cp "${BASEDIR}"/systemd-udev-settle-dri.service "$sysroot"/usr/lib/systemd/system/ +ln -fsnr "$sysroot"/usr/lib/systemd/system/systemd-udev-settle-dri.service \ + "$sysroot"/usr/lib/systemd/system/multi-user.target.wants/systemd-udev-settle-dri.service + +#--------------- +# Flathub +if [[ -d "$sysroot"/usr/share/flatpak ]]; then + mkdir -p "$sysroot"/usr/share/factory/var/lib/ + curl https://flathub.org/repo/flathub.flatpakrepo -o "$sysroot"/usr/share/flatpak/flathub.flatpakrepo + chroot "$sysroot" bash -c '/usr/bin/flatpak remote-add --if-not-exists flathub /usr/share/flatpak/flathub.flatpakrepo' +fi + +#--------------- +# var +rm -fr "$sysroot"/var/lib/rpm +rm -fr "$sysroot"/var/lib/selinux +rm -fr "$sysroot"/var/log/dnf* +rm -fr "$sysroot"/var/cache/*/* +rm -fr "$sysroot"/var/tmp/* +rm -fr "$sysroot"/etc/systemd/system/network-online.target.wants +mv "$sysroot"/lib/tmpfiles.d/var.conf "$sysroot"/lib/tmpfiles.d-var.conf +chroot "$sysroot" bash -c 'for i in $(find -H /var -xdev -type d); do grep " $i " -r -q /lib/tmpfiles.d && ! grep " $i " -q /lib/tmpfiles.d-var.conf && rm -vfr --one-file-system "$i" ; done; :' +cp -avxr "$sysroot"/var/* "$sysroot"/usr/share/factory/data/var/ +rm -fr "$sysroot"/usr/share/factory/var/{run,lock} + +chroot "$sysroot" bash -c 'for i in $(find -H /var -xdev -type d); do echo "C /data$i - - - - -"; done > /usr/lib/tmpfiles.d/var-quirk.conf; :' +mv "$sysroot"/lib/tmpfiles.d-var.conf "$sysroot"/lib/tmpfiles.d/var.conf + +sed -i -e "s#VERSION_ID=.*#VERSION_ID=$VERSION_ID#" "$sysroot"/etc/os-release + +mv -v "$sysroot"/boot/*/*/initrd "$MY_TMPDIR"/ +mv -v "$sysroot"/lib/modules/*/vmlinuz "$MY_TMPDIR"/linux +rm -fr "$sysroot"/{boot,root} +ln -sfnr "$sysroot"/data/root "$sysroot"/root +rm -fr "$sysroot"/etc/yum.repos.d/* +mkdir "$sysroot"/efi +rm -fr "$sysroot"/var/* +rm -fr "$sysroot"/home/* +rm -fr "$sysroot"/etc/selinux +mkdir "$sysroot"/data + +for i in "$sysroot"/{dev,sys,proc,run}; do + [[ -d "$i" ]] && mountpoint -q "$i" && umount "$i" +done + + +# ------------------------------------------------------------------------------ +# sysroot +mksquashfs "$MY_TMPDIR"/sysroot "$MY_TMPDIR"/root.squashfs.img \ + -noDataCompression -noFragmentCompression -noXattrCompression -noInodeCompression + +# ------------------------------------------------------------------------------ +# verity +ROOT_HASH=$(veritysetup format "$MY_TMPDIR"/root.squashfs.img "$MY_TMPDIR"/root.verity.img |& tail -1 | { read a b c; echo $c; } ) + +echo "$ROOT_HASH" > "$MY_TMPDIR"/root-hash.txt + +ROOT_UUID=${ROOT_HASH:32:8}-${ROOT_HASH:40:4}-${ROOT_HASH:44:4}-${ROOT_HASH:48:4}-${ROOT_HASH:52:12} +HASH_UUID=${ROOT_HASH:0:8}-${ROOT_HASH:8:4}-${ROOT_HASH:12:4}-${ROOT_HASH:16:4}-${ROOT_HASH:20:12} + +# ------------------------------------------------------------------------------ +# make bootx64.efi +echo -n "rd.shell=0 quiet video=efifb:nobgrt audit=0 selinux=0 roothash=$ROOT_HASH systemd.verity_root_data=PARTUUID=$ROOT_UUID systemd.verity_root_hash=PARTUUID=$HASH_UUID resume=PARTLABEL=swap raid=noautodetect" > "$MY_TMPDIR"/options.txt +echo -n "$NAME $VERSION_ID" > "$MY_TMPDIR"/release.txt +objcopy \ + --add-section .release="$MY_TMPDIR"/release.txt --change-section-vma .release=0x20000 \ + --add-section .cmdline="$MY_TMPDIR"/options.txt --change-section-vma .cmdline=0x30000 \ + ${LOGO:+--add-section .splash="$LOGO" --change-section-vma .splash=0x40000} \ + --add-section .linux="$MY_TMPDIR"/linux --change-section-vma .linux=0x2000000 \ + --add-section .initrd="$MY_TMPDIR"/initrd --change-section-vma .initrd=0x3000000 \ + "${BASEDIR}"/linuxx64.efi.stub "$MY_TMPDIR"/bootx64.efi + + +mkdir -p "$OUTDIR" +mv "$MY_TMPDIR"/root-hash.txt \ + "$MY_TMPDIR"/bootx64.efi \ + "$MY_TMPDIR"/root.squashfs.img \ + "$MY_TMPDIR"/root.verity.img \ + "$MY_TMPDIR"/release.txt \ + "$MY_TMPDIR"/options.txt \ + "$MY_TMPDIR"/linux \ + "$MY_TMPDIR"/initrd \ + "$OUTDIR" diff --git a/quirks/nss_db.sh b/quirks/nss_db.sh new file mode 100644 index 0000000..5d42344 --- /dev/null +++ b/quirks/nss_db.sh @@ -0,0 +1,51 @@ + +sed -i -e 's#files#files db#g' "$sysroot"/etc/nsswitch.conf +mkdir -p "$sysroot"/usr/db +sed -i -e 's#/var/db#/usr/db#g' "$sysroot"/lib64/libnss_db-2*.so "$sysroot"/var/db/Makefile + +chroot "$sysroot" bash -c 'useradd -G wheel admin' +egrep -e '^(adm|wheel):.*' "$sysroot"/etc/group > "$sysroot"/etc/group.admin +egrep -e '^(adm|wheel):.*' "$sysroot"/etc/gshadow > "$sysroot"/etc/gshadow.admin + +sed -i -e '/^wheel:.*/d;/^adm:.*/d' "$sysroot"/etc/group "$sysroot"/etc/gshadow +sed -i -e '/^admin:.*/d' "$sysroot"/etc/passwd "$sysroot"/etc/shadow "$sysroot"/etc/group "$sysroot"/etc/gshadow + +chroot "$sysroot" bash -c 'make -C /var/db /usr/db/passwd.db /usr/db/shadow.db /usr/db/gshadow.db /usr/db/group.db && >/etc/passwd && > /etc/shadow && >/etc/group && >/etc/gshadow' +mv "$sysroot"/etc/group.admin "$sysroot"/etc/group +mv "$sysroot"/etc/gshadow.admin "$sysroot"/etc/gshadow +chroot "$sysroot" bash -c 'useradd admin; usermod -a -G wheel admin; echo -n admin | passwd --stdin admin' +#chroot "$sysroot" bash -c 'passwd -e admin' + +mkdir -p "$sysroot"/usr/share/factory/var +mv "$sysroot"/etc/passwd "$sysroot"/etc/sub{u,g}id "$sysroot"/etc/shadow "$sysroot"/etc/group "$sysroot"/etc/gshadow "$sysroot"/usr/share/factory/var + +sed -i -e 's!^# directory = /etc!directory = /var!g' "$sysroot"/etc/libuser.conf + +for i in passwd shadow group gshadow .pwd.lock subuid subgid; do + ln -sfnr "$sysroot"/var/"$i" "$sysroot"/etc/"$i" +done + +sed -i -e 's#/etc/passwd#/var/passwd#g;s#/etc/npasswd#/var/npasswd#g' "$sysroot"/usr/lib64/security/pam_unix.so +sed -i -e 's#/etc/shadow#/var/shadow#g;s#/etc/nshadow#/var/nshadow#g' "$sysroot"/usr/lib64/security/pam_unix.so +sed -i -e 's#/etc/.pwdXXXXXX#/var/.pwdXXXXXX#g' "$sysroot"/usr/lib64/security/pam_unix.so +sed -i -e 's#/etc/passwd#/var/passwd#g;s#/etc/shadow#/var/shadow#g;s#/etc/gshadow#/var/gshadow#g;s#/etc/group#/var/group#g;s#/etc/subuid#/var/subuid#g;s#/etc/subgid#/var/subgid#g' "$sysroot"/usr/sbin/user{add,mod,del} "$sysroot"/usr/sbin/group{add,mod,del} +sed -i -e 's#/etc/.pwd.lock#/var/.pwd.lock#g' \ + "$sysroot"/lib*/{,*/*/}libc.so.* \ + "$sysroot"/usr/lib*/librpmostree-1.so.1 \ + "$sysroot"/usr/lib/systemd/libsystemd-shared*.so + + +mkdir -p "$sysroot"/usr/share/factory/home +cp -avxr "$sysroot"/etc/skel "$sysroot"/usr/share/factory/home/admin +chown -R +1000.+1000 "$sysroot"/usr/share/factory/home/admin + +cat > "$sysroot"/usr/lib/tmpfiles.d/home.conf < "$sysroot"/usr/lib/tmpfiles.d/home.conf < "$sysroot"/etc/sssd/sssd.conf <> "$sysroot"/usr/lib/tmpfiles.d/sssd.conf <