diff options
Diffstat (limited to 'src/routes/blog/posts/alpine-ssh-early-initfs.svx')
| -rw-r--r-- | src/routes/blog/posts/alpine-ssh-early-initfs.svx | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/routes/blog/posts/alpine-ssh-early-initfs.svx b/src/routes/blog/posts/alpine-ssh-early-initfs.svx new file mode 100644 index 0000000..f284caf --- /dev/null +++ b/src/routes/blog/posts/alpine-ssh-early-initfs.svx @@ -0,0 +1,109 @@ +--- +title: "Launching SSH during early boot with mkinitfs" +blurb: "Replacing the early init with our own script to launch SSH, killing it in early userspace, and allowing remote disk decryption in the mean time" +author: "7222e800" +slug: "alpine-ssh-early-initfs-disk-decryption" +id: 1768406136 + +# Timestamps are in ISO8601 UTC (`date -u +%Y-%m-%dT%H:%M:%SZ`) +created: "2026-01-14T15:53:57Z" +updated: "2026-01-14T15:53:57Z" +published: false +--- + +For a while, this one's been meaning to setup an early-boot SSH environment for +Alpine Linux on systems that are using a +[System Disk](https://wiki.alpinelinux.org/wiki/System_Disk_Mode) installation +mode. + +<!-- TODO: APKOVL boot article --> +In [Data Disk](https://wiki.alpinelinux.org/wiki/Data_Disk_Mode) mode, it can +be handled in `boot`, or if needed, `sysinit`. This can even be nicely netbooted +via a netbooted apkovl - article on that eventually. (for now, if you're +interested in that, here's a good starting point: +[alpine/mkinitfs#cc4954b/initramfs-init.in](https://gitlab.alpinelinux.org/alpine/mkinitfs/-/blob/cc4954bc73cf55833b48624232b9c42ca3abc390/initramfs-init.in#L647)) + +On System Disk installations, with tooling like [dracut](https://wiki.gentoo.org/wiki/Dracut), +this would also be trivial. Unfortunately, this one's a masochist and like +staying close to the intended upstream Alpine installation + +> **Note**<br/> +> Alpine does have +> [a package](https://pkgs.alpinelinux.org/package/v3.23/community/x86_64/dracut) +> for dracut, and the reader may want to look into using it instead. + +## mkinitfs and it's challenges + +Alpine's [mkinitfs](https://gitlab.alpinelinux.org/alpine/mkinitfs/) allows us +to do things like including files or kernel modules in the image, via their +[features.d](https://gitlab.alpinelinux.org/alpine/mkinitfs/-/tree/master/features.d). +This is nice and all, but on it's own, we can only really give the kernel a +module, or a file we manually call by spamming enter through the encryption +password prompts and running via the 'Emergency Shell'. + +## some code + +```ts +/* + Copyright (C) 2024-2026 memdmp + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by Affero, Inc., at version 1. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Affero General Public License for more details. + + You should have received a copy of the Affero General Public License along with this program. If not, see <https://spdx.org/licenses/AGPL-1.0-only>. +*/ +import { Animation, MultiObjectKeyframe } from '@memdmp/keyframegen'; +import { + biosStepInterval, + biosSteps, + getDelay, + login, + ttyLines, +} from './shared.ts'; +import fs from 'node:fs'; +import esbuild from 'esbuild'; +console.log('hi'); +const anim = new Animation(); +let ttyCtr = 0; +const stages = [ + anim.selector('.anmroot #bios'), + anim.selector('.anmroot #grub'), + anim.selector('.anmroot #grub-term'), + anim.selector('.anmroot #openrc'), + ...ttyLines.flatMap((v) => + v.kind === 'clear' ? [anim.selector('.anmroot #tty-' + ttyCtr++)] : [], + ), +]; +const handleSteps: Step[] = [ + // (n) => { + // toStage(0); + // anim.in(500, n); + // }, + ...biosStepHandlers, + ...grubStepHandlers, + ...openrcStepHandlers(1), + ...ttyStepHandlers, + (n) => { + const s = anim.selector('.anmroot #app .hidden-after-anim'); + s.style(visibleStyles); + anim._internal_timeline.now += 1; + s.style(hiddenStyles); + anim.in(1000, n); + }, +]; +fs.writeFileSync( + 'src/routes/anim.css', + `${comment} +${esbuild.buildSync({ + stdin: { + contents: `${exported} +${tail}`, + loader: 'css', + }, + write: false, + minify: false, + }).outputFiles![0].text + }`, +); +``` |