From 85408020c61bbcbb841a179d599c6526f02a5518 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 6 Sep 2026 15:56:54 +0200 Subject: [PATCH] Feat: Automatische Konfiguration aller LAN-Schnittstellen und Loopback im Debian-Installer-Standard Co-authored-by: Junie --- AGENTS.md | 10 ++ README.md | 5 + config/packages/01-base.list | 8 + lib/network.sh | 273 +++++++++++++++++++++++++++++++++++ setup.sh | 1 + stages/00-preflight.sh | 16 +- stages/06-services.sh | 12 +- 7 files changed, 317 insertions(+), 8 deletions(-) create mode 100644 lib/network.sh diff --git a/AGENTS.md b/AGENTS.md index 608d83b..97603e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,7 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F │ ├── utils.sh # Logging, Error-Traps, Benutzer- und Pfadermittlung, Backups │ ├── apt.sh # Deb822-Quellen, Keyrings (/etc/apt/keyrings), APT-Pinning, Paketinstallation │ ├── btrfs.sh # Btrfs Root- & Subvolume-Erkennung, Migration (@, @home), fstab-Verwaltung +│ ├── network.sh # Loopback- & LAN-Schnittstellenkonfiguration (Debian Installer Standard) │ └── tui.sh # Whiptail-TUI-Menüs und Dialoge ├── config/ # Konfigurationsdateien & Paketlisten │ ├── setup.conf # Globale Umgebungsvariablen und Standardwerte @@ -145,6 +146,15 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F - `ensure_grub_btrfs`: Installiert und konfiguriert `grub-btrfs` sowie den `grub-btrfsd`-Dienst für die automatische Generierung von Snapshot-Bootmenüeinträgen in GRUB. - `create_timeshift_snapshot "comment" [tags]`: Erstellt einen Timeshift-Btrfs-Snapshot an kritischen Setup-Meilensteinen (idempotent, steuerbar über `ENABLE_TIMESHIFT_SNAPSHOTS` in `config/setup.conf`). +### `lib/network.sh` +- `get_lan_interfaces`: Erkennt alle physischen LAN/Ethernet-Schnittstellen dynamisch auf jedem System (unter Ausschluss von Loopback, Wi-Fi, Bridges und virtuellen Containern). +- `is_interface_configured "iface"`: Prüft, ob eine Schnittstelle bereits in `/etc/network/interfaces` oder `/etc/network/interfaces.d/` konfiguriert ist. +- `configure_loopback_interface`: Richtet das Loopback-Interface `lo` in `/etc/network/interfaces` (`auto lo`, `iface lo inet loopback`) sowie `/etc/hosts` ein und aktiviert es. +- `configure_lan_interfaces`: Richtet alle erkannten physischen LAN-Schnittstellen im Debian-Installer-Standard (`allow-hotplug `, `iface inet dhcp`, `iface inet6 auto`) ein und aktiviert diese. +- `configure_network_manager`: Konfiguriert `/etc/NetworkManager/NetworkManager.conf` mit `[ifupdown] managed=true` für nahtlose Desktop- und Waybar-Integration. +- `enable_network_services`: Aktiviert und startet `networking.service` und `NetworkManager.service`. +- `configure_network_all`: Zentraler Orchestrator zur vollständigen Netzwerkeinrichtung. + ### `lib/tui.sh` - `tui_show_stage_selection`: Zeigt ein `whiptail` Checklist-Menü zur interaktiven Auswahl der auszuführenden Phasen. diff --git a/README.md b/README.md index 88d8ad1..899e9db 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ sudo ./setup.sh --stages 04,05 │ ├── utils.sh # Logging, Error-Traps (set -euo pipefail), Root/User-Erkennung & Abfrage │ ├── apt.sh # APT-Keyring-Management (/etc/apt/keyrings/), Deb822, Pinning │ ├── btrfs.sh # Btrfs Root- & Subvolume-Erkennung, Migration (@, @home), Timeshift-Snapshots +│ ├── network.sh # Loopback- & LAN-Schnittstellenkonfiguration (Debian Installer Standard) │ └── tui.sh # Whiptail-Menüs und Dialoge ├── config/ # Konfigurationsdateien & Paketlisten │ ├── setup.conf # Globale Variablen (Kernel, GRUB-Theme, Plymouth) @@ -131,6 +132,10 @@ sudo ./setup.sh --stages 04,05 - Installation von `apt-listbugs` und `apt-listchanges` vor dem `dist-upgrade` schützt vor bekannten kritischen Paketproblemen. 5. **Sichere Shell-Verwaltung**: - Standardkonforme Änderung der Login-Shell via `chsh -s` statt direkter `/etc/passwd`-Modifikation. +6. **Netzwerk- & Schnittstellenkonfiguration (Debian Installer Standard)**: + - Automatische Erkennung und Konfiguration aller physischen LAN-Netzwerkschnittstellen via DHCP und IPv6 SLAAC (`allow-hotplug `, `iface inet dhcp`, `iface inet6 auto`). + - Standardkonforme Einrichtung des Loopback-Interfaces (`auto lo`, `iface lo inet loopback`) in `/etc/network/interfaces` und `/etc/hosts`. + - Nahtlose NetworkManager-Integration (`managed=true`) und Berechtigung des Zielbenutzers via `netdev`-Gruppe. --- diff --git a/config/packages/01-base.list b/config/packages/01-base.list index 3b380bc..a483e85 100644 --- a/config/packages/01-base.list +++ b/config/packages/01-base.list @@ -31,6 +31,7 @@ cryptomator curl dconf-editor debian-goodies +ethtool fastfetch file-roller firmware-linux @@ -49,11 +50,16 @@ gparted htop hunspell hunspell-de-de-frami +ifupdown inotify-tools +iproute2 irqbalance +isc-dhcp-client keepassxc lsd man +net-tools +network-manager network-manager-gnome plymouth plymouth-themes @@ -71,6 +77,8 @@ topgrade tree unrar unzip +wireless-regdb +wpasupplicant zram-tools zsh zsh-autosuggestions diff --git a/lib/network.sh b/lib/network.sh new file mode 100644 index 0000000..3afb498 --- /dev/null +++ b/lib/network.sh @@ -0,0 +1,273 @@ +#!/usr/bin/env bash +# ============================================================================== +# lib/network.sh - Network interface configuration (Debian Installer style & Loopback) +# ============================================================================== + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +# shellcheck source=lib/utils.sh +source "$SCRIPT_DIR/lib/utils.sh" + +# Get a list of all physical LAN / Ethernet network interfaces on the system +get_lan_interfaces() { + local -a lan_ifaces=() + + if [[ -d /sys/class/net ]]; then + for iface_path in /sys/class/net/*; do + [[ -e "$iface_path" ]] || continue + local iface + iface="$(basename "$iface_path")" + + # Skip loopback interface + [[ "$iface" == "lo" ]] && continue + + # Skip known virtual, bridge, container, tunnel and VPN interfaces + if [[ "$iface" =~ ^(docker[0-9]*|veth.*|virbr[0-9]*|br.*|bridge.*|tun[0-9]*|tap[0-9]*|wg[0-9]*|dummy[0-9]*|waydroid.*|tailscale.*|zt.*|bond.*|sit[0-9]*|ip6tnl.*|gre.*|erspan.*|vboxnet.*|vmnet.*)$ ]]; then + continue + fi + + # Skip wireless / Wi-Fi interfaces + if [[ -e "$iface_path/wireless" || -e "$iface_path/phy80211" || "$iface" =~ ^(wl.*|wlan.*|wifi.*|ath.*)$ ]]; then + continue + fi + + # Check if it is a physical device (has device link) or standard Ethernet type (type == 1) + local is_lan=0 + local dev_type="" + if [[ -f "$iface_path/type" ]]; then + dev_type="$(cat "$iface_path/type" 2>/dev/null || echo "")" + fi + + if [[ -e "$iface_path/device" && "$dev_type" == "1" ]]; then + is_lan=1 + elif [[ "$iface" =~ ^(eth[0-9]+|en[a-zA-Z0-9]+)$ ]] && [[ "$dev_type" == "1" || -z "$dev_type" ]]; then + is_lan=1 + elif [[ -e "$iface_path/device" ]]; then + is_lan=1 + fi + + if [[ "$is_lan" -eq 1 ]]; then + lan_ifaces+=("$iface") + fi + done + elif command_exists ip; then + # Fallback to ip link parsing if /sys/class/net is not directly readable + while IFS= read -r line; do + local iface + iface="$(echo "$line" | awk -F': ' '{print $2}' | cut -d'@' -f1)" + [[ -z "$iface" || "$iface" == "lo" ]] && continue + if [[ "$iface" =~ ^(eth[0-9]+|en[a-zA-Z0-9]+)$ ]]; then + lan_ifaces+=("$iface") + fi + done < <(ip -o link show 2>/dev/null || true) + fi + + echo "${lan_ifaces[@]:-}" +} + +# Check if a specific interface is already configured in /etc/network/interfaces or interfaces.d +is_interface_configured() { + local iface="$1" + local interfaces_file="/etc/network/interfaces" + local interfaces_dir="/etc/network/interfaces.d" + + if [[ -f "$interfaces_file" ]]; then + if grep -E -q "^[[:space:]]*(iface|auto|allow-hotplug)[[:space:]]+${iface}([[:space:]]|$)" "$interfaces_file" 2>/dev/null; then + return 0 + fi + fi + + if [[ -d "$interfaces_dir" ]]; then + if grep -E -q -r "^[[:space:]]*(iface|auto|allow-hotplug)[[:space:]]+${iface}([[:space:]]|$)" "$interfaces_dir" 2>/dev/null; then + return 0 + fi + fi + + return 1 +} + +# Configure loopback interface in /etc/network/interfaces and /etc/hosts +configure_loopback_interface() { + local interfaces_file="/etc/network/interfaces" + local interfaces_dir="/etc/network/interfaces.d" + + mkdir -p "/etc/network" "$interfaces_dir" + + log_substep "Configuring loopback network interface (lo)..." + + if [[ ! -f "$interfaces_file" ]]; then + cat < "$interfaces_file" +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +source /etc/network/interfaces.d/* + +# The loopback network interface +auto lo +iface lo inet loopback +EOF + chmod 0644 "$interfaces_file" + log_success "Created $interfaces_file with loopback configuration." + else + backup_file_or_dir "$interfaces_file" + + # Ensure source /etc/network/interfaces.d/* is present + if ! grep -E -q "^[[:space:]]*source[[:space:]]+/etc/network/interfaces\.d/\*" "$interfaces_file"; then + sed -i '1i # The loopback network interface\nsource /etc/network/interfaces.d/*\n' "$interfaces_file" + fi + + # Ensure auto lo and iface lo inet loopback are configured + if ! grep -E -q "^[[:space:]]*iface[[:space:]]+lo[[:space:]]+inet[[:space:]]+loopback" "$interfaces_file"; then + cat <> "$interfaces_file" + +# The loopback network interface +auto lo +iface lo inet loopback +EOF + log_success "Added loopback configuration to $interfaces_file." + fi + fi + + # Ensure /etc/hosts has standard loopback mappings + if [[ -f /etc/hosts ]]; then + local host_name + host_name="$(hostname 2>/dev/null || cat /etc/hostname 2>/dev/null || echo "debian")" + if ! grep -q "127.0.0.1[[:space:]]\+localhost" /etc/hosts; then + echo "127.0.0.1 localhost" >> /etc/hosts + fi + if ! grep -q "::1[[:space:]]\+localhost" /etc/hosts; then + echo "::1 localhost ip6-localhost ip6-loopback" >> /etc/hosts + fi + if [[ -n "$host_name" ]] && ! grep -E -q "(127\.0\.1\.1|127\.0\.0\.1)[[:space:]]+.*$host_name" /etc/hosts; then + echo "127.0.1.1 $host_name" >> /etc/hosts + fi + fi + + # Bring up loopback interface immediately + if command_exists ip; then + ip link set lo up 2>/dev/null || true + fi + if command_exists ifup; then + ifup lo 2>/dev/null || true + fi + log_success "Loopback interface (lo) configured and activated." +} + +# Configure all detected physical LAN interfaces (Debian installer standard) +configure_lan_interfaces() { + local interfaces_file="/etc/network/interfaces" + local interfaces_dir="/etc/network/interfaces.d" + + mkdir -p "/etc/network" "$interfaces_dir" + + local -a lan_ifaces + read -r -a lan_ifaces <<< "$(get_lan_interfaces)" + + if [[ ${#lan_ifaces[@]} -eq 0 ]]; then + log_info "No physical LAN interfaces detected at this time." + return 0 + fi + + log_substep "Found physical LAN interface(s): ${lan_ifaces[*]}" + + # Backup interfaces file before modifications + if [[ -f "$interfaces_file" ]]; then + backup_file_or_dir "$interfaces_file" + fi + + for iface in "${lan_ifaces[@]}"; do + [[ -z "$iface" ]] && continue + + if is_interface_configured "$iface"; then + log_info "LAN interface '$iface' is already configured." + else + log_info "Configuring LAN interface '$iface' (Debian Installer style: DHCP & IPv6 Auto)..." + cat <> "$interfaces_file" + +# LAN network interface: $iface +allow-hotplug $iface +iface $iface inet dhcp +iface $iface inet6 auto +EOF + log_success "Added LAN interface '$iface' to $interfaces_file." + fi + + # Ensure the interface is brought UP and usable + if command_exists ip; then + ip link set "$iface" up 2>/dev/null || true + fi + if command_exists ifup; then + ifup "$iface" 2>/dev/null || true + fi + done + + log_success "All LAN network interfaces configured and activated." +} + +# Configure NetworkManager to manage interfaces and work seamlessly with ifupdown +configure_network_manager() { + local nm_conf="/etc/NetworkManager/NetworkManager.conf" + local nm_dir="/etc/NetworkManager" + + if [[ -d "$nm_dir" ]] || command_exists NetworkManager || command_exists nmcli; then + log_substep "Configuring NetworkManager integration (managed=true)..." + mkdir -p "$nm_dir" + + if [[ ! -f "$nm_conf" ]]; then + cat < "$nm_conf" +[main] +plugins=ifupdown,keyfile + +[ifupdown] +managed=true +EOF + chmod 0644 "$nm_conf" + log_success "Created $nm_conf with managed=true." + else + backup_file_or_dir "$nm_conf" + + # Set managed=true in [ifupdown] section + if grep -q "\[ifupdown\]" "$nm_conf"; then + sed -i '/\[ifupdown\]/,/^\[/{s/managed=false/managed=true/}' "$nm_conf" + if ! grep -A2 "\[ifupdown\]" "$nm_conf" | grep -q "managed="; then + sed -i '/\[ifupdown\]/a managed=true' "$nm_conf" + fi + else + cat <> "$nm_conf" + +[ifupdown] +managed=true +EOF + fi + log_success "Updated $nm_conf to managed=true." + fi + fi +} + +# Enable networking and NetworkManager services +enable_network_services() { + if command_exists systemctl; then + log_substep "Enabling and activating network services..." + + # Enable networking service (ifupdown) + systemctl enable networking.service 2>/dev/null || true + + # Enable & start NetworkManager if available + if systemctl list-unit-files NetworkManager.service >/dev/null 2>&1 || [[ -f /lib/systemd/system/NetworkManager.service ]]; then + systemctl enable NetworkManager.service 2>/dev/null || true + systemctl start NetworkManager.service 2>/dev/null || true + log_success "NetworkManager service enabled and started." + fi + fi +} + +# Central orchestration function for network configuration +configure_network_all() { + log_substep "Configuring complete network subsystem (Loopback, all LAN interfaces, NetworkManager)..." + configure_loopback_interface + configure_lan_interfaces + configure_network_manager + enable_network_services + log_success "Network configuration completed successfully." +} diff --git a/setup.sh b/setup.sh index 6f341c5..7fdfc7b 100755 --- a/setup.sh +++ b/setup.sh @@ -11,6 +11,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/lib/utils.sh" source "$SCRIPT_DIR/lib/apt.sh" source "$SCRIPT_DIR/lib/btrfs.sh" +source "$SCRIPT_DIR/lib/network.sh" source "$SCRIPT_DIR/lib/tui.sh" if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then diff --git a/stages/00-preflight.sh b/stages/00-preflight.sh index 3e96c33..602fbbf 100755 --- a/stages/00-preflight.sh +++ b/stages/00-preflight.sh @@ -8,6 +8,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "$SCRIPT_DIR/lib/utils.sh" source "$SCRIPT_DIR/lib/btrfs.sh" +source "$SCRIPT_DIR/lib/network.sh" if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then # shellcheck source=/dev/null @@ -35,7 +36,12 @@ fi log_success "Target user identified: $TARGET_USER (Home: $TARGET_HOME)" -# 3. Check Internet Connectivity +# 3. Configure and Activate Network Interfaces (Loopback & LAN) +log_substep "Initializing and activating network interfaces (Loopback & LAN)..." +configure_loopback_interface +configure_lan_interfaces + +# 4. Check Internet Connectivity log_substep "Checking internet connectivity..." INTERNET_OK=0 for host in "deb.debian.org" "1.1.1.1" "8.8.8.8"; do @@ -51,7 +57,7 @@ if [[ "$INTERNET_OK" -ne 1 ]]; then fi log_success "Internet connection verified." -# 4. Check Operating System +# 5. Check Operating System log_substep "Verifying operating system..." if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null @@ -64,7 +70,7 @@ else log_warn "/etc/os-release not found. Proceeding with caution." fi -# 5. Check Disk Space +# 6. Check Disk Space log_substep "Checking available disk space..." AVAILABLE_KB=$(df --output=avail / | tail -n1) if [[ "$AVAILABLE_KB" -lt 5242880 ]]; then # Less than 5 GB @@ -73,11 +79,11 @@ else log_success "Sufficient disk space available ($(( AVAILABLE_KB / 1024 / 1024 )) GB free)." fi -# 6. Check & Setup Btrfs Subvolumes (@, @home) +# 7. Check & Setup Btrfs Subvolumes (@, @home) log_substep "Checking Btrfs root volume & subvolume layout..." check_and_setup_btrfs_subvolumes -# 7. Create Timeshift Btrfs Snapshot after preflight & subvolume setup +# 8. Create Timeshift Btrfs Snapshot after preflight & subvolume setup create_timeshift_snapshot "Stage 00: Pre-flight checks & Btrfs baseline" "B" log_success "Stage 00: Pre-flight checks passed successfully." diff --git a/stages/06-services.sh b/stages/06-services.sh index afda760..83f66c0 100755 --- a/stages/06-services.sh +++ b/stages/06-services.sh @@ -9,6 +9,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "$SCRIPT_DIR/lib/utils.sh" source "$SCRIPT_DIR/lib/apt.sh" source "$SCRIPT_DIR/lib/btrfs.sh" +source "$SCRIPT_DIR/lib/network.sh" if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then # shellcheck source=/dev/null @@ -147,15 +148,20 @@ elif is_root_btrfs; then log_info "Timeshift will be configured when installed; grub-btrfs configured." fi -# 7. User Group Memberships +# 7. Network Configuration & Services (Loopback, LAN, NetworkManager) +log_substep "Configuring and activating network interfaces (Loopback, all LAN interfaces, NetworkManager)..." +configure_network_all + +# 8. User Group Memberships log_substep "Updating user group memberships for $TARGET_USER..." groupadd -f sudo groupadd -f docker +groupadd -f netdev groupadd -f ollama 2>/dev/null || true -usermod -aG sudo,docker "$TARGET_USER" +usermod -aG sudo,docker,netdev "$TARGET_USER" if getent group ollama >/dev/null 2>&1; then usermod -aG ollama "$TARGET_USER" 2>/dev/null || true fi -log_success "Target user $TARGET_USER added to sudo, docker and ollama groups." +log_success "Target user $TARGET_USER added to sudo, docker, netdev and ollama groups." log_success "Stage 06: System services configuration completed successfully!"