#!/usr/bin/env bash # Set up a WiFi access point on wlan0 and share internet from ethernet (eth0). # # Usage: # sudo ./scripts/setup_ap.sh # sudo PORTAL_AP_SSID=mywifi PORTAL_AP_PASSWORD=secret ./scripts/setup_ap.sh # # Environment: # PORTAL_AP_SSID WiFi name (default: portal) # PORTAL_AP_PASSWORD WPA password, 8+ chars (default: portal1234) # PORTAL_AP_CON_NAME NetworkManager connection name (default: portal-ap) # PORTAL_AP_IF AP interface (default: wlan0) # PORTAL_WAN_IF Uplink interface (default: eth0) set -euo pipefail SSID="${PORTAL_AP_SSID:-portal}" PASSWORD="${PORTAL_AP_PASSWORD:-portal1234}" CON_NAME="${PORTAL_AP_CON_NAME:-portal-ap}" AP_IF="${PORTAL_AP_IF:-wlan0}" WAN_IF="${PORTAL_WAN_IF:-eth0}" die() { echo "Error: $*" >&2 exit 1 } if [[ "${EUID}" -ne 0 ]]; then die "run as root: sudo $0" fi if ((${#PASSWORD} < 8)); then die "PORTAL_AP_PASSWORD must be at least 8 characters" fi if ! command -v nmcli >/dev/null; then die "NetworkManager (nmcli) is required" fi if ! systemctl is-active --quiet NetworkManager; then die "NetworkManager is not running" fi if ! ip link show "${WAN_IF}" >/dev/null 2>&1; then die "uplink interface ${WAN_IF} not found" fi if ! ip link show "${AP_IF}" >/dev/null 2>&1; then die "AP interface ${AP_IF} not found" fi if ! ip link show "${WAN_IF}" | grep -q "state UP"; then echo "Warning: ${WAN_IF} is not UP — connect ethernet before clients can reach the internet." >&2 fi # NM shared AP mode uses hostapd on many Pi images. if ! command -v hostapd >/dev/null; then echo "Installing hostapd..." apt-get update -qq apt-get install -y hostapd fi # Allow forwarding between AP clients and ethernet. sysctl -w net.ipv4.ip_forward=1 >/dev/null cat >/etc/sysctl.d/99-portal-ap.conf <<'EOF' # portal AP: share ethernet to WiFi clients net.ipv4.ip_forward=1 EOF rfkill unblock wifi >/dev/null 2>&1 || true nmcli radio wifi on >/dev/null 2>&1 || true if nmcli -t -f NAME connection show | grep -Fxq "${CON_NAME}"; then echo "Updating existing connection '${CON_NAME}'..." nmcli connection delete "${CON_NAME}" >/dev/null fi echo "Creating access point '${SSID}' on ${AP_IF}..." nmcli connection add type wifi ifname "${AP_IF}" con-name "${CON_NAME}" \ autoconnect yes \ ssid "${SSID}" \ 802-11-wireless.mode ap \ 802-11-wireless.band bg \ ipv4.method shared \ ipv6.method ignore \ wifi-sec.key-mgmt wpa-psk \ wifi-sec.psk "${PASSWORD}" >/dev/null # Prefer ethernet for upstream internet when both are available. nmcli connection modify "${CON_NAME}" ipv4.never-default no if nmcli -t -f NAME connection show | grep -Fxq "Wired connection 1"; then nmcli connection modify "Wired connection 1" connection.autoconnect-priority 100 fi nmcli connection modify "${CON_NAME}" connection.autoconnect-priority 50 echo "Starting access point..." nmcli connection up "${CON_NAME}" AP_IP="$(nmcli -g IP4.ADDRESS device show "${AP_IF}" 2>/dev/null | cut -d/ -f1)" WAN_IP="$(nmcli -g IP4.ADDRESS device show "${WAN_IF}" 2>/dev/null | cut -d/ -f1 || true)" cat <