Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add headless_nm module #230

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/modules/headless_nm/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
#Shebang for better file detection
#### headless_nm install module
####
#### Written by Stephan Wendel aka KwadFan <[email protected]>
#### Copyright 2024 - till today
#### https://github.com/mainsail-crew/MainsailOS
####
#### This File is distributed under GPLv3
####

# shellcheck disable=all

# Use disable power save for wifi module
[ -n "$HEADLESS_NM_DISABLE_PWRSAVE" ] || HEADLESS_NM_DISABLE_PWRSAVE=yes

# Type of power save rclocal/service/udev
# rclocal - backwards compatibility, runs via rc.local
# service - will add an systemd.service to enable or disable behavior
# on reboots
# udev - creates a udev rules that should affect all wifi devices.

[ -n "$HEADLESS_NM_PWRSAVE_TYPE" ] || HEADLESS_NM_PWRSAVE_TYPE=udev


# DO NOT MODIFY BELOW THIS LINE UNLESS YOU KNOW CONSEQUENCES...

[ -n "$HEADLESS_NM_DEPS" ] || HEADLESS_NM_DEPS="network-manager dos2unix uuid"
59 changes: 59 additions & 0 deletions src/modules/headless_nm/filesystem/boot/WiFi-README.txt
Original file line number Diff line number Diff line change
@@ -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://<yourpisname>.local

If you did not change the hostname during the initial flash, you could use

http://OS_NAME.local

5.) Enjoy OS_NAME :)
14 changes: 14 additions & 0 deletions src/modules/headless_nm/filesystem/boot/headless_nm.txt.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#### Headless Wifi configuration

# Your Wifis SSID
SSID="<mySSID>"

# Your WiFis password
PASSWORD="<mySecretPasword>"

# Is your SSID in hidden state? [true/false]
HIDDEN="false"

# Wifi Country code
# See Wifi-README.txt for details!
REGDOMAIN="US"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#### Disable wifi power_save
####
#### Written by Stephan Wendel aka KwadFan <[email protected]>
#### Copyright 2022
#### https://github.com/mainsail-crew/MainsailOS
####
#### This File is distributed under GPLv3
####
#### Note: This is based on:
#### https://www.intel.com/content/www/us/en/support/articles/000006168/boards-and-kits.html

[Unit]
Description=Disable power management for wlan0
After=network.target

[Service]
Type=oneshot
StandardOutput=tty
ExecStart=/usr/local/bin/pwrsave off

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#### headless_nm service
####
#### Written by Stephan Wendel aka KwadFan <[email protected]>
#### 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ACTION=="add", \
SUBSYSTEM=="net", \
KERNEL=="wlan*" \
RUN+="/usr/sbin/iw %k set power_save off"
183 changes: 183 additions & 0 deletions src/modules/headless_nm/filesystem/usr/local/bin/headless_nm
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#!/usr/bin/env bash
#### headless_nm
####
#### Written by Stephan Wendel aka KwadFan <[email protected]>
#### 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
Loading