Skip to content

Commit baf6d1c

Browse files
committed
feat: add headless_nm module
* Since RPI nor Armbian have a possibility to change (WiFi) networks after initial flash, adding a solution that it makes it possible to generate a new 'preconfigured.nmconnection' (this one is generated by rpi-imager) * As discussed here guysoft#219 Signed-off-by: Stephan Wendel <[email protected]>
1 parent 4526f28 commit baf6d1c

File tree

10 files changed

+599
-0
lines changed

10 files changed

+599
-0
lines changed

src/modules/headless_nm/config

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
#Shebang for better file detection
3+
#### headless_nm install module
4+
####
5+
#### Written by Stephan Wendel aka KwadFan <[email protected]>
6+
#### Copyright 2024 - till today
7+
#### https://github.com/mainsail-crew/MainsailOS
8+
####
9+
#### This File is distributed under GPLv3
10+
####
11+
12+
# shellcheck disable=all
13+
14+
# Use disable power save for wifi module
15+
[ -n "$HEADLESS_NM_DISABLE_PWRSAVE" ] || HEADLESS_NM_DISABLE_PWRSAVE=yes
16+
17+
# Type of power save rclocal/service/udev
18+
# rclocal - backwards compatibility, runs via rc.local
19+
# service - will add an systemd.service to enable or disable behavior
20+
# on reboots
21+
# udev - creates a udev rules that should affect all wifi devices.
22+
23+
[ -n "$HEADLESS_NM_PWRSAVE_TYPE" ] || HEADLESS_NM_PWRSAVE_TYPE=udev
24+
25+
26+
# DO NOT MODIFY BELOW THIS LINE UNLESS YOU KNOW CONSEQUENCES...
27+
28+
[ -n "$HEADLESS_NM_DEPS" ] || HEADLESS_NM_DEPS="network-manager dos2unix uuid"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Wifi-README.txt
2+
3+
################################################################################
4+
#### IMPORTANT WARNING ####
5+
################################################################################
6+
#### ####
7+
#### First, make sure you have a decent text editor of your choice. ####
8+
#### Notepad++, VSCode, SublimeText or similar are recommended. ####
9+
#### ####
10+
#### Do not use Wordpad to edit this file, it will corrupt it and your ####
11+
#### configuration will not work. ####
12+
#### ####
13+
#### If you use Textedit to edit this file, ####
14+
#### be sure to use "plain text format" and "disable smart quotes" ####
15+
#### in "Textedit > Preferences", otherwise Textedit will use ####
16+
#### incompatible characters and your network configuration won't work! ####
17+
#### ####
18+
################################################################################
19+
20+
How do I setup a new network on my OS_NAME ?
21+
--------------------------------------------
22+
23+
1.) Copy and paste the 'headless_nm.txt.template'.
24+
Rename this file to 'headless_nm.txt'
25+
26+
2.) Now open the file with your favourite text editor.
27+
Windows and MacOS users please read the note above!
28+
29+
This file is pretty self explaining, just the 'REGDOMAIN'
30+
needs some explaination:
31+
32+
Valid country codes are:
33+
34+
GB (United Kingdom)
35+
FR (France)
36+
DE (Germany)
37+
US (United States)
38+
SE (Sweden)
39+
40+
For a complete list, please visit https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
41+
42+
3.) Remove the SD card afterwards.
43+
44+
4.) Almost done... Please put the SD card back into your SBC and wait for it to connect.
45+
46+
NOTE:
47+
48+
Plug in a monitor and watch the console output to get its IP address or
49+
consult your router's setup page to get this information.
50+
51+
You could also try to reach it by its hostname.
52+
53+
http://<yourpisname>.local
54+
55+
If you did not change the hostname during the initial flash, you could use
56+
57+
http://OS_NAME.local
58+
59+
5.) Enjoy OS_NAME :)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#### Headless Wifi configuration
2+
3+
# Your Wifis SSID
4+
SSID="<mySSID>"
5+
6+
# Your WiFis password
7+
PASSWORD="<mySecretPasword>"
8+
9+
# Is your SSID in hidden state? [true/false]
10+
HIDDEN="false"
11+
12+
# Wifi Country code
13+
# See Wifi-README.txt for details!
14+
REGDOMAIN="US"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#### Disable wifi power_save
2+
####
3+
#### Written by Stephan Wendel aka KwadFan <[email protected]>
4+
#### Copyright 2022
5+
#### https://github.com/mainsail-crew/MainsailOS
6+
####
7+
#### This File is distributed under GPLv3
8+
####
9+
#### Note: This is based on:
10+
#### https://www.intel.com/content/www/us/en/support/articles/000006168/boards-and-kits.html
11+
12+
[Unit]
13+
Description=Disable power management for wlan0
14+
After=network.target
15+
16+
[Service]
17+
Type=oneshot
18+
StandardOutput=tty
19+
ExecStart=/usr/local/bin/pwrsave off
20+
21+
[Install]
22+
WantedBy=multi-user.target
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#### headless_nm service
2+
####
3+
#### Written by Stephan Wendel aka KwadFan <[email protected]>
4+
#### Copyright 2024
5+
#### https://github.com/mainsail-crew/MainsailOS
6+
####
7+
#### This File is distributed under GPLv3
8+
####
9+
10+
[Unit]
11+
Description=Setup Wifi on headless machines using NetworkManager
12+
Before=network.target NetworkManager.service
13+
14+
[Service]
15+
Type=oneshot
16+
StandardOutput=tty
17+
ExecStart=/usr/local/bin/headless_nm
18+
19+
[Install]
20+
WantedBy=multi-user.target
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ACTION=="add", \
2+
SUBSYSTEM=="net", \
3+
KERNEL=="wlan*" \
4+
RUN+="/usr/sbin/iw %k set power_save off"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#!/usr/bin/env bash
2+
#### headless_nm
3+
####
4+
#### Written by Stephan Wendel aka KwadFan <[email protected]>
5+
#### Copyright 2024 - till today
6+
#### https://github.com/mainsail-crew/MainsailOS
7+
####
8+
#### This File is distributed under GPLv3
9+
####
10+
11+
#### Description:
12+
#### This is a wrapper for network manager to be able to setup
13+
#### Wifi connections on headless SBC.
14+
#### Takes setup from a file in /boot (/boot/firmware) and recreates
15+
#### Raspberrys 'preconfigured.nmconnection'
16+
17+
#### Copyright hint: This file contains code snippets from
18+
#### Raspberrys raspi-config therefore it applies also there license
19+
#### and copyrights!
20+
#### See https://github.com/RPi-Distro/raspi-config/blob/bookworm/LICENSE
21+
22+
#### It also reuses parts of raspberry-sys-mods
23+
#### See https://github.com/RPi-Distro/raspberrypi-sys-mods/blob/bookworm/usr/lib/raspberrypi-sys-mods/imager_custom
24+
25+
set -e
26+
27+
# Global Vars
28+
DISTRO=""
29+
CMDLINE="/boot/firmware/cmdline.txt"
30+
ARMBIANENV="/boot/armbianEnv.txt"
31+
UUID=""
32+
PSK_HASH=""
33+
KEYMGMT="wpa-psk"
34+
CONNFILE=/etc/NetworkManager/system-connections/preconfigured.nmconnection
35+
SETUPFILE="$(find /boot -name "headless_nm.txt")"
36+
REGDOMAIN=""
37+
CFG80211="/etc/modprobe.d/cfg80211.conf"
38+
39+
40+
# functions
41+
log() {
42+
local msg
43+
msg="${1}"
44+
logger -t headless_nm "${msg}"
45+
}
46+
47+
get_distro() {
48+
local armbian rpi
49+
armbian="$(find /boot -name "$(basename ${ARMBIANENV})")"
50+
rpi="$(find /boot -name "$(basename ${CMDLINE})")"
51+
log "Determine distribution ..."
52+
if [[ -n "${armbian}" ]]; then
53+
DISTRO="armbian"
54+
elif [[ -n "${rpi}" ]]; then
55+
DISTRO="rpi"
56+
else
57+
DISTRO=""
58+
log "Could not determine distribution ... Exiting!"
59+
exit 1
60+
fi
61+
if [[ -n "${DISTRO}" ]]; then
62+
log "Using setup profile: ${DISTRO} ..."
63+
fi
64+
}
65+
66+
get_config() {
67+
# shellcheck disable=SC1090
68+
source "${SETUPFILE}"
69+
}
70+
71+
gen_uuid() {
72+
log "Generating UUID for connection..."
73+
UUID="$(uuid -v4)"
74+
declare -r UUID
75+
}
76+
77+
gen_nmconnection() {
78+
cat <<- EOF >"${CONNFILE}"
79+
[connection]
80+
id=preconfigured
81+
uuid=${UUID}
82+
type=wifi
83+
[wifi]
84+
mode=infrastructure
85+
ssid=${SSID}
86+
hidden=${HIDDEN,,}
87+
[ipv4]
88+
method=auto
89+
[ipv6]
90+
addr-gen-mode=default
91+
method=auto
92+
[proxy]
93+
EOF
94+
}
95+
96+
gen_keymgmt() {
97+
PSK_HASH="$(gen_psk)"
98+
if [[ -n "${PASSWORD}" ]]; then
99+
cat <<- EOF >>${CONNFILE}
100+
[wifi-security]
101+
key-mgmt=${KEYMGMT}
102+
psk=${PSK_HASH}
103+
EOF
104+
fi
105+
}
106+
107+
gen_psk() {
108+
wpa_passphrase "${SSID}" "${PASSWORD}" | sed -n "/^.*[ \t]psk.*/s/[ \t]psk=//p"
109+
}
110+
111+
set_regdomain() {
112+
log "Set registration domain to '${REGDOMAIN}' ..."
113+
# Shameless borrowed from
114+
# https://github.com/RPi-Distro/raspi-config/blob/d22643ade3851c42648f3676e577a622c34af49a/raspi-config#L830C3-L832C5
115+
if ! ischroot; then
116+
iw reg set "${REGDOMAIN}"
117+
fi
118+
# set permanent
119+
case "${DISTRO}" in
120+
"rpi")
121+
# Shameless borrowed from
122+
# https://github.com/RPi-Distro/raspi-config/blob/d22643ade3851c42648f3676e577a622c34af49a/raspi-config#L822C3-L825C15
123+
sed -i \
124+
-e "s/\s*cfg80211.ieee80211_regdom=\S*//" \
125+
-e "s/\(.*\)/\1 cfg80211.ieee80211_regdom=$REGDOMAIN/" \
126+
"${CMDLINE}"
127+
;;
128+
"armbian")
129+
if [[ -f "${CFG80211}" ]]; then
130+
rm -f "${CFG80211}"
131+
fi
132+
echo "options cfg80211 ieee80211_regdom=${REGDOMAIN}" > "${CFG80211}"
133+
;;
134+
esac
135+
}
136+
137+
# MAIN
138+
main() {
139+
# Determine base distribution
140+
get_distro
141+
142+
# Check setup file is present
143+
if [[ -f "${SETUPFILE}" ]]; then
144+
log "Configuration file found in ${SETUPFILE}, continuing...\n"
145+
else
146+
log "Configuration file not found! Nothing to do, exiting...\n"
147+
exit 0
148+
fi
149+
150+
# Generate UUID
151+
gen_uuid
152+
153+
# Remove preconfiguration if present
154+
if [[ -f "${CONNFILE}" ]]; then
155+
rm -f "${CONNFILE}"
156+
fi
157+
158+
# Read config file
159+
get_config
160+
161+
# Generate preconfigured.nmconnection file
162+
gen_nmconnection
163+
164+
# Add key management and psk to preconfigured.nmconnection file
165+
gen_keymgmt
166+
167+
# Set REGDOMAIN
168+
set_regdomain
169+
170+
# NetworkManager only accepts 0600 permissions for configs
171+
chmod 0600 "${CONNFILE}"
172+
173+
# Cleanup
174+
PSK_HASH=""
175+
PASSWORD=""
176+
SSID=""
177+
log "Configuration successful written ..."
178+
rm -f "${SETUPFILE}"
179+
}
180+
181+
if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
182+
main
183+
fi

0 commit comments

Comments
 (0)