diff --git a/src/modules/headless_nm/config b/src/modules/headless_nm/config new file mode 100755 index 00000000..899f61da --- /dev/null +++ b/src/modules/headless_nm/config @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +#Shebang for better file detection +#### headless_nm install module +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2024 - till today +#### https://github.com/mainsail-crew/MainsailOS +#### +#### This File is distributed under GPLv3 +#### + +# shellcheck disable=all + +# DO NOT MODIFY BELOW THIS LINE UNLESS YOU KNOW CONSEQUENCES... + +[ -n "$HEADLESS_NM_DEPS" ] || HEADLESS_NM_DEPS="network-manager dos2unix uuid" diff --git a/src/modules/headless_nm/filesystem/boot/WiFi-README.txt b/src/modules/headless_nm/filesystem/boot/WiFi-README.txt new file mode 100644 index 00000000..e32757a6 --- /dev/null +++ b/src/modules/headless_nm/filesystem/boot/WiFi-README.txt @@ -0,0 +1,59 @@ +Wifi-README.txt + +################################################################################ +#### IMPORTANT WARNING #### +################################################################################ +#### #### +#### First, make sure you have a decent text editor of your choice. #### +#### Notepad++, VSCode, SublimeText or similar are recommended. #### +#### #### +#### Do not use Wordpad to edit this file, it will corrupt it and your #### +#### configuration will not work. #### +#### #### +#### If you use Textedit to edit this file, #### +#### be sure to use "plain text format" and "disable smart quotes" #### +#### in "Textedit > Preferences", otherwise Textedit will use #### +#### incompatible characters and your network configuration won't work! #### +#### #### +################################################################################ + +How do I setup a new network on my OS_NAME ? +-------------------------------------------- + +1.) Copy and paste the 'headless_nm.txt.template'. + Rename this file to 'headless_nm.txt' + +2.) Now open the file with your favourite text editor. + Windows and MacOS users please read the note above! + + This file is pretty self explaining, just the 'REGDOMAIN' + needs some explaination: + + Valid country codes are: + + GB (United Kingdom) + FR (France) + DE (Germany) + US (United States) + SE (Sweden) + + For a complete list, please visit https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + +3.) Remove the SD card afterwards. + +4.) Almost done... Please put the SD card back into your SBC and wait for it to connect. + +NOTE: + +Plug in a monitor and watch the console output to get its IP address or +consult your router's setup page to get this information. + +You could also try to reach it by its hostname. + + http://.local + +If you did not change the hostname during the initial flash, you could use + + http://OS_NAME.local + +5.) Enjoy OS_NAME :) diff --git a/src/modules/headless_nm/filesystem/boot/headless_nm.txt.template b/src/modules/headless_nm/filesystem/boot/headless_nm.txt.template new file mode 100644 index 00000000..18d5d1a3 --- /dev/null +++ b/src/modules/headless_nm/filesystem/boot/headless_nm.txt.template @@ -0,0 +1,14 @@ +#### Headless Wifi configuration + +# Your Wifis SSID +SSID="" + +# Your WiFis password +PASSWORD="" + +# Is your SSID in hidden state? [true/false] +HIDDEN="false" + +# Wifi Country code +# See Wifi-README.txt for details! +REGDOMAIN="US" diff --git a/src/modules/headless_nm/filesystem/etc/systemd/system/headless_nm.service b/src/modules/headless_nm/filesystem/etc/systemd/system/headless_nm.service new file mode 100644 index 00000000..a9e22680 --- /dev/null +++ b/src/modules/headless_nm/filesystem/etc/systemd/system/headless_nm.service @@ -0,0 +1,20 @@ +#### headless_nm service +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2024 +#### https://github.com/mainsail-crew/MainsailOS +#### +#### This File is distributed under GPLv3 +#### + +[Unit] +Description=Setup Wifi on headless machines using NetworkManager +Before=network.target NetworkManager.service + +[Service] +Type=oneshot +StandardOutput=tty +ExecStart=/usr/local/bin/headless_nm + +[Install] +WantedBy=multi-user.target diff --git a/src/modules/headless_nm/filesystem/usr/local/bin/headless_nm b/src/modules/headless_nm/filesystem/usr/local/bin/headless_nm new file mode 100755 index 00000000..44649e34 --- /dev/null +++ b/src/modules/headless_nm/filesystem/usr/local/bin/headless_nm @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +#### headless_nm +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2024 - till today +#### https://github.com/mainsail-crew/MainsailOS +#### +#### This File is distributed under GPLv3 +#### + +#### Description: +#### This is a wrapper for network manager to be able to setup +#### Wifi connections on headless SBC. +#### Takes setup from a file in /boot (/boot/firmware) and recreates +#### Raspberrys 'preconfigured.nmconnection' + +#### Copyright hint: This file contains code snippets from +#### Raspberrys raspi-config therefore it applies also there license +#### and copyrights! +#### See https://github.com/RPi-Distro/raspi-config/blob/bookworm/LICENSE + +#### It also reuses parts of raspberry-sys-mods +#### See https://github.com/RPi-Distro/raspberrypi-sys-mods/blob/bookworm/usr/lib/raspberrypi-sys-mods/imager_custom + +set -e + +# Global Vars +DISTRO="" +CMDLINE="/boot/firmware/cmdline.txt" +ARMBIANENV="/boot/armbianEnv.txt" +UUID="" +PSK_HASH="" +KEYMGMT="wpa-psk" +CONNFILE=/etc/NetworkManager/system-connections/preconfigured.nmconnection +SETUPFILE="$(find /boot -name "headless_nm.txt")" +REGDOMAIN="" +CFG80211="/etc/modprobe.d/cfg80211.conf" + + +# functions +log() { + local msg + msg="${1}" + logger -t headless_nm "${msg}" +} + +get_distro() { + local armbian rpi + armbian="$(find /boot -name "$(basename ${ARMBIANENV})")" + rpi="$(find /boot -name "$(basename ${CMDLINE})")" + log "Determine distribution ..." + if [[ -n "${armbian}" ]]; then + DISTRO="armbian" + elif [[ -n "${rpi}" ]]; then + DISTRO="rpi" + else + DISTRO="" + log "Could not determine distribution ... Exiting!" + exit 1 + fi + if [[ -n "${DISTRO}" ]]; then + log "Using setup profile: ${DISTRO} ..." + fi +} + +get_config() { + # shellcheck disable=SC1090 + source "${SETUPFILE}" +} + +gen_uuid() { + log "Generating UUID for connection..." + UUID="$(uuid -v4)" + declare -r UUID +} + +gen_nmconnection() { +cat <<- EOF >"${CONNFILE}" +[connection] +id=preconfigured +uuid=${UUID} +type=wifi +[wifi] +mode=infrastructure +ssid=${SSID} +hidden=${HIDDEN,,} +[ipv4] +method=auto +[ipv6] +addr-gen-mode=default +method=auto +[proxy] +EOF +} + +gen_keymgmt() { + PSK_HASH="$(gen_psk)" + if [[ -n "${PASSWORD}" ]]; then + cat <<- EOF >>${CONNFILE} +[wifi-security] +key-mgmt=${KEYMGMT} +psk=${PSK_HASH} +EOF +fi +} + +gen_psk() { + wpa_passphrase "${SSID}" "${PASSWORD}" | sed -n "/^.*[ \t]psk.*/s/[ \t]psk=//p" +} + +set_regdomain() { + log "Set registration domain to '${REGDOMAIN}' ..." + # Shameless borrowed from + # https://github.com/RPi-Distro/raspi-config/blob/d22643ade3851c42648f3676e577a622c34af49a/raspi-config#L830C3-L832C5 + if ! ischroot; then + iw reg set "${REGDOMAIN}" + fi + # set permanent + case "${DISTRO}" in + "rpi") + # Shameless borrowed from + # https://github.com/RPi-Distro/raspi-config/blob/d22643ade3851c42648f3676e577a622c34af49a/raspi-config#L822C3-L825C15 + sed -i \ + -e "s/\s*cfg80211.ieee80211_regdom=\S*//" \ + -e "s/\(.*\)/\1 cfg80211.ieee80211_regdom=$REGDOMAIN/" \ + "${CMDLINE}" + ;; + "armbian") + if [[ -f "${CFG80211}" ]]; then + rm -f "${CFG80211}" + fi + echo "options cfg80211 ieee80211_regdom=${REGDOMAIN}" > "${CFG80211}" + ;; + esac +} + +# MAIN +main() { + # Determine base distribution + get_distro + + # Check setup file is present + if [[ -f "${SETUPFILE}" ]]; then + log "Configuration file found in ${SETUPFILE}, continuing...\n" + else + log "Configuration file not found! Nothing to do, exiting...\n" + exit 0 + fi + + # Generate UUID + gen_uuid + + # Remove preconfiguration if present + if [[ -f "${CONNFILE}" ]]; then + rm -f "${CONNFILE}" + fi + + # Read config file + get_config + + # Generate preconfigured.nmconnection file + gen_nmconnection + + # Add key management and psk to preconfigured.nmconnection file + gen_keymgmt + + # Set REGDOMAIN + set_regdomain + + # NetworkManager only accepts 0600 permissions for configs + chmod 0600 "${CONNFILE}" + + # Cleanup + PSK_HASH="" + PASSWORD="" + SSID="" + log "Configuration successful written ..." + rm -f "${SETUPFILE}" +} + +if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then + main +fi diff --git a/src/modules/headless_nm/start_chroot_script b/src/modules/headless_nm/start_chroot_script new file mode 100755 index 00000000..a070d733 --- /dev/null +++ b/src/modules/headless_nm/start_chroot_script @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +#Shebang for better file detection +#### headless_nm install module +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2024 - till today +#### https://github.com/mainsail-crew/MainsailOS +#### +#### This File is distributed under GPLv3 +#### + +set -Ee + +export LC_ALL=C + +# shellcheck disable=SC1091 +source /common.sh +install_cleanup_trap + +# Install dependencies +apt-get update +# shellcheck disable=SC2086 +apt-get install -y ${HEADLESS_NM_DEPS} + +# Install scripts +unpack filesystem/usr/local/bin /usr/local/bin root +unpack filesystem/boot /boot root +unpack filesystem/etc /etc root + +#Enable network-manager service +systemctl_if_exists enable NetworkManager.service + +# Enable Service +systemctl_if_exists enable headless_nm.service + +# set OS_NAME in Wifi-README.txt according to DIST_NAME +if [ -f "/boot/WiFi-README.txt" ]; then + sed -i 's|OS_NAME|'"${DIST_NAME}"'|g' /boot/WiFi-README.txt +fi diff --git a/src/modules/network/config b/src/modules/network/config index 9b8923fd..75144d5c 100755 --- a/src/modules/network/config +++ b/src/modules/network/config @@ -16,4 +16,7 @@ [ -n "$NETWORK_WPA_SUPPLICANT" ] || NETWORK_WPA_SUPPLICANT=no # Enable Network Manager boot folder support (bookworm) -[ -n "$NETWORK_NETWORK_MANAGER" ] || NETWORK_NETWORK_MANAGER=yes \ No newline at end of file +[ -n "$NETWORK_NETWORK_MANAGER" ] || NETWORK_NETWORK_MANAGER=no + +# Enable Headless Network Manager boot folder support (bookworm) +[ -n "$NETWORK_HEADLESS_NM" ] || NETWORK_HEADLESS_NM=yes \ No newline at end of file diff --git a/src/modules/network/filesystem/network-manager/boot/wifi.nmconnection b/src/modules/network/filesystem/network-manager/boot/wifi.nmconnection index afca98b3..3f73327f 100644 --- a/src/modules/network/filesystem/network-manager/boot/wifi.nmconnection +++ b/src/modules/network/filesystem/network-manager/boot/wifi.nmconnection @@ -1,7 +1,6 @@ # Uncomment everything below this line and set your ssid and password # [connection] # id=wifi -# uuid=593819b8-135a-4a3e-9611-c36cdeadbeef # type=wifi # interface-name=wlan0 diff --git a/src/modules/network/meta b/src/modules/network/meta index d56198b9..5d8d2ffe 100755 --- a/src/modules/network/meta +++ b/src/modules/network/meta @@ -16,4 +16,8 @@ elif [[ "${BASE_BOARD}" = orange* ]]; then FINAL_MODULES+=("orange_net") fi +if [[ "${NETWORK_HEADLESS_NM}" = "yes" ]]; then + FINAL_MODULES+=("headless_nm") +fi + printf '%s\n' "$(IFS=,; printf '%s' "${FINAL_MODULES[*]}")"