Files
tailrescue-headscale-iso/scripts/build-live-iso.sh

210 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ARCH=${ARCH:-amd64}
WORKDIR=${WORKDIR:-/root/tailrescue-live-$ARCH}
OUTDIR=${OUTDIR:-/root/tailrescue-dist}
ISO_NAME=${ISO_NAME:-tailrescue-headscale-${ARCH}-$(date +%Y%m%d-%H%M).iso}
DIST=${DIST:-bookworm}
RESCUE_ENV=${RESCUE_ENV:-rescue.env}
AUTHORIZED_KEYS=${AUTHORIZED_KEYS:-templates/authorized_keys}
case "$ARCH" in
amd64) KERNEL_PKG=linux-image-amd64 ;;
i386) KERNEL_PKG=linux-image-686-pae ;;
*) echo "unsupported ARCH=$ARCH; use amd64 or i386" >&2; exit 2 ;;
esac
if [[ ! -f "$RESCUE_ENV" ]]; then
echo "missing $RESCUE_ENV; copy templates/rescue.env.example and fill field secrets" >&2
exit 2
fi
install -d "$WORKDIR" "$OUTDIR"
rm -rf "$WORKDIR"
mkdir -p "$WORKDIR"
cd "$WORKDIR"
lb config \
--distribution "$DIST" \
--architectures "$ARCH" \
--archive-areas "main contrib non-free non-free-firmware" \
--binary-images iso-hybrid \
--bootappend-live "boot=live components hostname=tailrescue username=rescue console=tty0 console=ttyS0,115200n8"
cat > config/package-lists/tailrescue.list.chroot <<PKGS
$KERNEL_PKG
systemd-sysv
openssh-server
sudo
curl
ca-certificates
gnupg
iptables
nftables
iproute2
iputils-ping
dnsutils
net-tools
isc-dhcp-client
pciutils
usbutils
lshw
parted
gdisk
fdisk
ntfs-3g
rsync
rclone
restic
smartmontools
gddrescue
pv
jq
tmux
vim-tiny
less
firmware-linux
firmware-linux-free
firmware-linux-nonfree
firmware-misc-nonfree
firmware-realtek
firmware-atheros
firmware-brcm80211
firmware-bnx2
firmware-bnx2x
firmware-iwlwifi
firmware-libertas
PKGS
mkdir -p config/includes.chroot/etc/apt/keyrings config/includes.chroot/etc/apt/sources.list.d
curl -fsSL https://pkgs.tailscale.com/stable/debian/${DIST}.noarmor.gpg \
-o config/includes.chroot/etc/apt/keyrings/tailscale-archive-keyring.gpg
case "$ARCH" in
amd64) TAILSCALE_DEB_ARCH=amd64 ;;
i386) TAILSCALE_DEB_ARCH=i386 ;;
esac
TAILSCALE_VERSION=${TAILSCALE_VERSION:-1.98.4}
TAILSCALE_DEB="tailscale_${TAILSCALE_VERSION}_${TAILSCALE_DEB_ARCH}.deb"
TAILSCALE_DEB_URL="https://pkgs.tailscale.com/stable/debian/pool/${TAILSCALE_DEB}"
mkdir -p config/packages.chroot
curl -fsSL "$TAILSCALE_DEB_URL" -o "config/packages.chroot/$TAILSCALE_DEB"
mkdir -p config/includes.chroot/etc/tailrescue
cp "$OLDPWD/$RESCUE_ENV" config/includes.chroot/etc/tailrescue/rescue.env
chmod 600 config/includes.chroot/etc/tailrescue/rescue.env
mkdir -p config/includes.chroot/usr/local/bin config/includes.chroot/etc/systemd/system
cat > config/includes.chroot/usr/local/bin/rescue-status <<"RS"
#!/bin/bash
set -euo pipefail
echo "== TailRescue Status =="
echo "Hostname: $(hostname)"
echo "Date: $(date -Is)"
echo "LAN IPs:"
ip -br addr || true
echo
echo "Routes:"
ip route || true
echo
echo "Tailscale:"
tailscale status || true
echo
echo "Disks:"
lsblk -o NAME,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS,MODEL || true
echo
echo "SSH: ssh rescue@<tailscale-ip>"
RS
chmod +x config/includes.chroot/usr/local/bin/rescue-status
cat > config/includes.chroot/usr/local/bin/list-disks <<"LD"
#!/bin/bash
exec lsblk -o NAME,TYPE,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS,MODEL,SERIAL "$@"
LD
chmod +x config/includes.chroot/usr/local/bin/list-disks
cat > config/includes.chroot/usr/local/bin/mount-ntfs-ro <<"MN"
#!/bin/bash
set -euo pipefail
if [ "$#" -ne 2 ]; then echo "usage: mount-ntfs-ro /dev/sdXN /mnt/windows" >&2; exit 2; fi
mkdir -p "$2"
exec ntfs-3g -o ro,show_sys_files,streams_interface=windows "$1" "$2"
MN
chmod +x config/includes.chroot/usr/local/bin/mount-ntfs-ro
cat > config/includes.chroot/usr/local/bin/tailrescue-firstboot <<"FB"
#!/bin/bash
set -u
exec > >(tee -a /var/log/tailrescue-firstboot.log) 2>&1
set -x
ENV_FILE=/etc/tailrescue/rescue.env
[ -f "$ENV_FILE" ] && . "$ENV_FILE"
RESCUE_USER=${RESCUE_USER:-rescue}
TAILSCALE_LOGIN_SERVER=${TAILSCALE_LOGIN_SERVER:-https://head.pharmq.kr}
TAILSCALE_TAGS=${TAILSCALE_TAGS:-tag:rescue}
mkdir -p /run/sshd
systemctl enable --now ssh || systemctl enable --now sshd || service ssh restart || /usr/sbin/sshd || true
systemctl enable --now tailscaled || service tailscaled start || true
sleep 3
if [ -n "${TAILSCALE_AUTHKEY:-}" ]; then
tailscale up --login-server "$TAILSCALE_LOGIN_SERVER" --authkey "$TAILSCALE_AUTHKEY" --hostname "tailrescue-$(cat /etc/machine-id | cut -c1-8)" --advertise-tags "$TAILSCALE_TAGS" || true
fi
rescue-status || true
FB
chmod +x config/includes.chroot/usr/local/bin/tailrescue-firstboot
cat > config/includes.chroot/etc/systemd/system/tailrescue-firstboot.service <<"SVC"
[Unit]
Description=TailRescue first boot SSH and Headscale enrollment
After=network-online.target tailscaled.service ssh.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/tailrescue-firstboot
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
SVC
mkdir -p config/includes.chroot/etc/systemd/system/multi-user.target.wants
ln -sf ../tailrescue-firstboot.service config/includes.chroot/etc/systemd/system/multi-user.target.wants/tailrescue-firstboot.service
mkdir -p config/hooks/normal
cat > config/hooks/normal/0900-tailrescue-users.hook.chroot <<"HOOK"
#!/bin/bash
set -eux
. /etc/tailrescue/rescue.env || true
USER_NAME=${RESCUE_USER:-rescue}
PASS_PLAIN=${RESCUE_PASSWORD:-}
if ! id "$USER_NAME" >/dev/null 2>&1; then useradd -m -s /bin/bash "$USER_NAME"; fi
if [ -n "$PASS_PLAIN" ]; then echo "$USER_NAME:$PASS_PLAIN" | chpasswd; fi
usermod -aG sudo "$USER_NAME"
echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/90-rescue
chmod 0440 /etc/sudoers.d/90-rescue
mkdir -p /home/$USER_NAME/.ssh /root/.ssh
if [ -f /etc/tailrescue/authorized_keys ]; then
cp /etc/tailrescue/authorized_keys /home/$USER_NAME/.ssh/authorized_keys
cp /etc/tailrescue/authorized_keys /root/.ssh/authorized_keys
fi
chown -R $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh
chmod 700 /home/$USER_NAME/.ssh /root/.ssh
chmod 600 /home/$USER_NAME/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null || true
sed -i "s/^#\?PasswordAuthentication .*/PasswordAuthentication yes/" /etc/ssh/sshd_config || true
sed -i "s/^#\?PermitRootLogin .*/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config || true
sed -i "s/^#\?PubkeyAuthentication .*/PubkeyAuthentication yes/" /etc/ssh/sshd_config || true
grep -q "^AllowUsers " /etc/ssh/sshd_config && sed -i "s/^AllowUsers .*/AllowUsers $USER_NAME root/" /etc/ssh/sshd_config || echo "AllowUsers $USER_NAME root" >> /etc/ssh/sshd_config
HOOK
chmod +x config/hooks/normal/0900-tailrescue-users.hook.chroot
if [[ -f "$OLDPWD/$AUTHORIZED_KEYS" ]]; then
cp "$OLDPWD/$AUTHORIZED_KEYS" config/includes.chroot/etc/tailrescue/authorized_keys
elif [[ -f "$OLDPWD/templates/authorized_keys.example" ]]; then
cp "$OLDPWD/templates/authorized_keys.example" config/includes.chroot/etc/tailrescue/authorized_keys
fi
lb build
cp -f "live-image-${ARCH}.hybrid.iso" "$OUTDIR/$ISO_NAME"
(cd "$OUTDIR" && sha256sum "$ISO_NAME" > "SHA256SUMS.${ARCH}" && cp "SHA256SUMS.${ARCH}" SHA256SUMS && echo "$ISO_NAME" > "latest.${ARCH}.txt" && cp "latest.${ARCH}.txt" latest.txt)
echo "$OUTDIR/$ISO_NAME"