From 4026274721240097cdb8f1b27a1729d8bf9f1c19 Mon Sep 17 00:00:00 2001 From: macmpi <16296055+macmpi@users.noreply.github.com> Date: Fri, 17 Nov 2023 10:08:04 +0100 Subject: [PATCH] version 1.1 improved interfaces detection: fixes https://github.com/macmpi/alpine-linux-headless-bootstrap/issues/20 make.sh: tighten-up archive construction (reproducibility) --- README.md | 7 +- headless.apkovl.tar.gz | Bin 7263 -> 7547 bytes make.sh | 34 ++++--- overlay/usr/local/bin/headless_bootstrap | 123 +++++++++++++---------- sample_unattended.sh | 1 + 5 files changed, 94 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index c906df8..8427b02 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Please follow [Alpine Linux Wiki](https://wiki.alpinelinux.org/wiki/Installation Tools provided here can be used on any plaform for any install modes (diskless, data disk, system disk). Just add [**headless.apkovl.tar.gz**](https://is.gd/apkovl_master)[^2] overlay file *as-is* at the root of Alpine Linux boot media (or onto any custom side-media) and boot-up the system.\ -With default DCHP-based network interface definitions (and [SSID/pass file](#extra-configuration) if using wifi), system can then be remotely accessed with: `ssh root@`\ +With default DCHP-based network interface definitions (and [SSID/pass](#extra-configuration) file if using wifi), system can then be remotely accessed with: `ssh root@`\ (system IP address may be determined with any IP scanning tools such as `nmap`). As with Alpine Linux initial bring-up, `root` account has no password initially (change that during target setup!).\ @@ -29,7 +29,7 @@ Extra files may be added next to `headless.apkovl.tar.gz` to customise boostrapp **Goody:** seamless USB-serial & USB-ethernet gadget mode (PiZero for instance):\ On supporting Pi devices, just add `dtoverlay=dwc2,dr_mode=peripheral` in `usercfg.txt` (or `config.txt`), and plug USB cable into host Computer port.\ -Serial terminal can then be connected-to from host Computer (xon/xoff flow control: e.g. on Linux with `cu -l ttyACM0`).\ +Serial terminal can then be connected-to from host Computer (e.g. `cu -l ttyACM0` on Linux. xon/xoff flow control).\ Alternatively, with host Computer set-up to share networking with USB interface as 10.42.0.1 gateway, one can log into device from host with: `ssh root@10.42.0.2`. Main execution steps are logged: `cat /var/log/messages | grep headless`. @@ -44,7 +44,8 @@ Main execution steps are logged: `cat /var/log/messages | grep headless`. ## Want to tweak more ? This repository may be forked/cloned/downloaded.\ Main script file is [`headless.start`](https://github.com/macmpi/alpine-linux-headless-bootstrap/tree/main/overlay/usr/local/bin/headless_bootstrap).\ -Execute `./make.sh` to rebuild `headless.apkovl.tar.gz` after changes. +Execute `./make.sh` to rebuild `headless.apkovl.tar.gz` after changes.\ +(requires `busybox`; check `busybox` build options if not running from Alpine or Ubuntu) ## Credits diff --git a/headless.apkovl.tar.gz b/headless.apkovl.tar.gz index c468d2f458cd118ac1d7abf5805983e679222c92..8a57b83d8c4d9a00aef5eeab6b579d268fb77a0a 100644 GIT binary patch literal 7547 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 RchCRx^FNd+aH;@!004hQ8tMQ5 literal 7263 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 /dev/null || alias doas="/usr/bin/sudo" build_path="$(mktemp -d)" if [ -n "$build_path" ]; then - cp -r overlay "$build_path"/. - find "$build_path"/overlay/ -exec touch -md "$(date '+%F 00:00:00')" {} \; - - # setting owner/groups for runtime (won't affect mtime) + # prefer timestamp option for touch as it works on directories too + t_stamp="$( TZ=UTC date +%Y%m%d0000.00 )" + cp -a overlay "$build_path"/. + find "$build_path"/overlay/ -exec sh -c 'TZ=UTC touch -chm -t "$0" "$1"' "$t_stamp" {} \; + # setting modes and owner/groups for runtime (won't affect mtime) find "$build_path"/overlay/etc -type d -exec chmod 755 {} \; - chmod +x "$build_path"/overlay/etc/init.d/* - find "$build_path"/overlay/usr -type d -exec chmod 755 {} \; - chmod +x "$build_path"/overlay/usr/local/bin/* + chmod 755 "$build_path"/overlay/etc/init.d/* + chmod 755 "$build_path"/overlay/etc/runlevels/default/* chmod 777 "$build_path"/overlay/tmp chmod 700 "$build_path"/overlay/tmp/.trash - chmod 600 "$build_path"/overlay/tmp/.trash/ssh_host_*_key - doas chown -R 0:0 "$build_path"/overlay/* - - doas tar -cvf "$build_path"/headless.apkovl.tar -C "$build_path"/overlay etc usr tmp - gzip -nk9 "$build_path"/headless.apkovl.tar && mv "$build_path"/headless.apkovl.tar.gz . - touch -md "$(date '+%F 00:00:00')" headless.apkovl.tar.gz + chmod -R 600 "$build_path"/overlay/tmp/.trash/ssh_host_*_key + find "$build_path"/overlay/usr -type d -exec chmod 755 {} \; + chmod 755 "$build_path"/overlay/usr/local/bin/* + doas chown -Rh 0:0 "$build_path"/overlay/* + # busybox config on Alpine & Ubuntu has FEATURE_TAR_GNU_EXTENSIONS + # (will preserve user/group/modes & mtime) and FEATURE_TAR_LONG_OPTIONS + # shellcheck disable=SC2046 # we want word splitting as result of find + doas tar cv -C "$build_path"/overlay --no-recursion \ + $(doas find "$build_path"/overlay/ | sed "s|$build_path/overlay/||" | sort | xargs ) | \ + gzip -c9n > headless.apkovl.tar.gz + TZ=UTC touch -cm -t "$t_stamp" headless.apkovl.tar.gz doas rm -rf "$build_path" fi diff --git a/overlay/usr/local/bin/headless_bootstrap b/overlay/usr/local/bin/headless_bootstrap index 485f5f8..6ba5a96 100755 --- a/overlay/usr/local/bin/headless_bootstrap +++ b/overlay/usr/local/bin/headless_bootstrap @@ -3,7 +3,7 @@ # SPDX-FileCopyrightText: Copyright 2022-2023, macmpi # SPDX-License-Identifier: MIT -HDLSBSTRP_VERSION="1.0" +HDLSBSTRP_VERSION="1.1" _apk() { local cmd="$1" @@ -29,7 +29,7 @@ _apk() { _preserve() { # create a back-up of element (file, folder, symlink) [ -z "${1}" ] && return 1 - [ -e "$1" ] && cp -a "$1" "${1}.orig" + [ -e "${1}" ] && cp -a "${1}" "${1}".orig } _restore() { @@ -37,7 +37,7 @@ _restore() { # previous back-up if available [ -z "${1}" ] && return 1 rm -rf "${1}" - [ -e "${1}.orig" ] && mv -f "${1}.orig" "${1}" + [ -e "${1}".orig ] && mv -f "${1}".orig "${1}" } # shellcheck disable=SC2142 # known special case @@ -69,7 +69,7 @@ cat <<-EOF >> /tmp/.trash/headless_cleanup rm -f /usr/local/bin/headless_bootstrap # Run unattended script if available - install -m755 "${ovlpath}/unattended.sh" /tmp/headless_unattended > /dev/null 2>&1 && \ + install -m755 "${ovlpath}"/unattended.sh /tmp/headless_unattended > /dev/null 2>&1 && \ _logger "Starting headless_unattended service" && \ rc-service headless_unattended start @@ -99,7 +99,7 @@ cat <<-EOF > /etc/ssh/sshd_config EOF # Client authorized_keys or no authentication -if install -m600 "${ovlpath}/authorized_keys" /tmp/.trash/authorized_keys > /dev/null 2>&1; then +if install -m600 "${ovlpath}"/authorized_keys /tmp/.trash/authorized_keys > /dev/null 2>&1; then _logger "Enabling public key SSH authentication..." cat <<-EOF >> /etc/ssh/sshd_config AuthenticationMethods publickey @@ -161,58 +161,66 @@ _logger "Internet access: $status" _setup_networking() { ## Setup Network interfaces -if [ -d "/sys/class/net/wlan0" ] && [ -f "${ovlpath}/wpa_supplicant.conf" ]; then +local has_wifi +_has_wifi() { return "$has_wifi"; } + +find /sys/class/ieee80211/*/device/net/* -maxdepth 0 -type d -exec basename {} \; > /tmp/.wlan_list 2>/dev/null +[ -s /tmp/.wlan_list ] && [ -f "${ovlpath}"/wpa_supplicant.conf ] +has_wifi=$? +if _has_wifi; then _logger "Configuring wifi..." _apk add wpa_supplicant _preserve "/etc/wpa_supplicant/wpa_supplicant.conf" - install -m600 "${ovlpath}/wpa_supplicant.conf" /etc/wpa_supplicant/wpa_supplicant.conf + install -m600 "${ovlpath}"/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf + rc-service wpa_supplicant restart else - _logger "No wifi interface or setup file supplied" + _logger "No wifi interface or SSID/pass file supplied" fi _preserve "/etc/network/interfaces" -if ! install -m644 "${ovlpath}/interfaces" /etc/network/interfaces > /dev/null 2>&1; then - # set default interfaces if not specified by interface file on boot storage +if ! install -m644 "${ovlpath}"/interfaces /etc/network/interfaces > /dev/null 2>&1; then _logger "No interfaces file supplied, building defaults..." + cat <<-EOF > /etc/network/interfaces + auto lo + iface lo inet loopback + + EOF for dev in /sys/class/net/*; do - dev="$(basename "$dev")" - case ${dev%%[0-9]*} in + # shellcheck disable=SC2034 # Unused IFINDEX while still sourced from uevent + local DEVTYPE INTERFACE IFINDEX + DEVTYPE="" + # shellcheck source=/dev/null + . "$dev"/uevent + case ${INTERFACE%%[0-9]*} in lo) - cat <<-EOF >> /etc/network/interfaces - auto $dev - iface $dev inet loopback - - EOF - ;; + ;; eth) + cat <<-EOF >> /etc/network/interfaces + auto $INTERFACE + iface $INTERFACE inet dhcp + + EOF + ;; + *) + _has_wifi && grep -q "$INTERFACE" /tmp/.wlan_list && \ cat <<-EOF >> /etc/network/interfaces - auto $dev - iface $dev inet dhcp + auto $INTERFACE + iface $INTERFACE inet dhcp - EOF - ;; - wlan) - [ -f /etc/wpa_supplicant/wpa_supplicant.conf ] && cat <<-EOF >> /etc/network/interfaces - auto $dev - iface $dev inet dhcp + EOF + [ "$DEVTYPE" = "gadget" ] && \ + cat <<-EOF >> /etc/network/interfaces && cat <<-EOF > /etc/resolv.conf + auto $INTERFACE + iface $INTERFACE inet static + address 10.42.0.2/24 + gateway 10.42.0.1 - EOF - ;; - usb) - cat <<-EOF >> /etc/network/interfaces - auto $dev - iface $dev inet static - address 10.42.0.2/24 - gateway 10.42.0.1 + EOF + nameserver 208.67.222.222 + nameserver 208.67.220.220 - EOF - - cat <<-EOF > /etc/resolv.conf - nameserver 208.67.222.222 - nameserver 208.67.220.220 - - EOF - ;; + EOF + ;; esac done fi @@ -226,25 +234,31 @@ _preserve "/etc/hostname" echo "alpine-headless" > /etc/hostname hostname -F /etc/hostname -grep -q "wlan" /etc/network/interfaces && \ - [ -f /etc/wpa_supplicant/wpa_supplicant.conf ] && \ - rc-service wpa_supplicant restart rc-service networking restart +rm -f /tmp/.wlan_list } _setup_gadget() { -# load composite USB Serial/USB Ethernel driver & setup terminal +## load composite USB Serial/USB Ethernel driver & setup terminal _logger "Enabling USB-gadget Serial and Ethernet ports" lsmod | grep -q "dwc2" || modprobe -qs dwc2 -modprobe -qs g_cdc -# default config: xon/xoff flow control -stty -g -F /dev/ttyGS0 >/dev/null 2>&1 && setconsole /dev/ttyGS0 +# remove conflicting modules in case they were initially loaded (cmdline.txt) +modprobe -rq g_serial g_ether g_cdc +modprobe -q g_cdc && sleep 1 +# once driver has settled check if cable is connected: unload if not +[ "$( cat "$udc_gadget"/current_speed )" = "UNKNOWN" ] && \ + _logger "USB cable not connected !!" && modprobe -rq g_cdc && return 1 + +# default serial config: xon/xoff flow control +stty -g -F /dev/ttyGS0 >/dev/null 2>&1 # notes to users willing to connect from Linux Ubuntu-based host terminal: # - user on host needs to be part of dialout group (reboot required), and # - disable spurious AT commands from ModemManager on host-side Gadget serial port # you may create a /etc/udev/rules.d/99-ttyacms-gadget.rules as per: # https://linux-tips.com/t/prevent-modem-manager-to-capture-usb-serial-devices/284/2 # ATTRS{idVendor}=="0525" ATTRS{idProduct}=="a4aa", ENV{ID_MM_DEVICE_IGNORE}="1" + +setconsole /dev/ttyGS0 } @@ -258,9 +272,10 @@ _logger "Alpine Linux headless bootstrap v$HDLSBSTRP_VERSION by macmpi" # help randomness for wpa_supplicant and sshd (urandom until 3.16) rc-service seedrng restart || rc-service urandom restart -# setup USB gadget mode if device has compatible device-tree -find /proc/device-tree/soc/usb* -name "dr_mode" -print0 | \ - xargs -0 grep -q "peripheral" && _setup_gadget +# setup USB gadget mode if such device mode is enabled +udc_gadget="$( dirname "$( find -L /sys/class/udc/* -maxdepth 2 -type f -name "is_a_peripheral" 2>/dev/null)" )" +[ "$( cat "$udc_gadget"/is_a_peripheral 2>/dev/null )" = "0" ] && \ + _setup_gadget # Determine ovl file location # grab used ovl filename from dmesg @@ -293,10 +308,10 @@ _setup_networking # Test latest available version online # Can be skipped by creating a 'opt-out'-named dummy file aside apkovl file -[ -f "${ovlpath}/opt-out" ] || _tst_version & +[ -f "${ovlpath}"/opt-out ] || _tst_version & # setup sshd unless unattended.sh script prevents it -grep -q "^#NO_SSH$" "${ovlpath}/unattended.sh" > /dev/null 2>&1 \ +grep -q "^#NO_SSH$" "${ovlpath}"/unattended.sh > /dev/null 2>&1 \ || _setup_sshd _prep_cleanup diff --git a/sample_unattended.sh b/sample_unattended.sh index 7eea175..110e74f 100644 --- a/sample_unattended.sh +++ b/sample_unattended.sh @@ -98,6 +98,7 @@ cat <<-EOF > /tmp/ANSWERFILE # trick setup-alpine to pretend existing SSH connection # and therefore keep (do not reset) network interfaces while running in background +# requires alpine-conf 3.15.1 and later, available from Alpine 3.17 SSH_CONNECTION="FAKE" setup-alpine -ef /tmp/ANSWERFILE lbu commit -d