scripts/setup-ap.sh
126 Zeilen · 4.5 KB · Shell
| 1 | |
| 2 | # =========================================================================== |
| 3 | # Richtet den Raspberry Pi als WLAN-Access-Point ein (NetworkManager/nmcli). |
| 4 | # |
| 5 | # Aufruf: sudo ./setup-ap.sh [/etc/tvwall/tvwall.conf] |
| 6 | # |
| 7 | # Der Name des WLANs kommt aus AP_SSID in der Konfigurationsdatei - so |
| 8 | # bekommt jeder Pi seinen eigenen, unterscheidbaren Netznamen. |
| 9 | # =========================================================================== |
| 10 | set -euo pipefail |
| 11 | |
| 12 | CONF="${1:-/etc/tvwall/tvwall.conf}" |
| 13 | CON_NAME="tvwall-ap" |
| 14 | |
| 15 | info() { printf '\033[1;36m==>\033[0m %s\n' "$*"; } |
| 16 | ok() { printf '\033[1;32m ✓\033[0m %s\n' "$*"; } |
| 17 | warn() { printf '\033[1;33m !\033[0m %s\n' "$*"; } |
| 18 | die() { printf '\033[1;31mFehler:\033[0m %s\n' "$*" >&2; exit 1; } |
| 19 | |
| 20 | [[ $EUID -eq 0 ]] || die "bitte mit sudo starten: sudo $0" |
| 21 | [[ -f "$CONF" ]] || die "Konfigurationsdatei nicht gefunden: $CONF" |
| 22 | |
| 23 | set -a |
| 24 | # shellcheck disable=SC1090 |
| 25 | . "$CONF" |
| 26 | set +a |
| 27 | |
| 28 | AP_SSID="${AP_SSID:-TVWall-01}" |
| 29 | AP_PASSWORD="${AP_PASSWORD:-tvwall1234}" |
| 30 | AP_COUNTRY="${AP_COUNTRY:-DE}" |
| 31 | AP_IP="${AP_IP:-192.168.4.1}" |
| 32 | AP_CHANNEL="${AP_CHANNEL:-7}" |
| 33 | CAPTIVE_PORTAL="${CAPTIVE_PORTAL:-no}" |
| 34 | HOSTNAME_NEW="${HOSTNAME:-tvwall}" |
| 35 | |
| 36 | [[ ${#AP_PASSWORD} -ge 8 ]] || die "AP_PASSWORD muss mindestens 8 Zeichen haben" |
| 37 | |
| 38 | command -v nmcli >/dev/null || die "nmcli fehlt. Bitte NetworkManager installieren: |
| 39 | sudo apt install network-manager && sudo systemctl enable --now NetworkManager" |
| 40 | |
| 41 | systemctl is-active --quiet NetworkManager || systemctl start NetworkManager |
| 42 | |
| 43 | # --- WLAN-Schnittstelle finden -------------------------------------------- |
| 44 | IFACE="${AP_IFACE:-}" |
| 45 | if [[ -z "$IFACE" ]]; then |
| 46 | IFACE="$(nmcli -t -f DEVICE,TYPE device status | awk -F: '$2=="wifi"{print $1; exit}')" |
| 47 | fi |
| 48 | [[ -n "$IFACE" ]] || die "keine WLAN-Schnittstelle gefunden" |
| 49 | info "WLAN-Schnittstelle: $IFACE" |
| 50 | |
| 51 | # --- Funk freischalten und Land setzen ------------------------------------ |
| 52 | command -v rfkill >/dev/null && rfkill unblock wifi || true |
| 53 | if command -v raspi-config >/dev/null; then |
| 54 | raspi-config nonint do_wifi_country "$AP_COUNTRY" >/dev/null 2>&1 || true |
| 55 | fi |
| 56 | command -v iw >/dev/null && iw reg set "$AP_COUNTRY" >/dev/null 2>&1 || true |
| 57 | nmcli radio wifi on >/dev/null 2>&1 || true |
| 58 | ok "Funk aktiv, Land: $AP_COUNTRY" |
| 59 | |
| 60 | # --- Verbindung anlegen ---------------------------------------------------- |
| 61 | info "Richte Access Point '$AP_SSID' ein" |
| 62 | nmcli connection delete "$CON_NAME" >/dev/null 2>&1 || true |
| 63 | |
| 64 | nmcli connection add \ |
| 65 | type wifi \ |
| 66 | ifname "$IFACE" \ |
| 67 | con-name "$CON_NAME" \ |
| 68 | autoconnect yes \ |
| 69 | ssid "$AP_SSID" >/dev/null |
| 70 | |
| 71 | nmcli connection modify "$CON_NAME" \ |
| 72 | 802-11-wireless.mode ap \ |
| 73 | 802-11-wireless.band bg \ |
| 74 | 802-11-wireless.channel "$AP_CHANNEL" \ |
| 75 | 802-11-wireless.hidden no \ |
| 76 | wifi-sec.key-mgmt wpa-psk \ |
| 77 | wifi-sec.proto rsn \ |
| 78 | wifi-sec.pairwise ccmp \ |
| 79 | wifi-sec.group ccmp \ |
| 80 | wifi-sec.psk "$AP_PASSWORD" \ |
| 81 | ipv4.method shared \ |
| 82 | ipv4.addresses "$AP_IP/24" \ |
| 83 | ipv6.method disabled \ |
| 84 | connection.autoconnect yes \ |
| 85 | connection.autoconnect-priority 100 |
| 86 | |
| 87 | # --- Namensaufloesung im eigenen Netz ------------------------------------- |
| 88 | # NetworkManager startet im Modus "shared" ein eigenes dnsmasq. Damit ist der |
| 89 | # Pi auch unter einem einfachen Namen statt nur ueber die IP erreichbar. |
| 90 | install -d -m 0755 /etc/NetworkManager/dnsmasq-shared.d |
| 91 | { |
| 92 | echo "# von TV-Wall setup-ap.sh erzeugt" |
| 93 | echo "address=/tvwall/$AP_IP" |
| 94 | echo "address=/$HOSTNAME_NEW/$AP_IP" |
| 95 | echo "address=/$HOSTNAME_NEW.local/$AP_IP" |
| 96 | if [[ "$CAPTIVE_PORTAL" == "yes" ]]; then |
| 97 | # Alle Namen zeigen auf den Pi - Handys oeffnen die Seite dann von selbst. |
| 98 | echo "address=/#/$AP_IP" |
| 99 | fi |
| 100 | } > /etc/NetworkManager/dnsmasq-shared.d/tvwall.conf |
| 101 | ok "Namensaufloesung eingerichtet (http://tvwall)" |
| 102 | |
| 103 | # --- Starten --------------------------------------------------------------- |
| 104 | info "Aktiviere Access Point" |
| 105 | if ! nmcli connection up "$CON_NAME" >/dev/null 2>&1; then |
| 106 | warn "Access Point liess sich nicht sofort starten. Details:" |
| 107 | nmcli connection up "$CON_NAME" || true |
| 108 | warn "Haeufigste Ursache: das WLAN ist noch mit einem anderen Netz verbunden." |
| 109 | warn "Andere WLAN-Verbindungen abschalten: nmcli connection show" |
| 110 | fi |
| 111 | |
| 112 | sleep 2 |
| 113 | if nmcli -t -f NAME connection show --active | grep -qx "$CON_NAME"; then |
| 114 | ok "Access Point '$AP_SSID' laeuft auf $IFACE ($AP_IP)" |
| 115 | else |
| 116 | warn "Access Point ist noch nicht aktiv - nach einem Neustart versucht NetworkManager es erneut" |
| 117 | fi |
| 118 | |
| 119 | cat <<EOF |
| 120 | |
| 121 | WLAN-Name : $AP_SSID |
| 122 | Passwort : $AP_PASSWORD |
| 123 | Adresse : http://$AP_IP (oder http://tvwall) |
| 124 | |
| 125 | Namen aendern: AP_SSID in $CONF anpassen und dieses Skript erneut ausfuehren. |
| 126 | EOF |