From a613848f9354622b16a17fe3aa0334fb3360b663 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 18 Sep 2024 20:53:21 +0200 Subject: [PATCH] Refactor networking configuration logic (#84) * Expand filter to show more adaptors * Refactoring --------- Co-authored-by: Joey Turner --- lib/armbian-configng/config.ng.functions.sh | 7 + lib/armbian-configng/config.ng.jobs.json | 140 ++------ lib/armbian-configng/config.ng.network.sh | 374 ++++++++------------ 3 files changed, 174 insertions(+), 347 deletions(-) diff --git a/lib/armbian-configng/config.ng.functions.sh b/lib/armbian-configng/config.ng.functions.sh index 65abe596..e6593d88 100644 --- a/lib/armbian-configng/config.ng.functions.sh +++ b/lib/armbian-configng/config.ng.functions.sh @@ -212,6 +212,13 @@ function set_runtime_variables(){ fi fi + # Determine which network renderer is in use for NetPlan + if systemctl is-active systemd-networkd 1>/dev/null; then + renderer=networkd + else + renderer=NetworkManager + fi + DIALOG_CANCEL=1 DIALOG_ESC=255 diff --git a/lib/armbian-configng/config.ng.jobs.json b/lib/armbian-configng/config.ng.jobs.json index 89b9b301..ba348195 100644 --- a/lib/armbian-configng/config.ng.jobs.json +++ b/lib/armbian-configng/config.ng.jobs.json @@ -328,149 +328,55 @@ "description": "Fixed and wireless network settings", "sub": [ { - "id": "N01.1", + "id": "N01", "description": "Configure network interfaces", "sub": [ { - "id": "N01.1.1", - "description": "Wired", - "sub": [ - { - "id": "N01", - "description": "Show configuration", - "command": [ "netplan_wrapper \"show_message\" \"\" \"\" \"ethernets\"" ], - "status": "Active", - "doc_link": "", - "src_reference": "", - "author": "Igor Pecovnik", - "condition": "[ -f /etc/netplan/30-*static-interfaces.yaml ] || [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]" - }, - { - "id": "N02", - "description": "Enable DHCP on all interfaces", - "command": [ "netplan_wrapper \"dhcp_all_wired_interfaces\" \"false\" \"10-dhcp-all-interfaces\" \"ethernets\" \"networkd\"" ], - "status": "Active", - "author": "Igor Pecovnik", - "condition": "[ ! -f /etc/netplan/10-dhcp-all-interfaces.yaml ]" - }, - { - "id": "N03", - "description": "Set fixed IP address", - "command": [" netplan_wrapper \"set_ip\" \"true\" \"10-dhcp-all-interfaces\" \"ethernets\" \"networkd\""], - "status": "Active", - "doc_link": "", - "src_reference": "", - "author": "Igor Pecovnik", - "condition": "" - }, - { - "id": "N04", - "description": "Disable IPV6", - "command": [" netplan_wrapper \"disable_ipv6\" \"false\" \"10-dhcp-all-interfaces\" \"ethernets\" \"networkd\""], - "status": "Pending Review", - "doc_link": "", - "src_reference": "", - "author": "Igor Pecovnik", - "condition": "[ -f /etc/netplan/30-*static-interfaces.yaml ] || [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]" - }, - { - "id": "N05", - "description": "Enable IPV6", - "command": [" netplan_wrapper \"enable_ipv6\" \"false\" \"10-dhcp-all-interfaces\" \"ethernets\" \"networkd\""], - "status": "Pending Review", - "doc_link": "", - "src_reference": "", - "author": "Igor Pecovnik", - "condition": "[ -f /etc/netplan/30-*static-interfaces.yaml ] || [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]" - }, - { - "id": "N06", - "description": "Disable wired networking", - "command": [ "rm -f /etc/netplan/10-dhcp-all-interfaces.yaml /etc/netplan/30-*static-interfaces.yaml" ], - "condition": "[ -f /etc/netplan/30-*static-interfaces.yaml ] || [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]", - "status": "Active", - "author": "Igor Pecovnik" - } - ] + "id": "N02", + "description": "Add interface", + "command": [ "network_config armbian" ], + "status": "Active", + "author": "Igor Pecovnik", + "condition": "" }, { - "id": "N01.1.2", - "description": "Wireless", - "sub": [ - { - "id": "N07", - "description": "Show configuration", - "command": [ "netplan_wrapper \"show_message\" \"\" \"\" \"wifis\"" ], - "condition": "[ -f /etc/netplan/20-dhcp-wlan-interface.yaml ]", - "status": "Active", - "author": "Igor Pecovnik" - }, - { - "id": "N08", - "description": "Disable wireless networking", - "command": [ "rm -f /etc/netplan/20-dhcp-wlan-interface.yaml" ], - "condition": "[ -f /etc/netplan/20-dhcp-wlan-interface.yaml ]", - "status": "Active", - "author": "Igor Pecovnik" - }, - { - "id": "N09", - "description": "Disable IPV6", - "command": [" netplan_wrapper \"disable_ipv6\" \"false\" \"20-dhcp-wlan-interface\" \"wifis\" \"networkd\""], - "condition": "[ -f /etc/netplan/20-dhcp-wlan-interface.yaml ]", - "status": "Active", - "author": "Igor Pecovnik" - }, - { - "id": "N10", - "description": "Enable IPV6", - "command": [" netplan_wrapper \"enable_ipv6\" \"false\" \"20-dhcp-wlan-interface\" \"wifis\" \"networkd\""], - "condition": "[ -f /etc/netplan/20-dhcp-wlan-interface.yaml ]", - "status": "Active", - "author": "Igor Pecovnik" - }, - { - "id": "N11", - "description": "Enable DHCP on wireless network interface", - "command": [ - "wifi_connect" - ], - "status": "Active", - "author": "Igor Pecovnik", - "condition": "[ ! -f /etc/netplan/20-dhcp-wlan-interface.yaml ]" - } - ] + "id": "N03", + "description": "Revert to defaults", + "command": [ "default_network_config" ], + "status": "Active", + "author": "Igor Pecovnik", + "condition": "[[ -f /etc/netplan/armbian.yaml ]] && ! cat /etc/netplan/armbian.yaml | diff -q 1>/dev/null <(netplan get all) - || [[ ! -f /etc/netplan/10-dhcp-all-interfaces.yaml ]] && ! cat /etc/netplan/10-dhcp-all-interfaces.yaml 2>/dev/null | diff -q 1>/dev/null <(netplan get all) -" }, { - "id": "N12", - "description": "Show common configs", - "command": [ "show_message <<< \"$(sudo netplan get all)\"" ], + "id": "N04", + "description": "Show draft configuration", + "command": [ "show_message <<< \"$(netplan get all)\"" ], "status": "Active", "doc_link": "", "src_reference": "", "author": "Igor Pecovnik", - "condition": "" + "condition": "[[ -f /etc/netplan/armbian.yaml ]]" }, { - "id": "N13", - "description": "Apply common configs", + "id": "N05", + "description": "Apply changes", "prompt": "This will apply new network configuration\n\nwould you like to continue?", "command": [ "netplan apply" ], "status": "Active", "doc_link": "", "src_reference": "", "author": "Igor Pecovnik", - "condition": "" + "condition": "[[ -f /etc/netplan/armbian.yaml ]] && ! cat /etc/netplan/armbian.yaml | diff -q 1>/dev/null <(netplan get all) - || [[ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]]" }, { - "id": "N14", - "description": "Display status", + "id": "N06", + "description": "Show active status", "command": [ "show_message <<< \"$(netplan status --all)\"" ], "status": "Active", "doc_link": "", "src_reference": "", "author": "Igor Pecovnik", - "condition": "[ $(netplan get network.renderer) == networkd ]" + "condition": "[ -f /etc/netplan/armbian.yaml ] && [ netplan status 2>/dev/null ]" } ] }, diff --git a/lib/armbian-configng/config.ng.network.sh b/lib/armbian-configng/config.ng.network.sh index 15014d23..df117696 100644 --- a/lib/armbian-configng/config.ng.network.sh +++ b/lib/armbian-configng/config.ng.network.sh @@ -106,261 +106,175 @@ function see_ping() { } - - module_options+=( -["hotspot_setup,author"]="Joey Turner" -["hotspot_setup,ref_link"]="" -["hotspot_setup,feature"]="hotspot_setup" -["hotspot_setup,desc"]="Set up a WiFi hotspot on the device" -["hotspot_setup,example"]="hotspot_setup" -["hotspot_setup,status"]="review" -["hotspot_setup,doc_link"]="" +["default_network_config,author"]="Igor Pecovnik" +["default_network_config,ref_link"]="" +["default_network_config,feature"]="default_network_config" +["default_network_config,desc"]="Revert network config back to Armbian defaults" +["default_network_config,example"]="default_network_config" +["default_network_config,doc_link"]="" +["default_network_config,status"]="review" ) +# +# Function to revert network configuration to defaults +# +function default_network_config() { -# Function to display an error message and exit -function error_exit { - whiptail --msgbox "$1" 8 40 - exit 1 -} - -function hotspot_setup() { -# Ensure the script is run as root -if [[ $EUID -ne 0 ]]; then - error_exit "This script must be run as root." -fi - -# Gather SSID and passphrase for the hotspot -SSID=$(whiptail --inputbox "Enter SSID for the Hotspot:" 8 40 3>&1 1>&2 2>&3) -if [ $? -ne 0 ]; then - error_exit "SSID input cancelled." -fi - -PASSPHRASE=$(whiptail --passwordbox "Enter Passphrase for the Hotspot:" 8 40 3>&1 1>&2 2>&3) -if [ $? -ne 0 ]; then - error_exit "Passphrase input cancelled." -fi - -# Confirm SSID and Passphrase -whiptail --msgbox "SSID: $SSID\nPassphrase: $PASSPHRASE" 8 40 - -# Update and install necessary packages -apt update -apt install -y hostapd dnsmasq - -# Stop services while configuring -systemctl stop hostapd -systemctl stop dnsmasq - -# Configure hostapd -cat > /etc/hostapd/hostapd.conf < /etc/dnsmasq.conf <> /etc/network/interfaces < /etc/iptables.ipv4.nat" - -# Ensure iptables rule is loaded on boot -cat > /etc/rc.local <&1 1>&2 2>&3) - if [[ -n $adapter && adapter != "all-eth-interfaces" && "${getip}" != false && $? == 0 ]]; then - address=$(ip -br addr show dev $adapter | awk '{print $3}') - address=$(whiptail --title "Enter IP for $adapter" --inputbox "\nValid format: $address" 9 40 "$address" 3>&1 1>&2 2>&3) - if [[ -n $address && $? == 0 ]]; then - defaultroute=$(ip route show default | grep "$adapter" | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]") - defaultroute=$(whiptail --title "Enter IP for default route" --inputbox "\nValid format: $defaultroute" 9 40 "$defaultroute" 3>&1 1>&2 2>&3) - if [[ -n $defaultroute && $? == 0 ]]; then - nameservers="9.9.9.9,1.1.1.1" - nameservers=$(whiptail --title "Enter DNS server" --inputbox "\nValid format: $nameservers" 9 40 "$nameservers" 3>&1 1>&2 2>&3) + adapter=$(whiptail --title "Select interface" --menu "" $((${LIST_LENGTH} + 8)) 60 $((${LIST_LENGTH})) "${LIST[@]}" 3>&1 1>&2 2>&3) + if [[ -n $adapter && $? == 0 ]]; then + # + # Wireless networking + # + if [[ "$adapter" == w* ]]; then + # wireless + LIST=("sta" "Connect to access point") + LIST+=("ap" "Become an access point") + LIST_LENGTH=$((${#LIST[@]}/2)); + wifimode=$(whiptail --title "Select wifi mode" --menu "" $((${LIST_LENGTH} + 8)) 60 $((${LIST_LENGTH})) "${LIST[@]}" 3>&1 1>&2 2>&3) + if [[ "${wifimode}" == "sta" && $? == 0 ]]; then + ip link set ${adapter} up + systemctl stop hostapd 1>/dev/null + systemctl disable hostapd 1>/dev/null + LIST=() + LIST=($(iw dev ${adapter} scan 2> /dev/null | grep 'SSID\|^BSS' | cut -d" " -f2 | sed "s/(.*//g" | xargs -n2 -d'\n' | awk '{print $2,$1}')) + sleep 2 + LIST_LENGTH=$((${#LIST[@]}/2)); + SELECTED_SSID=$(whiptail --title "Select SSID" --menu "rf" $((${LIST_LENGTH} + 6)) 50 $((${LIST_LENGTH})) "${LIST[@]}" 3>&1 1>&2 2>&3) + if [[ -n $SELECTED_SSID ]]; then + SELECTED_PASSWORD=$(whiptail --title "Enter new password for $SELECTED_SSID" --passwordbox "" 7 50 3>&1 1>&2 2>&3) + if [[ -n $SELECTED_PASSWORD ]]; then + # connect to AP + netplan set --origin-hint ${yamlfile} renderer=${renderer} + netplan set --origin-hint ${yamlfile} wifis.$adapter.access-points."${SELECTED_SSID}".password=${SELECTED_PASSWORD} + netplan set --origin-hint ${yamlfile} wifis.$adapter.dhcp4=true + netplan set --origin-hint ${yamlfile} wifis.$adapter.dhcp6=true + show_message <<< "$(netplan get all)" + fi + fi + elif [[ "${wifimode}" == "ap" ]]; then + + check_if_installed hostapd && debconf-apt-progress -- apt-get -y --no-install-recommends hostapd + + SELECTED_SSID=$(whiptail --title "Enter SSID for AP" --inputbox "" 7 50 3>&1 1>&2 2>&3) + if [[ -n "${SELECTED_SSID}" && $? == 0 ]]; then + SELECTED_PASSWORD=$(whiptail --title "Enter new password for $SELECTED_SSID" --passwordbox "" 7 50 3>&1 1>&2 2>&3) + if [[ -n "${SELECTED_PASSWORD}" && $? == 0 ]]; then + # start bridged AP + netplan set --origin-hint ${yamlfile} renderer=${renderer} + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp4=no + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp6=no + netplan set --origin-hint ${yamlfile} bridges.br0.interfaces='['$adapter']' + cat <<- EOF > "/etc/hostapd/hostapd.conf" + interface=$adapter + driver=nl80211 + ssid=$SELECTED_SSID + hw_mode=g + channel=7 + wmm_enabled=0 + macaddr_acl=0 + auth_algs=1 + ignore_broadcast_ssid=0 + wpa=2 + wpa_passphrase=$SELECTED_PASSWORD + wpa_key_mgmt=WPA-PSK + wpa_pairwise=TKIP + rsn_pairwise=CCMP + EOF + # Start services + systemctl stop hostapd + sleep 2 + systemctl start hostapd + # Enable services on boot + systemctl enable hostapd + show_message <<< "$(netplan get all)" + fi + fi fi - fi - fi -} - -module_options+=( -["wifi_connect,author"]="Igor Pecovnik" -["wifi_connect,ref_link"]="" -["wifi_connect,feature"]="wifi_connect" -["wifi_connect,desc"]="List and connect to wireless network" -["wifi_connect,example"]="wifi_connect" -["wifi_connect,doc_link"]="" -["wifi_connect,status"]="review" -) -# -# Function to list and connect to wireless network -# -function wifi_connect() { - - choose_adapter "w" "false" "true" - # enable adapter - ip link set ${adapter} up - LIST=() - LIST=($(iw dev ${adapter} scan 2> /dev/null | grep 'SSID\|^BSS' | cut -d" " -f2 | sed "s/(.*//g" | xargs -n2 -d'\n' | awk '{print $2,$1}')) - LIST_LENGTH=$((${#LIST[@]}/2)); - SELECTED_SSID=$(whiptail --title "Select SSID" --menu "rf" $((${LIST_LENGTH} + 6)) 50 $((${LIST_LENGTH})) "${LIST[@]}" 3>&1 1>&2 2>&3) - if [[ -n $SELECTED_SSID ]]; then - SELECTED_PASSWORD=$(whiptail --title "Enter new password for $SELECTED_SSID" --passwordbox "" 7 50 3>&1 1>&2 2>&3) - if [[ -n $SELECTED_PASSWORD ]]; then - rm -f /etc/netplan/20-dhcp-wlan-interface - netplan set --origin-hint 20-dhcp-wlan-interface renderer=networkd - netplan set --origin-hint 20-dhcp-wlan-interface wifis.$adapter.access-points."${SELECTED_SSID}".password=${SELECTED_PASSWORD} - netplan set --origin-hint 20-dhcp-wlan-interface wifis.$adapter.dhcp4=true - netplan set --origin-hint 20-dhcp-wlan-interface wifis.$adapter.dhcp6=true - fi - fi -} - -module_options+=( -["netplan_wrapper,author"]="Igor Pecovnik" -["netplan_wrapper,ref_link"]="" -["netplan_wrapper,feature"]="netplan_wrapper" -["netplan_wrapper,desc"]="Wrapping Netplan commands" -["netplan_wrapper,example"]="netplan_wrapper" -["netplan_wrapper,doc_link"]="" -["netplan_wrapper,status"]="review" -) -# -# Function to feed netplan CLI -# -function netplan_wrapper() { - local what=$1 - local get_ip=$2 - local config=$3 - local type=$4 - local renderer=$5 - local adapter=$6 - local address=$7 - - case "$1" in - - show_message) - show_message <<< $(sudo netplan get ${type}) - ;; - - dhcp_all_wired_interfaces) - rm -f /etc/netplan/30-*-static-interfaces.yaml - netplan set --origin-hint ${config} renderer=${renderer} - netplan set --origin-hint ${config} ethernets.all-eth-interfaces.dhcp4=true - netplan set --origin-hint ${config} ethernets.all-eth-interfaces.dhcp6=true - netplan set --origin-hint ${config} ethernets.all-eth-interfaces.match.name=e* - show_message <<< "$(sudo netplan get ${type})" - ;; - - set_ip) - choose_adapter "${type:0:1}" "${get_ip}" "true" - if [[ "${address}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$ ]]; then - rm -f /etc/netplan/10-dhcp-all-interfaces.yaml - netplan set --origin-hint ${config} renderer=${renderer} - netplan set --origin-hint ${config} ethernets.${adapter}.addresses=[$address] - netplan set --origin-hint ${config} ${type}.${adapter}.routes='[{"to":"0.0.0.0/0", "via": "'$defaultroute'","metric":200}]' - netplan set --origin-hint ${config} ${type}.${adapter}.nameservers.addresses=[$nameservers] - show_message <<< "$(sudo netplan get ${type})" else - [[ -n "${address}" ]] && show_message <<< "IP address is wrong. Try 1.2.3.4/5" - fi - ;; - - disable_ipv6) - choose_adapter "${type:0:1}" "${get_ip}" "false" - netplan set --origin-hint ${config} renderer=${renderer} - netplan set --origin-hint ${config} ${type}.${adapter}.dhcp6=false - show_message <<< "$(sudo netplan get ${type})" - ;; - enable_ipv6) - choose_adapter "${type:0:1}" "${get_ip}" "true" - netplan set --origin-hint ${config} renderer=${renderer} - netplan set --origin-hint ${config} ${type}.${adapter}.dhcp6=true - show_message <<< "$(sudo netplan get ${type})" - ;; - *) - esac + # + # Wireless networking + # + LIST=("dhcp" "Auto IP assigning") + LIST+=("static" "Set IP manually") + wiredmode=$(whiptail --title "Select IP mode" --menu "" $((${LIST_LENGTH} + 8)) 60 $((${LIST_LENGTH})) "${LIST[@]}" 3>&1 1>&2 2>&3) + if [[ "${wiredmode}" == "dhcp" && $? == 0 ]]; then + netplan set --origin-hint ${yamlfile} renderer=${renderer} + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp4=no + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp6=no + netplan set --origin-hint ${yamlfile} bridges.br0.interfaces='['$adapter']' + netplan set --origin-hint ${yamlfile} bridges.br0.dhcp4=yes + netplan set --origin-hint ${yamlfile} bridges.br0.dhcp6=yes + show_message <<< "$(netplan get all)" + elif [[ "${wiredmode}" == "static" ]]; then + address=$(ip -br addr show dev $adapter | awk '{print $3}') + [[ -z "${address}" ]] && address="1.2.3.4/5" + address=$(whiptail --title "Enter IP for $adapter" --inputbox "\nValid format: $address" 9 40 "$address" 3>&1 1>&2 2>&3) + if [[ -n $address && $? == 0 ]]; then + defaultroute=$(ip route show default | grep "$adapter" | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]" | head 1 | xargs) + defaultroute=$(whiptail --title "Enter IP for default route" --inputbox "\nValid format: $defaultroute" 9 40 "$defaultroute" 3>&1 1>&2 2>&3) + if [[ -n $defaultroute && $? == 0 ]]; then + nameservers="9.9.9.9,1.1.1.1" + nameservers=$(whiptail --title "Enter DNS server" --inputbox "\nValid format: $nameservers" 9 40 "$nameservers" 3>&1 1>&2 2>&3) + fi + if [[ -n $nameservers && $? == 0 ]]; then + netplan set --origin-hint ${yamlfile} renderer=${renderer} + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp4=no + netplan set --origin-hint ${yamlfile} ethernets.$adapter.dhcp6=no + netplan set --origin-hint ${yamlfile} bridges.br0.interfaces='['$adapter']' + netplan set --origin-hint ${yamlfile} bridges.br0.addresses='['$address']' + netplan set --origin-hint ${yamlfile} bridges.br0.routes='[{"to":"0.0.0.0/0", "via": "'$defaultroute'","metric":200}]' + netplan set --origin-hint ${yamlfile} bridges.br0.nameservers.addresses='['$nameservers']' + fi + fi + fi + fi + fi }