bash script to setup 'wifish' on Linux

Slug: bash-script-to-setup-wifish-on-linux

16759 characters 1711 words
#!/bin/bash # This script automates the setup of 'wifish' on a Debian Bullseye system. # Version 2: Improved backup, idempotency, and interface detection. # # IMPORTANT: This script makes certain assumptions: # 1. It should be run as root. # 2. It attempts to auto-detect the Wi-Fi interface. If detection fails or is # incorrect, the default "wlan0" is used, or you may need to edit the script # or use wifish with the -i flag. # 3. The active wpa_supplicant configuration file is assumed to be # '/etc/wpa_supplicant/wpa_supplicant.conf'. If different, this needs to be changed. # 4. It will attempt to identify the primary non-root user (UID 1000 or SUDO_USER) # to add to the 'netdev' group. # # Review these assumptions and the script content before execution. set -e # Exit immediately if a command exits with a non-zero status. # --- Configuration --- DEFAULT_WIFI_INTERFACE="wlan0" WPA_SUPPLICANT_CONF_FILE="/etc/wpa_supplicant/wpa_supplicant.conf" WIFI_INTERFACE="" # Will be auto-detected or fall back to DEFAULT_WIFI_INTERFACE # Determine the primary non-root user to add to the 'netdev' group. PRIMARY_USER="" if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then # Prefer SUDO_USER if available and not root PRIMARY_USER="$SUDO_USER" elif command -v id >/dev/null && id -u 1000 &>/dev/null; then # Try UID 1000 PRIMARY_USER_UID1000=$(id -un 1000) if [ "$PRIMARY_USER_UID1000" != "root" ]; then # Ensure user 1000 is not root PRIMARY_USER="$PRIMARY_USER_UID1000" fi fi # Fallback to parsing /etc/passwd if PRIMARY_USER is still not set if [ -z "$PRIMARY_USER" ]; then PRIMARY_USER=$(awk -F: '($3>=1000 && $1 != "root" && $1 != "" && $1 != "nobody"){print $1; exit}' /etc/passwd) fi # --- Helper Functions --- log_action() { echo "[INFO] $1" } log_warning() { echo "[WARNING] $1" } log_error() { echo "[ERROR] $1" >&2 } # --- Wi-Fi Interface Detection --- detect_wifi_interface() { log_action "Attempting to auto-detect Wi-Fi interface..." local detected_iface="" # Try with 'iw dev' first, common for Wi-Fi specific tools if command -v iw >/dev/null; then detected_iface=$(iw dev | awk '$1=="Interface"{print $2; exit}') fi # If 'iw dev' didn't yield a result, try with 'ip link' for wlan* if [ -z "$detected_iface" ] && command -v ip >/dev/null; then detected_iface=$(ip -o link show type wlan | awk -F': ' '{print $2; exit}' | awk '{print $1}') fi # If still no result, try 'ip link' for wlp* (common alternative naming) if [ -z "$detected_iface" ] && command -v ip >/dev/null; then detected_iface=$(ip -o link show | grep -Eo 'wlp[0-9]+s[0-9]+' | head -n1) fi if [ -n "$detected_iface" ]; then WIFI_INTERFACE="$detected_iface" log_action "Detected Wi-Fi interface: $WIFI_INTERFACE. Using this." else WIFI_INTERFACE="$DEFAULT_WIFI_INTERFACE" log_warning "Could not auto-detect Wi-Fi interface. Using default: $WIFI_INTERFACE." log_warning "If this is incorrect, review script or use wifish with the '-i <your_interface>' option." fi } # --- Main Script --- # Check if running as root if [ "$(id -u)" -ne 0 ]; then log_error "This script must be run as root. Please use 'sudo $0' or run as the root user." exit 1 fi detect_wifi_interface # Call detection function log_action "Starting wifish setup script (v2)..." log_action "Using Wi-Fi Interface: ${WIFI_INTERFACE}" log_action "Targeting wpa_supplicant config: ${WPA_SUPPLICANT_CONF_FILE}" if [ -n "$PRIMARY_USER" ]; then log_action "Primary non-root user identified for 'netdev' group: ${PRIMARY_USER}" else log_warning "Could not automatically detect a primary non-root user. Manual 'usermod -a -G netdev youruser' might be required." fi echo "---------------------------------------------------------------------" # Phase 1: Prerequisites and Getting wifish log_action "Phase 1: Installing prerequisites and getting wifish..." log_action "Updating package lists (apt update)..." if ! apt update -qq; then log_error "apt update failed. Please check your network connection and apt sources." exit 1 fi log_action "Installing gawk, dialog, git..." if ! apt install -y gawk dialog git; then log_error "Failed to install required packages. Please check apt output for errors." exit 1 fi TEMP_WIFISH_DIR="/tmp/bougyman-wifish_install_temp_$(date +%Y%m%d%H%M%S)" log_action "Cloning wifish repository to $TEMP_WIFISH_DIR..." rm -rf "$TEMP_WIFISH_DIR" # Clean up if exists if ! git clone https://github.com/bougyman/wifish.git "$TEMP_WIFISH_DIR"; then log_error "Failed to clone wifish repository. Check internet connection and git." exit 1 fi log_action "Setting execute permissions for scripts in repository..." ( cd "$TEMP_WIFISH_DIR" chmod +x wifish install.sh test/test.sh chmod +x sv/wpa_supplicant/run sv/wpa_supplicant/log/run ) log_action "Phase 1 complete." echo "---------------------------------------------------------------------" # Phase 2: Configuring wpa_supplicant log_action "Phase 2: Configuring wpa_supplicant..." log_action "Ensuring wpa_supplicant configuration file directory exists: $(dirname "$WPA_SUPPLICANT_CONF_FILE")" mkdir -p "$(dirname "$WPA_SUPPLICANT_CONF_FILE")" if [ ! -f "$WPA_SUPPLICANT_CONF_FILE" ]; then log_action "Creating empty wpa_supplicant configuration file: $WPA_SUPPLICANT_CONF_FILE" touch "$WPA_SUPPLICANT_CONF_FILE" fi TIMESTAMP=$(date +%Y%m%d%H%M%S) BACKUP_FILE="${WPA_SUPPLICANT_CONF_FILE}.${TIMESTAMP}.bak" log_action "Backing up current $WPA_SUPPLICANT_CONF_FILE to $BACKUP_FILE..." if cp "$WPA_SUPPLICANT_CONF_FILE" "$BACKUP_FILE"; then log_action "Backup successful: $BACKUP_FILE" else log_warning "Failed to create backup of $WPA_SUPPLICANT_CONF_FILE. Proceeding with caution." fi log_action "Configuring 'ctrl_interface' and 'update_config' in $WPA_SUPPLICANT_CONF_FILE for idempotency..." # Comment out any existing ctrl_interface lines to avoid conflicts sed -i -E 's/^[[:space:]]*ctrl_interface=.*$/#& (old_ctrl_interface, commented by wifish_setup.sh)/' "$WPA_SUPPLICANT_CONF_FILE" # Add the correct ctrl_interface line if it's not already present (uncommented) if ! grep -qFx "ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev" "$WPA_SUPPLICANT_CONF_FILE"; then log_action "Adding 'ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev' to $WPA_SUPPLICANT_CONF_FILE." echo "ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev" >> "$WPA_SUPPLICANT_CONF_FILE" else log_action "'ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev' already present or re-added." fi # Comment out any existing update_config lines sed -i -E 's/^[[:space:]]*update_config=.*$/#& (old_update_config, commented by wifish_setup.sh)/' "$WPA_SUPPLICANT_CONF_FILE" # Add the correct update_config line if it's not already present (uncommented) if ! grep -qFx "update_config=1" "$WPA_SUPPLICANT_CONF_FILE"; then log_action "Adding 'update_config=1' to $WPA_SUPPLICANT_CONF_FILE." echo "update_config=1" >> "$WPA_SUPPLICANT_CONF_FILE" else log_action "'update_config=1' already present or re-added." fi log_action "Securing $WPA_SUPPLICANT_CONF_FILE permissions (chmod 600)..." chmod 600 "$WPA_SUPPLICANT_CONF_FILE" USER_MODIFIED_LOGIN_MESSAGE="" if [ -n "$PRIMARY_USER" ]; then log_action "Ensuring 'netdev' group exists and adding user '$PRIMARY_USER' to it..." if ! getent group netdev >/dev/null; then log_action "Group 'netdev' does not exist. Creating it..." if ! groupadd --system netdev; then # Use --system for system groups if appropriate log_warning "Could not create group 'netdev'. Manual creation (groupadd netdev) might be needed." else log_action "Group 'netdev' created." fi fi # Check if user is already in group to avoid unnecessary usermod message if ! groups "$PRIMARY_USER" | grep -q '\bnetdev\b'; then if ! usermod -a -G netdev "$PRIMARY_USER"; then log_warning "Failed to add user '$PRIMARY_USER' to 'netdev' group. Check permissions or do it manually." else USER_MODIFIED_LOGIN_MESSAGE="User '$PRIMARY_USER' has been added to the 'netdev' group. IMPORTANT: '$PRIMARY_USER' MUST log out and log back in for this change to take effect." log_action "$USER_MODIFIED_LOGIN_MESSAGE" fi else log_action "User '$PRIMARY_USER' is already a member of the 'netdev' group." USER_MODIFIED_LOGIN_MESSAGE="User '$PRIMARY_USER' is a member of 'netdev'. If this membership is recent, a logout/login might still be needed for all services to recognize it." fi else USER_MODIFIED_LOGIN_MESSAGE="IMPORTANT: Could not automatically determine a primary non-root user. Please manually add your regular user to the 'netdev' group (e.g., 'sudo usermod -a -G netdev yourusername') and then log out and log back in." log_warning "$USER_MODIFIED_LOGIN_MESSAGE" fi log_action "Attempting to restart wpa_supplicant for interface '$WIFI_INTERFACE'..." WPA_RESTARTED_MANUALLY_MSG="If wpa_supplicant was restarted, it should pick up the new configuration. If not, a manual restart of wpa_supplicant or a system reboot might be necessary." SERVICE_NAME="wpa_supplicant@${WIFI_INTERFACE}.service" SERVICE_EXISTS=false if systemctl list-unit-files | grep -q "^${SERVICE_NAME}"; then # More precise grep SERVICE_EXISTS=true fi if [ "$SERVICE_EXISTS" = true ]; then log_action "${SERVICE_NAME} found." if systemctl is-active --quiet "${SERVICE_NAME}"; then log_action "Restarting ${SERVICE_NAME} via systemd..." if ! systemctl restart "${SERVICE_NAME}"; then log_warning "Failed to restart ${SERVICE_NAME}. Check 'systemctl status ${SERVICE_NAME}' and 'journalctl -u ${SERVICE_NAME}'." fi else log_action "${SERVICE_NAME} exists but is not active. Attempting to enable and start it..." if ! systemctl enable "${SERVICE_NAME}" --now; then log_warning "Failed to enable and start ${SERVICE_NAME}. Check status and journal." fi fi elif [ -f "/etc/network/interfaces" ] && grep -q "iface ${WIFI_INTERFACE} inet" /etc/network/interfaces; then # More specific grep log_action "Attempting to restart network interface ${WIFI_INTERFACE} via ifdown/ifup..." ifdown "${WIFI_INTERFACE}" >/dev/null 2>&1 || true # Ignore errors if already down if ! ifup "${WIFI_INTERFACE}"; then log_warning "ifup ${WIFI_INTERFACE} failed. Manual network reconfiguration might be needed. Check /etc/network/interfaces configuration." fi else WPA_RESTARTED_MANUALLY_MSG="Could not determine how wpa_supplicant is managed for '${WIFI_INTERFACE}' (no specific systemd service or /etc/network/interfaces entry found). A manual restart of wpa_supplicant or a system reboot might be necessary to apply configuration changes." log_warning "$WPA_RESTARTED_MANUALLY_MSG" fi log_action "Phase 2 complete." echo "---------------------------------------------------------------------" # Phase 3: Implementing wifish (System-Wide Installation) log_action "Phase 3: Installing wifish system-wide..." ( cd "$TEMP_WIFISH_DIR" log_action "Running install.sh from wifish repository (current directory: $(pwd))..." if ! ./install.sh; then log_error "wifish install.sh script failed. Please check output for errors." log_action "Cleaning up temporary directory $TEMP_WIFISH_DIR..." rm -rf "$TEMP_WIFISH_DIR" exit 1 fi ) log_action "wifish's install.sh completed." if [ -f "$TEMP_WIFISH_DIR/test/test.sh" ]; then log_action "The wifish repository includes a test script: $TEMP_WIFISH_DIR/test/test.sh" log_action "You can explore running it manually from the '$TEMP_WIFISH_DIR' directory if desired (e.g., './test/test.sh')." log_action "Note: This test script typically mocks wpa_cli and runs its own checks." fi log_action "Phase 3 complete." echo "---------------------------------------------------------------------" # Phase 4: Using wifish (Information for the user) log_action "Phase 4: Information on using wifish..." log_action "wifish should now be installed and available as the 'wifish' command." log_action "Example usage (as the non-root user, AFTER they have logged back in if their group membership was changed):" log_action " wifish list" log_action " wifish menu" log_action " wifish connect \"Your_Network_SSID\"" log_action " " log_action "If wifish needs to target a specific interface (detected/defaulted to '${WIFI_INTERFACE}'), use:" log_action " wifish -i ${WIFI_INTERFACE} menu" log_action "or set the environment variable for the session:" log_action " export WPA_CLI_INTERFACE=${WIFI_INTERFACE} (unset with 'unset WPA_CLI_INTERFACE')" log_action " " log_action "IMPORTANT NOTE ON IP ADDRESS:" log_action "wifish handles the Wi-Fi connection (association). After connecting," log_action "your system still needs an IP address to access the internet." log_action "If not configured automatically, run as root (or with sudo):" log_action " dhclient ${WIFI_INTERFACE}" log_action "(Or use another DHCP client like 'dhcpcd5' if installed and preferred, or check 'systemd-networkd' if active)." log_action "Phase 4 complete." echo "---------------------------------------------------------------------" # Final messages log_action "wifish setup script finished." if [ -n "$USER_MODIFIED_LOGIN_MESSAGE" ]; then log_action "$USER_MODIFIED_LOGIN_MESSAGE" fi log_action "$WPA_RESTARTED_MANUALLY_MSG" log_action " " log_action "To test, AFTER the designated user ('${PRIMARY_USER:-your regular user}') has potentially logged out and back in:" log_action "1. Open a new terminal as that user." log_action "2. Run 'wpa_cli status'. It should show connection details without needing sudo." log_action "3. Run 'wifish list' or 'wifish menu'." log_action " " log_action "The script used Wi-Fi interface '${WIFI_INTERFACE}'. If this was incorrect," log_action "use wifish with the '-i <your_actual_interface>' flag." log_action "Cleaning up temporary directory $TEMP_WIFISH_DIR..." rm -rf "$TEMP_WIFISH_DIR" log_action "Setup complete. Backup of wpa_supplicant config (if it existed) is at: $BACKUP_FILE" echo "---------------------------------------------------------------------" exit 0
URL: https://ib.bsb.br/bash-script-to-setup-wifish-on-linux