From 2682f6a7441fe2b549f19d5453e9f8c785305bc2 Mon Sep 17 00:00:00 2001 From: Carlo Landmeter Date: Wed, 27 Jun 2018 12:55:19 +0000 Subject: use images from offical mirror Do not generate images locally but instead generate signatures locally and use images from offical mirror. - generate ipxe boot script from template - add option to start sshd with firstboot - add version information when selecting branch - verify netboot releases with gpg signature - added ncopa.asc gpg public key --- README.md | 37 ++++++--------- boot.ipxe | 105 ------------------------------------------ boot.ipxe.tpl | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++ build.lua | 51 +++++++++++++++++++++ config.sample.yaml | 23 ++++++++++ mknetboot.sh | 85 ---------------------------------- ncopa.asc | 52 +++++++++++++++++++++ sign_images.sh | 48 +++++++++++++++++++ update-netboot.sh | 93 ------------------------------------- 9 files changed, 319 insertions(+), 307 deletions(-) delete mode 100644 boot.ipxe create mode 100644 boot.ipxe.tpl create mode 100755 build.lua create mode 100644 config.sample.yaml delete mode 100755 mknetboot.sh create mode 100644 ncopa.asc create mode 100755 sign_images.sh delete mode 100755 update-netboot.sh diff --git a/README.md b/README.md index 65fe1aa..09da492 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,11 @@ Welcome to the Alpine Linux netboot server. -Netboot provides kernel initramfs and modloop images to boot over the -network/internet. Booting from netboot is provided by the IPXE binaries -available in alpine-ipxe `apk add alpine-ipxe` or from -[this location](alpine-ipxe) (x86_64 and aarch64). +This netboot server provides a boot script and image signatures to securly boot +Alpine Linux over the internet. To be able to boot you will need to have a copy +of the iPXE bootloader available. You can get a copy of the bootloaders by +installing alpine-ipxe `apk add alpine-ipxe` or from [this location](alpine-ipxe) +(only x86_64). ## Boot script @@ -16,28 +17,18 @@ build your own version of [ipxe](https://ipxe.org). Some cloud providers (ie [packet.net](https://help.packet.net/technical/infrastructure/custom-ipxe)) support the loading of custom ipxe scripts/payloads to install an operating -system. You can chainload one of the ipxe loaders from [alpine-ipxe](alpine-ipxe). -Loading our default boot script from another firware will disable image -verification. +system. You can chainload one of the ipxe bootloaders from [alpine-ipxe](alpine-ipxe). +Loading our boot script from another bootloader will disable image verification. ## Images -Images are hosted in the [Images](images) directory on boot.alpinelinux.org. -Current available images are: - -* **edge** - * [x86](images/edge/x86) - * [x86_64](images/edge/x86_64) - * [aarch64](images/edge/aarch64) -* **latest-stable** - * [x86](images/latest-stable/x86) - * [x86_64](images/latest-stable/x86_64) - * [aarch64](images/latest-stable/aarch64) +**NOTE**: since Alpine v3.8 this netboot server does not provide images anymore. +You can find netboot images in the release directories on our [mirrors](https://mirrors.alpinelinux.org). ## Signed images Alpine Linux images are signed and can be verified only by making use of -[alpine-ipxe](alpine-ipxe). Using another ipxe loader will disable verification. +[alpine-ipxe](alpine-ipxe). Using another ipxe bootloader will disable verification. ## Boot options @@ -55,14 +46,12 @@ Alpine Linux images are signed and can be verified only by making use of ### UEFI (aarch64) -* [snp.efi](alpine-ipxe/aarch64/snp.efi) UEFI executable - +* snp.efi UEFI executable ## Updates -Netboot images are updated every night automatically if any package in the -dependecy tree (kernel and alpine-base) has been updated. Regular packages are -updated automatically via our package repositories. +Currently we only support latest stable releases. We are working on adding montly +edge snapshots. ## Testing netboot diff --git a/boot.ipxe b/boot.ipxe deleted file mode 100644 index 217d7b2..0000000 --- a/boot.ipxe +++ /dev/null @@ -1,105 +0,0 @@ -#!ipxe - -set os Alpine Linux -iseq ${ipxe_cloud_config} packet && set provider (Packet.net) || -iseq ${alpine_loader} true && set img_verify true || set img_verify false -set console tty0 || -set cmdline_extra none || -set release latest-stable || -iseq ${buildarch} arm64 && goto arm64 || -cpuid --ext 29 && goto x86_64 || goto x86 - -:arm64 -set arch aarch64 || -set acpi acpi=force || -set console ttyAMA0 || -iseq ${ipxe_cloud_config} packet && set console ttyAMA0,115200 || -goto menu - -:x86_64 -set arch x86_64 || -iseq ${ipxe_cloud_config} packet && set console ttyS1,115200n8 || -goto menu - -:x86 -set arch x86 || -goto menu - -:menu -set space:hex 20:20 -set space ${space:string} -menu ${os} ${provider} [ ${arch} ] -item --gap Boot options -item release ${space} Choose release [ ${release} ] -item console ${space} Set console [ ${console} ] -iseq ${alpine_loader} true && item img_verify ${space} Image verification [ ${img_verify} ] || -item cmdline_extra ${space} Additional cmdline [ ${cmdline_extra} ] -item boot ${space} Boot with above settings -item --gap Utilities -item shell ${space} iPXE Shell -item reboot ${space} Reboot system -choose item -goto ${item} - -:release -menu ${os} [ ${arch} ] -item latest-stable Latest stable -item edge Edge (development) -choose release || goto alpine_exit -goto menu - -:console -menu ${os} [ ${arch} ] -item tty0 Console on tty0 -item ttyS0 Console on ttyS0 -item ttyS1 Console on ttyS1 -item ttyAMA0 Console on ttyAMA0 (aarch64) -item custom Enter custom console -choose console || goto menu -iseq ${console} custom && goto custom_console || -goto menu - -:custom_console -clear console -echo -n Enter console: && read console -goto menu - -:shell -echo Type "exit" to return to menu. -shell -goto menu - -:img_verify -iseq ${img_verify} true && set img_verify false || set img_verify true -goto menu - -:cmdline_extra -clear cmdline_extra -echo -n Enter extra cmdline options: && read cmdline_extra -goto menu - -:boot -iseq ${cmdline_extra} none && clear cmdline_extra || -isset ${console} && set console console=${console} || -set img-url https://boot.alpinelinux.org/images/${release}/${arch} -set repo-url http://dl-cdn.alpinelinux.org/alpine/${release}/main -imgfree -kernel ${img-url}/vmlinuz-vanilla initrd=initramfs-vanilla pkgs=libressl alpine_repo=${repo-url} modules=loop,squashfs modloop=${img-url}/modloop-vanilla nomodeset ${console} ${acpi} ${cmdline_extra} -initrd ${img-url}/initramfs-vanilla -iseq ${img_verify} true && goto verify_img || goto no_img_verify -:verify_img -imgverify vmlinuz-vanilla ${img-url}/vmlinuz-vanilla.sig -imgverify initramfs-vanilla ${img-url}/initramfs-vanilla.sig -:no_img_verify -boot -goto alpine_exit - -:reboot -reboot - -:poweroff -poweroff - -:alpine_exit -clear menu -exit 0 diff --git a/boot.ipxe.tpl b/boot.ipxe.tpl new file mode 100644 index 0000000..8f5db38 --- /dev/null +++ b/boot.ipxe.tpl @@ -0,0 +1,132 @@ +#!ipxe + +set os Alpine Linux +iseq ${ipxe_cloud_config} packet && set provider (Packet.net) || +iseq ${alpine_loader} true && set img_verify enabled || set img_verify disabled +set console tty0 || +set cmdline {{{cmdline}}} || +set default_cmdline default || +set start_sshd no || +set branch {{{default.branch}}} || +set version {{{default.version}}} || +set flavor {{{default.flavor}}} || +iseq ${buildarch} arm64 && goto arm64 || +cpuid --ext 29 && goto x86_64 || goto x86 + +:arm64 +set arch aarch64 || +set acpi acpi=force || +set console ttyAMA0 || +iseq ${ipxe_cloud_config} packet && set console ttyAMA0,115200 || +goto menu + +:x86_64 +set arch x86_64 || +iseq ${ipxe_cloud_config} packet && set console ttyS1,115200n8 || +goto menu + +:x86 +set arch x86 || +goto menu + +:menu +set space:hex 20:20 +set space ${space:string} +menu ${os} ${provider} [ ${arch} ] +item --gap Boot options +item branch ${space} Alpine version [ ${branch} ] +iseq ${arch} x86_64 && item flavor ${space} Kernel flavor [ ${flavor} ] || +iseq ${alpine_loader} true && item img_verify ${space} Image verification [ ${img_verify} ] || +item cmdline ${space} Linux cmdline [ ${default_cmdline} ] +item console ${space} Set console [ ${console} ] +item start_sshd ${space} Start sshd at first boot [ ${start_sshd} ] +item --gap Booting +item boot ${space} Boot with above settings +item --gap Utilities +item shell ${space} iPXE Shell +item reboot ${space} Reboot system +choose item +goto ${item} + +:branch +menu ${os} ${provider} [ ${arch} ] +{{#releases}} +item {{{branch}}} Version {{{version}}} +{{/releases}} +choose branch || goto shell +{{#releases}} +iseq branch {{{branch}}} && set version {{{version}}} || +{{/releases}} +goto menu + +:flavor +menu ${os} ${provider} [ ${arch} ] +{{#flavors}} +item {{{.}}} Linux {{{.}}} +{{/flavors}} +choose flavor || goto shell +goto menu + +:console +menu ${os} ${provider} [ ${arch} ] +{{#consoles}} +item {{{.}}} Console on {{{.}}} +{{/consoles}} +item custom Enter custom console +choose console || goto menu +iseq ${console} custom && goto custom_console || +goto menu + +:custom_console +clear console +echo -n Enter console: && read console +goto menu + +:shell +echo Type "exit" to return to menu. +shell +goto menu + +:img_verify +iseq ${img_verify} enabled && set img_verify disabled || set img_verify enabled +goto menu + +:cmdline +echo -n Enter extra cmdline options:${space} && read cmdline +set default_cmdline modified +goto menu + +:start_sshd +clear start_sshd +echo -n Enter url to ssh key:${space} && read ssh_key +isset ${ssh_key} && set start_sshd yes || set start_sshd no +iseq ${start_sshd} yes && set ssh_key ssh_key=${ssh_key} || clear ssh_key +goto menu + +:boot +isset ${console} && set console console=${console} || +set mirror {{{mirror}}} +set img-url ${mirror}/${branch}/releases/${arch}/netboot-${version} +set sig-url sigs/${branch}/${arch}/${version} +set repo-url ${mirror}/${branch}/main +set modloop-url ${img-url}/modloop-${flavor} +imgfree +kernel ${img-url}/vmlinuz-${flavor} ${cmdline} alpine_repo=${repo-url} modloop=${modloop-url} ${console} ${acpi} ${ssh_key} +initrd ${img-url}/initramfs-${flavor} +iseq ${img_verify} enabled && goto verify_img || goto no_img_verify +:verify_img +imgverify vmlinuz-${flavor} ${sig-url}/vmlinuz-${flavor}.sig +imgverify initramfs-${flavor} ${sig-url}/initramfs-${flavor}.sig +:no_img_verify +boot +goto alpine_exit + +:reboot +reboot + +:poweroff +poweroff + +:alpine_exit +clear menu +exit 0 diff --git a/build.lua b/build.lua new file mode 100755 index 0000000..c509502 --- /dev/null +++ b/build.lua @@ -0,0 +1,51 @@ +#!/usr/bin/lua5.3 + +local yaml = require("lyaml") +local http = require("socket.http") +local pfile = require("pl.file") +local ppath = require("pl.path") +local lustache = require("lustache") + +local cf = yaml.load(pfile.read("config.yaml")) +cf.releases = {} +local info = {} + +function get_release_info(release, arch) + local url = ("%s/%s/releases/%s/latest-releases.yaml"):format( + cf.mirror, release, arch) + local body, code = http.request(url) + if not body then error(code) end + + local res = yaml.load(body) + for k,v in ipairs(res) do + if v.flavor == "alpine-netboot" then return v end + end +end + +for _,branch in ipairs(cf.branches) do + for _,arch in ipairs(cf.archs) do + info = get_release_info(branch, arch) + if info then + if ppath.exists(("/var/www/localhost/htdocs/sigs/%s/%s/%s"):format( + info.branch, info.arch, info.version)) then + print(("Skipping: %s/%s/%s"):format( + info.branch, info.arch, info.version)) + else + info.origin_branch = branch + print(("Processing: %s/%s/%s"):format( + info.branch, info.arch, info.version)) + os.execute(("./sign_images.sh \"%s\" \"%s\" \"%s\""):format( + info.branch, info.arch, info.version)) + end + end + end + if branch == cf.default.branch then + cf.default.branch = info.branch + cf.default.version = info.version + end + table.insert(cf.releases, { branch=info.branch, version=info.version }) +end + +local tpl = pfile.read(cf.tpl) +print("Updating ipxe script: "..cf.ipxe) +pfile.write(cf.ipxe, lustache:render(tpl, cf)) diff --git a/config.sample.yaml b/config.sample.yaml new file mode 100644 index 0000000..4af1dea --- /dev/null +++ b/config.sample.yaml @@ -0,0 +1,23 @@ +--- +mirror: http://dl-cdn.alpinelinux.org/alpine +tpl: boot.ipxe.tpl +ipxe: /var/www/localhost/htdocs/boot-test.ipxe +branches: + - latest-stable +archs: + - x86 + - x86_64 + - aarch64 +consoles: + - tty0 + - ttyS0 + - ttyS1 + - ttyAMA0 +flavors: + - vanilla + - virt +cmdline: modules=loop,squashfs quiet nomodeset +default: + flavor: vanilla + branch: latest-stable +... \ No newline at end of file diff --git a/mknetboot.sh b/mknetboot.sh deleted file mode 100755 index 1c4d084..0000000 --- a/mknetboot.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh -e - -ARCH=$(apk --print-arch) -FLAVOR="vanilla" -FEATURE="base squashfs network zfs" -PACKAGE="spl-vanilla zfs-vanilla" -OUTDIR="$PWD/out" -RELEASE="edge" -MIRROR="http://dl-cdn.alpinelinux.org/alpine" - -usage() { - local ws=$(printf %${#0}s) - cat <<-EOF - - $0 [--arch ARCH] [--flavor FLAVOR] [--feature FEATURE] - $ws [--outdir OUTDIR] [--release RELEASE] [--repository REPO] - $0 --help - - options: - --arch Specify which architecture images to build - --flavor Specify which kernel flavor images to build - --feature Specify which initramfs features to include - --package Additional module or firmware package - --outdir Specify directory for the created images - --release Build images for specified release from main repository - --repository Package repository to use (overides --release) - --extra-repository Add repository to search packages from (overides --release) - - EOF -} - -# parse parameters -while [ $# -gt 0 ]; do - opt="$1" - shift - case "$opt" in - --arch) ARCH="$1"; shift ;; - --flavor) FLAVOR="$1"; shift ;; - --feature) FEATURE="$1"; shift ;; - --outdir) OUTDIR="$1"; shift ;; - --release) RELEASE="$1"; shift ;; - --repository) REPO="$1"; shift ;; - --extra-repository) EXTRAREPO="$EXTRAREPO $1"; shift ;; - --) break ;; - -*) usage; exit 1;; - esac -done - -rm -rf "$OUTDIR" -mkdir -p "$OUTDIR" - -REPOFILE=$(mktemp) -DEFAULT_REPO="$MIRROR/$RELEASE/main" -echo "${REPO:-$DEFAULT_REPO}" >> "$REPOFILE" -for repo in $EXTRAREPO; do - echo "$repo" >> "$REPOFILE" -done - -echo "Creating netboot image: $RELEASE/$ARCH/$FLAVOR" - -update-kernel \ - --arch "$ARCH" \ - --flavor "$FLAVOR" \ - --feature "$FEATURE" \ - --package "$PACKAGE" \ - --repositories-file "$REPOFILE" \ - "$OUTDIR" - -# older vanilla kernels do not have the flavor appended. -for file in vmlinuz config System.map; do - if [ -f "$OUTDIR"/$file ]; then - mv "$OUTDIR"/$file "$OUTDIR"/$file-"$FLAVOR" - fi -done - -# arm64 kernel is not a std bzImage but intead gzip compressed image -# iPXE efi mode (default for aarch64) does not support compressed kernel image -if [ "$ARCH" = "aarch64" ] && gunzip -t "$OUTDIR"/vmlinuz-"$FLAVOR" 2> /dev/null; then - TMP_KERNEL=$(mktemp) - zcat "$OUTDIR"/vmlinuz-"$FLAVOR" > $TMP_KERNEL && mv $TMP_KERNEL \ - "$OUTDIR"/vmlinuz-"$FLAVOR" - chmod 644 "$OUTDIR"/vmlinuz-"$FLAVOR" -fi - -rm -f "$REPOFILE" diff --git a/ncopa.asc b/ncopa.asc new file mode 100644 index 0000000..b4b34a5 --- /dev/null +++ b/ncopa.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +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 +Mkc= +=FcYC +-----END PGP PUBLIC KEY BLOCK----- diff --git a/sign_images.sh b/sign_images.sh new file mode 100755 index 0000000..3835c09 --- /dev/null +++ b/sign_images.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +branch=$1 +arch=$2 +version=$3 +mirror=http://dl-cdn.alpinelinux.org/alpine +sigs=/var/www/localhost/htdocs/sigs/$branch/$arch/$version +tarball=alpine-netboot-$version-$arch.tar.gz + +# CA Settings +CA_CRT="/etc/ssl/alpine-netboot-ca/ca.crt" +SIGN_CRT="/etc/ssl/alpine-netboot-ca/codesign.crt" +SIGN_KEY="/etc/ssl/alpine-netboot-ca/codesign.key" +PASS_FILE="/etc/ssl/alpine-netboot-ca/passwd" + +sign_image() { + local in=$1 out=$2 + echo "Signing image: $in" + openssl cms -sign -binary -noattr -in "$in" \ + -signer "$SIGN_CRT" -inkey "$SIGN_KEY" \ + -certfile "$CA_CRT" \ + -outform DER -out "$out" \ + -passin file:"$PASS_FILE" +} + +fetch_and_verify() { + for file in "$tarball" "$tarball".asc; do + wget -q -P "$tmpdir" "$mirror"/$branch/releases/$arch/$file + done + gpg --verify "$tmpdir/$tarball".asc "$tmpdir/$tarball" &> /dev/null +} + +tmpdir=$(mktemp -d) +mkdir -p "$sigs" && rm -f "$sigs"/* + +if fetch_and_verify; then + tar -C "$tmpdir" -zxvf "$tmpdir"/"$tarball" | while read file; do + case $file in + *modloop*|*vmlinuz*|*initramfs*) + sign_image "$tmpdir/$file" "$sigs/${file##*/}.sig" ;; + esac + done +else + echo "Failed to verify: $branch/$tarball" +fi + +rm -rf "$tmpdir" + diff --git a/update-netboot.sh b/update-netboot.sh deleted file mode 100755 index 99ff659..0000000 --- a/update-netboot.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -e - -REPO="http://dl-cdn.alpinelinux.org/alpine" -BRANCHES="edge latest-stable" -ARCHS="x86 x86_64 aarch64" -IMGDIR="/var/www/localhost/htdocs/images" - -# CA Settings -CA_CRT="/etc/ssl/alpine-netboot-ca/ca.crt" -SIGN_CRT="/etc/ssl/alpine-netboot-ca/codesign.crt" -SIGN_KEY="/etc/ssl/alpine-netboot-ca/codesign.key" -PASS_FILE="/etc/ssl/alpine-netboot-ca/passwd" - -if [ -f "/lib/libalpine.sh" ]; then - . /lib/libalpine.sh -else - echo "Error: cannot find libalpine.sh" >&2 - exit 1 -fi - -CACHE_DIR="/var/cache/alpine-netboot" -APK="apk --no-cache --repositories-file /dev/null" - -compare_files() { - [ -f "$1" ] || return 1 - [ -f "$2" ] || return 1 - diff -q "$1" "$2" > /dev/null 2>&1 -} - -# list all runtime depencencies for alpine-base -resolve_base() { - local branch="$1" - local arch="$2" - ALPINE_BASE=$($APK --arch $arch -X $REPO/$branch/main fetch -R --simulate alpine-base 2> /dev/null) - [ "$?" = "0" ] || die "Failed to get base dependency tree" - echo "$ALPINE_BASE" | grep -v '^fetch' | cut -d' ' -f2 -} - -# find the latest kernel and firmware. -# kernel/firmware deps are not interesting so we do not resolve the tree. -get_latest_kernel() { - local branch="$1" - local arch="$2" - KERNEL=$($APK --arch $arch -X $REPO/$branch/main search -x linux-vanilla linux-firmware) - [ "$?" = "0" ] || die "Failed to get kernel version" - echo "$KERNEL" | grep -v '^fetch' -} - -sign_images() { - local imgdir="$1" - local img - for img in vmlinuz initramfs; do - local file=$(realpath $imgdir/*${img}*) - echo "Signing image: $file" - openssl cms -sign -binary -noattr -in "$file" \ - -signer "$SIGN_CRT" -inkey "$SIGN_KEY" \ - -certfile "$CA_CRT" \ - -outform DER -out "$file".sig \ - -passin file:"$PASS_FILE" - done -} - - -############# -# M a i n # -############# - -mkdir -p "$CACHE_DIR" -tmpfile=$(mktemp) -tmpdir=$(mktemp -d) - -for branch in $BRANCHES; do - mkdir -p "$IMGDIR"/$branch - for arch in $ARCHS; do - echo "Checking: $branch/$arch" - for i in $(resolve_base $branch $arch && get_latest_kernel $branch $arch); do - echo "$i" >> $tmpfile - done - sort $tmpfile -o $tmpfile - if ! compare_files $tmpfile "$CACHE_DIR"/$branch-$arch.lst; then - echo "Dependencies updated for: $branch/$arch" - ./mknetboot.sh --release "$branch" --arch "$arch" --outdir "$tmpdir" - (cd "$tmpdir" && sha512sum * > alpine-netboot-$branch-$arch.sha512 || true) - sign_images "$tmpdir" - rm -rf "$IMGDIR"/$branch/$arch - mv "$tmpdir" "$IMGDIR"/$branch/$arch - mv "$tmpfile" "$CACHE_DIR"/$branch-$arch.lst - else - printf "No update found\n" - rm -f $tmpfile - fi - done -done -- cgit v1.2.3