#!/usr/bin/env bash # patch_hotspot_apmode.sh # Make wlan0 persistent AP-mode and ensure hostapd can use it. # Run as root: sudo ./patch_hotspot_apmode.sh set -euo pipefail AP_IF="wlan0" NM_CONF="/etc/NetworkManager/conf.d/unmanaged-wlan0.conf" UDEV_RULE="/etc/udev/rules.d/90-wlan0-apmode.rules" IW_PATH="$(command -v iw || true)" if [ "$(id -u)" -ne 0 ]; then echo "Please run as root (sudo)." exit 2 fi echo "== patch_hotspot_apmode: starting ==" echo # 1) Tell NetworkManager to ignore wlan0 (idempotent) if [ -f "$NM_CONF" ] && grep -q "interface-name:${AP_IF}" "$NM_CONF"; then echo "[+] NetworkManager already configured to ignore $AP_IF ($NM_CONF)" else echo "[*] Writing NetworkManager unmanaged conf -> $NM_CONF" mkdir -p "$(dirname "$NM_CONF")" cat > "$NM_CONF" < $UDEV_RULE" else echo "[*] Writing udev rule -> $UDEV_RULE" cat > "$UDEV_RULE" </dev/null 2>&1 || true # Kill any lingering wpa_supplicant processes bound to the interface pkill -f "wpa_supplicant.*${AP_IF}" >/dev/null 2>&1 || true # 4) Force interface down -> ap mode -> up (immediate) if [ -z "$IW_PATH" ]; then echo "[!] 'iw' command not found. Please install 'iw' and re-run this script." exit 3 fi echo "[*] Forcing $AP_IF to AP mode now..." ip link set "$AP_IF" down || true # set type ap (if already ap this is harmless) $IW_PATH "$AP_IF" set type ap || { echo "[!] Failed to set $AP_IF to AP via iw. Check driver support (iw list)." # continue so hostapd restart attempt still happens } ip link set "$AP_IF" up || true # 5) Restart hostapd + dnsmasq (so hostapd binds to AP-mode iface) echo "[*] Starting hostapd and dnsmasq (or restarting if already running)..." systemctl unmask hostapd >/dev/null 2>&1 || true systemctl restart hostapd || echo "[!] hostapd restart returned non-zero (check sudo journalctl -u hostapd)" systemctl restart dnsmasq || echo "[!] dnsmasq restart returned non-zero (check sudo journalctl -u dnsmasq)" # 6) Re-enable NetworkManager (but it will ignore wlan0 now) echo "[*] Re-enabling NetworkManager (it should ignore $AP_IF per conf)..." systemctl start NetworkManager || true # 7) Persist iptables if netfilter-persistent exists if command -v netfilter-persistent >/dev/null 2>&1; then echo "[*] Saving iptables rules via netfilter-persistent..." netfilter-persistent save || echo "[!] netfilter-persistent save failed (check rules)" else echo "[*] netfilter-persistent not installed; skipping iptables save." fi # 8) Final status + verification commands echo echo "== done ==" echo "Quick checks you can run now:" echo " iw dev" echo " sudo systemctl status hostapd dnsmasq NetworkManager" echo " sudo journalctl -u hostapd -n 50" echo echo "If you reboot, udev will attempt to set $AP_IF to AP mode automatically and NetworkManager will ignore $AP_IF." echo "If anything goes wrong, paste the output of: sudo journalctl -u hostapd -n 100" echo